computed 是基于响应性依赖来进行缓存的。只有依赖数据发生改变,才会从新进行计算(当触发从新渲染,若依赖数据没有改变,则 computed 不会从新计算)。若没改变,计算属性会当即返回以前缓存的计算结果。html
不支持异步,当 computed 内有异步操做时无效,没法监听数据的变化的值。vue
computed 中的成员能够只定义一个函数做为只读属性, 也能够定义成 get/set 变成可读写属性api
若是一个属性是由其余属性计算而来的,这个属性依赖其余属性,是一个多对一或者一对一,通常用 computed。数组
下面的计算属性将再也不更新,由于 Date.now()
不是响应式依赖:缓存
computed: { now: function () { return Date.now() } }
相比之下,每当触发从新渲染时,调用方法将总会再次执行函数。frontend
咱们为何须要缓存?假设咱们有一个性能开销比较大的计算属性 A,它须要遍历一个巨大的数组并作大量的计算。而后咱们可能有其余的计算属性依赖于 A。若是没有缓存,咱们将不可避免的屡次执行 A 的 getter!若是你不但愿有缓存,请用方法来替代。异步
不支持缓存,数据变或者触发从新渲染时,直接会触发相应的操做。函数
watch 支持异步性能
当一个属性发生变化时,须要执行对应的操做;一对多时,通常用 watch。this
监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其余操做,函数有两个参数,immediate:组件加载当即触发回调函数执行,deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变更不须要这么作。注意:deep 没法监听到数组的变更和对象的新增,参考 vue 数组变异,只有以响应式的方式触发才会被监听到。
相同点:
不一样点:
类型:{ [key: string]: Function | { get: Function, set: Function } }
详细:
计算属性将被混入到 Vue 实例中。全部 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。
注意若是你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然能够将其实例做为函数的第一个参数来访问。
computed: { aDouble: vm => vm.a * 2 }
计算属性的结果会被缓存,除非依赖的响应式 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
类型:{ [key: string]: string | Function | Object | Array }
详细:
一个对象,键是须要观察的表达式,值是对应回调函数。值也能够是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每个 property。
var vm = new Vue({ data: { a: 1, b: 2, c: 3, d: 4, e: { f: { g: 5, }, }, }, watch: { a: function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) }, // 方法名 b: 'someMethod', // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深 c: { handler: function (val, oldVal) { ;/_ ... _/ }, // or handler:'方法名' deep: true, }, // 该回调将会在侦听开始以后被当即调用 d: { handler: 'someMethod', // or handler: function(val, oldVal){} immediate: true, }, // 你能够传入回调数组,它们会被逐一调用 e: [ 'handle1', function handle2(val, oldVal) { /* ... */ }, { handler: function handle3(val, oldVal) { /* ... */ }, /* ... */ }, ], // watch vm.e.f's value: {g: 5} 'e.f': function (val, oldVal) { ;/_ ... _/ }, }, }) vm.a = 2 // => new: 2, old: 1
a: 监听一个属性,须要使用先后变化值时使用
b: 监听一个属性,不会使用到改变先后的值,只为了执行一些方法,可使用字符串代替 字符串表明方法名
c: 在监听一个对象时,当对象内部的属性被改变时,没法触发 watch,设置 deep 为 true 后,不管嵌套多深,只要属性值被改变都会触发监听。但这种方式开销会较大,监听器会一层一层往下找,为每一个属性添加监听器。
watch:{ 'user.name':{ handler: 'method' } }
d: watch 是在监听属性改变时才会触发,组件建立时可能不会执行,所以咱们能够设置 immediate: true
,就会让在组件建立后 watch 可以当即执行一次。就不用在 create 的时候去修改属性啦。
handelr: 触发监听执行的方法(须要用到改变先后的值时,可换成函数)
immediate: 监听开始以后被当即调用
e: 监听一个属性,执行多个函数包括回调等
注意,不该该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级做用域的上下文,因此 this 将不会按照指望指向 Vue 实例,this.updateAutocomplete 将是 undefined。
原文地址:http://book.levy.net.cn/doc/frontend/vue/vue_computed_watch.html