1. watch,computed 和 methods 的区别
watch
- 定义:
- watch 是 options 的一个数据属性,负责监听/侦听;
- 一个对象,key 是需要 watch 的表达式,value 是对应的回调函数,也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用
$watch(),遍历 watch 对象的每一个 property
- 类型:
{ [key:string]: string | Function | Object | Array } - 注意:不能用箭头函数定义 watcher 函数,因为箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例。
- 实例:
vm.$watch(expOrFn, callback, [options])
- 参数
// 参数包含以下几种
{string | Function} expOrFn
{Fucntion | Object} callback
{Object} [options]
{boolean} deep
{boolean} immediate
- 返回值
{Function} unwatch
- 用法 观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。表达式只接受简单的键路径。对于更复杂的表达式,用一个函数取代。
- 选项
选项有 deep 和 immediate 两种。
(1). deep
为了发现对象内部值的变化,可以在选项参数中指定deep: true;如果不需要监听内部值的变化,则deep:false
(2). immediate
在选项参数中指定immediate:true,将立即以表达式的当前值触发回调,例如
vm.$watch('a', callback, {
immediate: true
})
// 立即以 `a` 的当前值触发回调
⚠️ 注意:在带有 immediate 选项时,不能在第一次回调时取消监听给定的 property,如果仍想在回调内部调用一个取消监听的函数,需要先检查其函数的可用性,例如
// 下面的代码会导致报错
var unwatch = vm.$watch(
'value',
function () {
doSomething()
unwatch()
},
{ immediate: true }
)
// 先检查可用性,再调用
var unwatch = vm.$watch(
'value',
function () {
doSomething()
if (unwatch) {
unwatch()
}
},
{ immediate: true }
)
computed
- 定义:
- 计算属性/被计算出来的属性,如果依赖的属性没有变化,就不会被重新计算;
- 计算属性将被混入到 Vue 实例中,所有 getter 和 setter 的 this 上下文自动绑定为 Vue 实例;
- 类型:
{ [key: string]: Function | {get: Function, set: Function} } - 注意
- 如果你为一个计算属性使用了箭头函数,那么这个
this不会指向这个组件的实例,不过还是可以把它座位函数的第一个参数~ - 计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意如果某个依赖,比如非响应式 property 在该实例范围之外,那么这个计算属性不会再次被更新~
- 实例
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3 // 在该实例范围之外,所以计算属性不会被再次更新~
vm.a // => 2
vm.aDouble // => 4
methods
- 定义:
- 方法,事件处理函数/普通函数
- methods 将被混入到 Vue 实例中,可以直接通过 VM 实例访问,或者在指令表达式中使用。methods 中的 this 自动绑定为 Vue 实例。
- 类型:
{ [key: string]: Function } - 注意:不应该使用箭头函数来定义 method 函数 (例如
plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。 - 实例
var vm = new Vue({
data: { a: 1 },
methods: {
plus: function () {
this.a++
}
}
})
vm.plus()
vm.a // 2
三者对比
- computed 和 methods:
- computed 有缓存,methods 没有;
- 如果 computed 属性依赖的属性没有变化,那么 computed 属性就不会重新计算;
- methods 则是看到一次计算一次。
- watch 和 computed
- computed 是计算出一个属性;
- watch 是监听,可能是做别的事情 (例如上报数据等).
- watch 和 methods
- watch 是监听,methods 是执行函数/事件处理函数
- watch 和 methods 的键/key 都是字符串,但是 methods 的值只接受函数,而 watch 的值接受字符串/函数/对象/数组,因为属性的定义不同,所以功能不一样,接受的数据类型也就不一样~
2. Vue 的生命周期钩子
图示

具体解释
- beforeCreate:Vue 实例出现在内存中以前;
- created:实例出现在内存中;
- beforeMount:实例出现在页面中以前;
- mounted:实例出现在页面中,请求数据发生在mounted周期中;
- beforeUpdate:实例更新以前;
- updated:实例更新了;
- beforeDestroy:实例从页面和内存中消亡以前;
- destoryed:实例从页面和内存中消亡了。
3. Vue 组件间通信
父子组件通信
父子/爷孙通信
- 父子组件通信,可以通过使用
v-on时间通信 - 隔代(爷孙)组件通信,可以通过两次
v-on实现
API
- v-on 的缩写(语法糖)是 @
- 预期:
Function | Inline Statement | Object - 参数:
event - 修饰符:
.stop
// 调用 event.stopPropagation()
.prevent
// 调用 event.preventDefault()
.capture
// 添加时间侦听器时使用 capture 模式
.self
// 只当事件是从侦听器绑定的元素本身触发时才触发回调
.{keyCode | keyAlias}
// 只当事件是从特定key触发时才触发回调
.native
// 监听组件根元素的原生事件
.once
// 只触发一次回调
.left
// 只当点击鼠标左键时触发
.right
// ...鼠标右键...
.middle
// ...鼠标中键...
.passive
// 以{passive:true}模式添加侦听器
- 用法
- 绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
- 用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
- 在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个
$eventproperty:v-on:click="handle('ok', $event)"。 - 从 2.4.0 开始,
v-on同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。
任意组件通信 | eventBus
- 用法:
eventBus = new Vue() - 主要 API
eventBus.$oneventBus.$emit
- 注意
- eventBus 不具备 DOM 组件
- eventBus是创建出来的全局事件总线,用法可以参考这篇:知乎文章:Vue事件总线 EventBus 使用介绍
任意组件通信 | Vuex
- Vuex 是专为 Vue.js 开发的状态管理模式,可以集中式存储管理应用所有组件的状态,并以响应的规则保证状态以一种可预测的方式发生变化。
- 核心概念有:State / Getter / Mutation / Action / Module
- 具体用法详见: Vuex 官方文档
4. Vue 数据响应式
响应式原理
options.data 会被 Vue 监听,会被 Vue 实例代理,每次对 data的读写都会被 Vue 监控,然后 Vue 会在 data 变化的时候更新 UI~
要点
- 使用
Object.defineProperty把这些属性全部转为getter/setter; - Vue 不能检测到对象属性的添加或删除,需要手动调用
Vue.set或this.$set解决 (Vue.set的重要用法)
5. VueRouter
- Vue Router 是 Vue.js 的官方路由管理器;
- 核心概念:History 模式/导航守卫/路由懒加载;
- 常用 API
router-link
router-view
this.$router.push
this.$router.replace
this.$router.params
this.$router.push('/user-admin')
Reference List | 参考资料
Vue 文档 : API
Vuex 官方文档
Vue 文档:深入响应式原理
知乎:EventBus使用介绍