【Vue2】基础知识汇总与实战指南
文章目录
- 一、Vue2 入门准备
- 1.1 什么是 Vue2
- 1.2 安装与环境搭建
- 方式 1:CDN 引入(快速入门)
- 方式 2:Vue-CLI 搭建项目(工程化开发)
- 1.3 第一个 Vue 实例
- 二、核心语法:模板与数据
- 2.1 模板语法
- 插值语法(双大括号)
- 指令语法(v - 开头)
- 2.2 数据绑定
- 单向绑定(v-bind)
- 双向绑定(v-model)
- 2.3 事件处理
- 基础用法
- 事件修饰符
- 2.4 条件与列表渲染
- 条件渲染(v-if vs v-show)
- 列表渲染(v-for)
- 三、组件系统:复用与通信
- 3.1 组件注册
- 全局注册(全项目可用)
- 局部注册(仅当前组件可用)
- 3.2 单文件组件(.vue)
- 3.3 组件通信
- 1. 父传子(Props)
- 2. 子传父($emit)
- 3. 兄弟组件通信(事件总线)
- 四、生命周期:实例的一生
- 4.1 生命周期流程图(核心阶段)
- 4.2 常用钩子函数
- 五、进阶特性:提升开发效率
- 5.1 计算属性(computed)
- 5.2 侦听器(watch)
- 5.3 过滤器(filter)
- 5.4 自定义指令
- 六、生态工具:路由与状态管理
- 6.1 路由(vue-router 3.x)
- 安装与配置
- 路由使用
- 6.2 状态管理(Vuex 3.x)
- 核心概念
- 基本使用
- 七、避坑技巧与学习资源
- 7.1 常见坑点
- 1. 响应式数据问题
- 2. v-for 与 v-if 混用
一、Vue2 入门准备
1.1 什么是 Vue2
Vue2 是尤雨溪开发的渐进式 JavaScript 框架,专注于构建用户界面,具有以下特点:
-
遵循 MVVM 模式,实现数据与视图分离
-
编码简洁,体积小(生产版本约 33KB)
-
支持组件化开发,复用性强
-
借鉴 Angular 模板语法与 React 虚拟 DOM 技术
1.2 安装与环境搭建
方式 1:CDN 引入(快速入门)
<!-- 开发环境 --><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script><!-- 生产环境(压缩版) --><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
方式 2:Vue-CLI 搭建项目(工程化开发)
# 安装 Vue-CLI(需 Node.js 8.9+)npm install -g @vue/cli@4.x# 创建项目vue create vue2-demo# 运行项目cd vue2-demo && npm run serve
1.3 第一个 Vue 实例
<div id="app">{{ message }}</div><script>new Vue({el: '#app',data() {return {message: 'Hello Vue2!'}}})</script>
二、核心语法:模板与数据
2.1 模板语法
插值语法(双大括号)
用于解析标签体内容,支持 JS 表达式:
<div>文本:{{ name }}计算:{{ 1 + 1 }}三元运算:{{ isShow ? '可见' : '隐藏' }}</div>
指令语法(v - 开头)
用于操作标签属性、绑定事件等,部分指令可简写:
| 指令 | 简写 | 功能 |
|---|---|---|
| v-bind:attr | :attr | 单向数据绑定 |
| v-on:event | @event | 事件绑定 |
| v-model | - | 双向数据绑定 |
2.2 数据绑定
单向绑定(v-bind)
<!-- 绑定属性 --><img :src="imgUrl" :alt="imgTitle"><!-- 绑定对象 --><div :class="{ active: isActive, disabled: isDisabled }"></div>
双向绑定(v-model)
仅适用于表单元素,本质是 v-bind:value + v-on:input 的语法糖:
<input v-model="username" placeholder="请输入用户名"><script>new Vue({el: '#app',data() {return {username: '' // 输入框内容实时同步到这里}}})</script>
2.3 事件处理
基础用法
<!-- 无参数 --><button @click="handleClick">点击</button><!-- 带参数 --><button @click="handleDelete(id)">删除</button><!-- 传递事件对象 --><button @click="handleEvent($event, id)">事件对象</button>
事件修饰符
<!-- 阻止默认行为(如表单提交) --><form @submit.prevent="handleSubmit"></form><!-- 停止事件冒泡 --><div @click.stop="handleParent"><button @click="handleChild"></button></div><!-- 按键修饰符(按回车触发) --><input @keyup.enter="handleSearch">
2.4 条件与列表渲染
条件渲染(v-if vs v-show)
| 特性 | v-if | v-show |
|---|---|---|
| 原理 | 动态创建 / 销毁元素 | 控制 display 样式 |
| 切换成本 | 高 | 低 |
| 初始隐藏 | 不渲染元素 | 渲染元素(隐藏) |
| 适用场景 | 切换不频繁 | 频繁切换 |
<!-- v-if 系列 --><div v-if="type === 'A'">A</div><div v-else-if="type === 'B'">B</div><div v-else>C</div><!-- v-show --><div v-show="isVisible">可见/隐藏</div>
列表渲染(v-for)
<!-- 遍历数组 --><ul><li v-for="(item, index) in list" :key="item.id">{{ index + 1 }}. {{ item.name }}</li></ul><!-- 遍历对象 --><div v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</div>
注意:必须加
key属性(推荐唯一 ID),避免 DOM 复用导致的问题。
三、组件系统:复用与通信
3.1 组件注册
全局注册(全项目可用)
// 注册全局组件Vue.component('my-button', {template: '<button @click="handleClick">{{ text }}</button>',props: ['text'],methods: {handleClick() {this.$emit('btn-click') // 触发自定义事件}}})
局部注册(仅当前组件可用)
// 导入组件import MyButton from './MyButton.vue'export default {components: {MyButton // 局部注册}}
3.2 单文件组件(.vue)
标准结构包含模板、脚本、样式三部分:
<template><div class="my-component">{{ msg }}</div></template><script>export default {name: 'MyComponent',data() {return {msg: '单文件组件'}}}</script><style scoped>/* scoped 表示样式仅作用于当前组件 */.my-component {color: #333;}</style>
3.3 组件通信
1. 父传子(Props)
<!-- 父组件 --><child :user="parentUser" :age="18"></child><!-- 子组件 --><script>export default {props: {user: {type: Object,required: true},age: {type: Number,default: 0}}}</script>
2. 子传父($emit)
<!-- 子组件 --><template><button @click="sendData">传递数据</button></template><script>export default {methods: {sendData() {// 触发事件并传参this.$emit('child-data', '子组件数据')}}}</script><!-- 父组件 --><child @child-data="handleChildData"></child><script>export default {methods: {handleChildData(data) {console.log('接收子组件数据:', data)}}}</script>
3. 兄弟组件通信(事件总线)
// 1. 全局创建事件总线Vue.prototype.$bus = new Vue()// 2. 发送方this.$bus.$emit('brother-event', '兄弟数据')// 3. 接收方(在 mounted 中监听)mounted() {this.$bus.$on('brother-event', (data) => {console.log('接收兄弟数据:', data)})},// 4. 销毁时移除监听beforeDestroy() {this.$bus.$off('brother-event')}
四、生命周期:实例的一生
4.1 生命周期流程图(核心阶段)
-
初始化阶段:beforeCreate → created → beforeMount → mounted
-
更新阶段:beforeUpdate → updated
-
销毁阶段:beforeDestroy → destroyed
4.2 常用钩子函数
| 钩子函数 | 触发时机 | 常用操作 |
|---|---|---|
| created | 实例创建完成(数据观测完成) | 发送 Ajax 请求、初始化数据 |
| mounted | 实例挂载到 DOM 后 | 操作 DOM、初始化插件 |
| beforeDestroy | 实例销毁前 | 清除定时器、解绑事件 |
export default {data() {return {timer: null}},created() {// 发送请求this.fetchData()},mounted() {// 启动定时器this.timer = setInterval(() => {console.log('定时器运行中')}, 1000)},beforeDestroy() {// 清除定时器clearInterval(this.timer)},methods: {fetchData() {// 模拟 Ajax 请求setTimeout(() => {this.data = '请求结果'}, 1000)}}}
五、进阶特性:提升开发效率
5.1 计算属性(computed)
缓存计算结果,依赖数据变化时自动更新:
export default {data() {return {firstName: '张',lastName: '三'}},computed: {// 完整写法(可设置get/set)fullName: {get() {return this.firstName + this.lastName},set(value) {const arr = value.split(' ')this.firstName = arr[0]this.lastName = arr[1]}}}}
5.2 侦听器(watch)
监听数据变化,执行异步或复杂操作:
export default {data() {return {username: '',suggestList: []}},watch: {// 监听 username 变化username(newVal, oldVal) {// 模拟搜索建议请求clearTimeout(this.timer)this.timer = setTimeout(() => {this.fetchSuggest(newVal)}, 500)}},methods: {fetchSuggest(keyword) {// 发送请求获取建议列表this.suggestList = ['建议1', '建议2']}}}
5.3 过滤器(filter)
格式化数据显示,不改变原数据:
// 全局过滤器Vue.filter('dateFormat', (value) => {const date = new Date(value)return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`})// 局部过滤器export default {filters: {moneyFormat(value) {return '¥' + Number(value).toFixed(2)}}}
<!-- 使用过滤器 --><div>{{ createTime | dateFormat }}</div><div>{{ price | moneyFormat }}</div>
5.4 自定义指令
// 全局指令:自动聚焦输入框Vue.directive('focus', {// 元素插入 DOM 时触发inserted(el) {el.focus()}})// 局部指令:设置字体颜色export default {directives: {color: {// 绑定值更新时触发update(el, binding) {el.style.color = binding.value}}}}
<!-- 使用自定义指令 --><input v-focus><div v-color="textColor">自定义颜色</div>
六、生态工具:路由与状态管理
6.1 路由(vue-router 3.x)
安装与配置
# 安装npm install vue-router@3.x --save
// router/index.jsimport Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'import About from '../views/About.vue'Vue.use(VueRouter)const routes = [{ path: '/', component: Home },{ path: '/about', component: About }]const router = new VueRouter({mode: 'history', // 去除 URL 中的 #routes})export default router
路由使用
<!-- 路由链接 --><router-link to="/">首页</router-link><router-link to="/about">关于</router-link><!-- 路由出口(组件渲染位置) --><router-view></router-view><!-- 编程式导航 --><script>export default {methods: {goAbout() {this.$router.push('/about')}}}</script>
6.2 状态管理(Vuex 3.x)
核心概念
-
State:存储状态数据
-
Mutations:修改状态的唯一途径(同步操作)
-
Actions:处理异步操作,通过 mutations 修改状态
-
Getters:计算派生状态(类似 computed)
基本使用
// store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {count: 0},mutations: {increment(state) {state.count++}},actions: {// 异步增加计数incrementAsync({ commit }) {setTimeout(() => {commit('increment')}, 1000)}},getters: {doubleCount(state) {return state.count * 2}}})
<!-- 组件中使用 --><template><div>计数:{{ $store.state.count }}双倍:{{ $store.getters.doubleCount }}<button @click="handleIncrement">同步增加</button><button @click="handleIncrementAsync">异步增加</button></div></template><script>export default {methods: {handleIncrement() {this.$store.commit('increment')},handleIncrementAsync() {this.$store.dispatch('incrementAsync')}}}</script>
七、避坑技巧与学习资源
7.1 常见坑点
1. 响应式数据问题
- 直接给对象添加新属性不会触发响应:
// 错误this.user.age = 18// 正确(使用 Vue.set 或重新赋值)this.$set(this.user, 'age', 18)
- 数组直接修改索引不会触发响应:
// 错误this.list[0] = '新值'// 正确(使用数组方法)this.list.splice(0, 1, '新值')
2. v-for 与 v-if 混用
不建议同时使用,可先用计算属性过滤数据:
computed: {filteredList() {return this.list.filter(item => item.isShow)}}
<!-- 推荐写法 --><li v-for="item in filteredList" :key="item.id">{{ item.name }}</li>
