一、Vue2 项目环境搭建
1. 环境准备
- 安装 Node.js:推荐使用 nvm 管理多版本 Node
# 安装Node 16.20.2 nvm install 16.20.2 # 切换至指定版本 nvm use 16.20.2 # 验证安装 node -v && npm -v
- 安装 Vue CLI 脚手架:
# 国内镜像源安装 npm install --registry=https://registry.npmmirror.com @vue/cli -g # 验证安装 vue -V
2. 创建项目
- 命令行方式:
vue create my-vue2-project # 选择"Default (Vue 2)"模板或手动配置
- UI 界面方式:
vue ui
在浏览器打开的 UI 界面中,点击 "创建项目",选择路径并配置选项。
3. 项目基本配置
在项目根目录创建vue.config.js
:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({// 关闭代码格式校验lintOnSave: false,// 配置跨域代理devServer: {proxy: {'/api': {target: 'http://localhost:3000',changeOrigin: true,pathRewrite: {'^/api': ''}}}},// 打包配置configureWebpack: {optimization: {splitChunks: {chunks: 'all'}}}
})
二、项目目录结构解析
典型的 Vue2 项目结构如下:
my-vue2-project/
├── public/ # 静态资源(HTML模板、图标等)
├── src/
│ ├── assets/ # 样式、图片等资源
│ ├── components/ # 组件文件夹
│ ├── router/ # 路由配置
│ ├── store/ # Vuex状态管理
│ ├── utils/ # 工具函数
│ ├── views/ # 页面级组件
│ ├── App.vue # 根组件
│ └── main.js # 入口文件
├── .gitignore # Git忽略文件
├── babel.config.js # Babel配置
├── package.json # 依赖管理
└── README.md # 项目说明
三、组件化开发核心
1. 组件基本结构
一个 Vue 组件由三部分组成:
<template><div class="component-container"><!-- 模板层,只能有一个根元素 --><h3>{{ title }}</h3><p>内容:{{ content }}</p></div>
</template><script>
export default {name: 'ComponentName', // 组件名(首字母大写)props: {title: {type: String,default: '默认标题'},content: {type: String,required: true}},data() {return {internalData: '组件内部数据'}},methods: {handleClick() {console.log('组件方法被调用')}},mounted() {console.log('组件挂载完成')}
}
</script><style scoped>
/* 样式层,scoped确保样式仅作用于当前组件 */
.component-container {padding: 16px;border: 1px solid #eee;
}
</style>
2. 组件注册方式
- 局部注册:在父组件中引入并注册
<!-- 父组件 --> <template><div><HeaderComponent /><MainContent /></div> </template><script> // 1. 引入组件 import HeaderComponent from './components/Header.vue' import MainContent from './components/MainContent.vue'export default {components: {// 2. 注册组件(可自定义标签名)HeaderComponent, // 等价于 HeaderComponent: HeaderComponentMainContent} } </script>
- 全局注册:在 main.js 中注册
// main.js import Vue from 'vue' import App from './App.vue' import FooterComponent from './components/Footer.vue'// 全局注册组件 Vue.component('FooterComponent', FooterComponent)new Vue({render: h => h(App) }).$mount('#app')
在任意组件中可直接使用:<FooterComponent />
3. 组件样式隔离
通过scoped
属性实现组件样式私有化:
<style scoped>
/* 该样式仅作用于当前组件 */
.button {background-color: #42b983;
}
</style>
若需使用 CSS Modules:
<style module>
/* 生成类名如 .button_1d823ab */
.button {color: white;
}
</style>
在模板中使用:
<button :class="$style.button">按钮</button>
四、组件间通信机制
1. 父传子(Props)
- 父组件传递数据:
<ChildComponent :title="pageTitle" :is-active="true" />
- 子组件接收 Props:
export default {props: {title: String,isActive: {type: Boolean,default: false},// 数组/对象类型的默认值需返回函数initialData: {type: Object,default() {return { count: 0 }}}} }
2. 子传父(自定义事件)
- 子组件触发事件:
methods: {sendDataToParent() {const data = { message: '子组件数据' }this.$emit('child-event', data)} }
- 父组件监听事件:
<ChildComponent @child-event="handleChildData" />
methods: {handleChildData(data) {console.log('接收到子组件数据:', data)} }
3. 非父子组件通信(事件总线)
- 创建事件总线(EventBus.js):
import Vue from 'vue' export default new Vue()
- 发送数据组件:
import EventBus from '@/utils/EventBus'methods: {sendToOtherComponent() {EventBus.$emit('custom-event', { data: '跨组件数据' })} }
- 接收数据组件:
import EventBus from '@/utils/EventBus'created() {this.eventHandler = (data) => {console.log('接收到跨组件数据:', data)}EventBus.$on('custom-event', this.eventHandler) }, beforeDestroy() {// 销毁时移除监听,避免内存泄漏EventBus.$off('custom-event', this.eventHandler) }
五、组件引用与 Ref
通过ref
获取 DOM 元素或子组件实例:
<template><div><!-- 引用DOM元素 --><input ref="inputElement" type="text"><!-- 引用子组件 --><ChildComponent ref="childComponent" /><button @click="focusInput">聚焦输入框</button></div>
</template><script>
export default {methods: {focusInput() {// 获取DOM元素并调用方法this.$refs.inputElement.focus()// 调用子组件方法this.$refs.childComponent.doSomething()}}
}
</script>
注意:$refs
在组件挂载后(mounted 钩子)才能正确获取,动态生成的 ref(如 v-for)会返回数组。