Vue2 学习指南
目录
基础概念
Vue 实例
javascript
// 创建 Vue 实例
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
greet() {
alert(this.message);
}
}
});
// 使用 Vue 实例
const app = new Vue({
el: '#app',
data: {
count: 0
}
});
// 访问数据
console.log(app.count);
app.count = 1;说明:
- el: 挂载点
- data: 数据对象
- methods: 方法对象
- 实例属性和方法
模板语法
html
<!-- 插值 -->
<div>{{ message }}</div>
<!-- 指令 -->
<div v-if="seen">现在你看到我了</div>
<div v-for="item in items">{{ item.text }}</div>
<div v-bind:class="{ active: isActive }"></div>
<div v-on:click="doSomething"></div>
<!-- 缩写 -->
<div :class="{ active: isActive }"></div>
<div @click="doSomething"></div>
<!-- 计算属性 -->
<div>{{ reversedMessage }}</div>
<!-- 过滤器 -->
<div>{{ message | capitalize }}</div>说明:
- 文本插值
- 指令系统
- 缩写语法
- 计算属性
- 过滤器
计算属性和侦听器
javascript
new Vue({
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: {
get() {
return this.firstName + ' ' + this.lastName;
},
set(newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
}
}
},
watch: {
firstName(newVal, oldVal) {
console.log('firstName changed:', oldVal, '->', newVal);
}
}
});说明:
- 计算属性缓存
- 计算属性 setter
- 侦听器选项
- 深度监听
组件开发
组件基础
javascript
// 全局组件
Vue.component('my-component', {
template: '<div>一个全局组件</div>'
});
// 局部组件
const ChildComponent = {
template: '<div>一个局部组件</div>'
};
new Vue({
el: '#app',
components: {
'child-component': ChildComponent
}
});
// 单文件组件
// MyComponent.vue
<template>
<div class="my-component">
<h1>{{ title }}</h1>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'MyComponent',
props: {
title: {
type: String,
required: true
}
}
};
</script>
<style scoped>
.my-component {
color: #42b983;
}
</style>说明:
- 组件注册
- 组件选项
- 单文件组件
- 作用域样式
组件通信
javascript
// 父组件
Vue.component('parent-component', {
template: `
<div>
<child-component
:message="message"
@update="handleUpdate"
></child-component>
</div>
`,
data() {
return {
message: 'Hello from parent'
};
},
methods: {
handleUpdate(newValue) {
this.message = newValue;
}
}
});
// 子组件
Vue.component('child-component', {
props: ['message'],
template: `
<div>
<p>{{ message }}</p>
<button @click="updateMessage">Update</button>
</div>
`,
methods: {
updateMessage() {
this.$emit('update', 'Updated message');
}
}
});
// 事件总线
const EventBus = new Vue();
// 发送事件
EventBus.$emit('event-name', data);
// 监听事件
EventBus.$on('event-name', data => {
console.log(data);
});说明:
- Props 传递
- 事件触发
- 事件总线
- 依赖注入
生命周期
javascript
new Vue({
el: '#app',
data: {
message: 'Hello'
},
beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
},
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroyed');
}
});说明:
- 创建阶段
- 挂载阶段
- 更新阶段
- 销毁阶段
状态管理
Vuex
javascript
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
getters: {
doubleCount: state => state.count * 2
},
mutations: {
INCREMENT(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('INCREMENT');
}, 1000);
}
},
modules: {
user: {
namespaced: true,
state: {
name: 'John'
},
mutations: {
SET_NAME(state, name) {
state.name = name;
}
}
}
}
});
// 组件中使用
export default {
computed: {
count() {
return this.$store.state.count;
},
doubleCount() {
return this.$store.getters.doubleCount;
}
},
methods: {
increment() {
this.$store.commit('INCREMENT');
},
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
};说明:
- State 管理
- Getters 计算
- Mutations 修改
- Actions 异步
- Modules 模块
路由管理
Vue Router
javascript
// router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
},
{
path: '/user/:id',
name: 'User',
component: () => import('../views/User.vue'),
props: true
}
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
});
// 导航守卫
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login');
} else {
next();
}
});
export default router;
// 组件中使用
export default {
methods: {
goToHome() {
this.$router.push('/');
},
goToUser(id) {
this.$router.push({ name: 'User', params: { id } });
}
}
};说明:
- 路由配置
- 动态路由
- 导航守卫
- 路由组件
最佳实践
1. 代码组织
- 使用单文件组件
- 模块化管理
- 遵循命名规范
- 保持组件简洁
2. 性能优化
- 合理使用计算属性
- 避免不必要的渲染
- 使用 keep-alive
- 懒加载组件
3. 开发技巧
- 使用 Vue Devtools
- 编写单元测试
- 使用 TypeScript
- 遵循 Vue 风格指南
学习资源
官方文档
视频课程
- 慕课网
- 极客时间
- B站技术区
- YouTube 技术频道