计算属性的目的是用于对数据进行简单运算的,若在模板中放过多的计算逻辑会致使模板难以维护。html
计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会从新求值。vue
1.在一个计算属性里能够完成各类复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就能够。浏览器
computed: { reverseText: function(){ return app1.text.split('').reverse().join(''); //对数据进行计算,将reverseText放进模板中,只要依赖的数据发生变化就会改变 } }
2.计算属性还能够依赖多个Vue 实例的数据,只要其中任一数据变化,计算属性就会从新执行,视图也会更新。缓存
两个小方面:一是计算属性能够依赖其余计算属性; 二是计算属性不只能够依赖当前Vue 实例的数据,还能够依赖其余实例的数据。性能优化
<div id="app1"></div> <div id="app2">{{ reverseText}}</div>
var app1 = new Vue({ el: '#app1', data: { text: 'computed' } }); var app2 = new Vue({ el: '#app2', computed: { reverseText: function(){ return app1.text.split('').reverse().join(''); //使用app1的数据进行计算 } } });
每个计算属性都包含一个getter 和一个setter ,计算属性会默认使用getter,相关用法以下:app
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' '); this.firstName = names[0]; this.lastName = names[names.length - 1]; } } } });
在咱们平常使用中,一般不用特地声明setter,当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter 函数,执行一些自定义的操做ide
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' '); this.firstName = names[0]; this.lastName = names[names.length - 1]; } } } }); //如今再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
绝大多数状况下,咱们只会用默认的getter 方法来读取一个计算属性,在业务中不多用到setter,因此在声明一个计算属性时,能够直接使用默认的写法,没必要将getter 和setter 都声明。函数
总结:当一个属性data须要进行逻辑性的运算和判断时,便出现了计算属性(computed),计算属性一个最大的特色就是会判断依赖的数据是否改变来判断,若未改变便会利用以前储存的数据,不用再获取,虽然方法也能够实现逻辑的运算,但不会监听数据是否发生了变化,会进行重复性的请求,因此计算属性更加优化和智能。性能
computed vs methods 优化
-计算属性是基于它们的依赖进行缓存的。
-计算属性只有在它的相关依赖发生改变时才会从新求值
相关函数的案例转自:http://www.javashuo.com/article/p-svqnaisq-cr.html
一个普通的 JavaScript 对象传入 Vue 实例做为 data
选项,Vue 将遍历此对象全部的属性,并使用 defineProperty 把这些属性所有转为 getter/setter
Object.defineProperty 是 ES5 中一个没法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的缘由
// 给对象添加属性的语法 var data = {} // IE8和以前浏览器不支持 // 一种给对象添加属性的方式 // 给obj添加name属性 // 这样加属性的好处是,能够监听属性的赋值和取值 // 当对象给这个属性赋值时,就会调用set方法 // 取值时就会调用get方法 Object.defineProperty(data,'name',{ get(){ // console.log('取值了'); //必须在get最后写return _属性名 return _name; }, // value是你赋值时是什么值,就传过来什么 set(value){ // console.log('set'); // 必须写_属性名 = value _name = value // console.log(data.name); var list = document.querySelectorAll('[v-bind]') for(var i = 0; i < list.length; i++){ list[i].innerHTML = value; } } })
这样就能够经过get和set来监听数据的获取和传值
上面就是目前Vue2.x的双向绑定原理,但即将发布的Vue3.0的双向绑定原理则采用了新的技术,就是proxy
let data = {} // new proxy对象 let proxyData = new Proxy(data,{ get(obj,prop){ console.log('get') console.log(obj) console.log(prop) return obj[prop] }, set(obj,prop,value){ //obj:绑定的对象 //prop:赋的属性 //value:属性值 obj[prop]= value console.log('set') console.log(obj) console.log(prop) console.log(value) } })
//obj:绑定的对象 //prop:赋的属性 //value:属性值
new的proxy对象绑定的数据data,只要是data任何属性发生改变都会调用
无论是这个对象的什么属性都会调用set或者get
1.Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty
不具有的。
2.Proxy返回的是一个新对象,咱们能够只操做新的对象达到目的,而Object.defineProperty
只能遍历对象属性直接修改。
3.Proxy做为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利。
4.Proxy的劣势就是兼容性问题,并且没法用polyfill磨平,所以Vue的做者才声明须要等到下个大版本(3.0)才能用Proxy重写。
相关详细资料参考:https://www.jianshu.com/p/2df6dcddb0d7