关于vue的计算属性以及双向绑定的原理理解(vue2.x)以及vue3.0

vue的计算属性:

1.什么是计算属性?                 

计算属性的目的是用于对数据进行简单运算的,若在模板中放过多的计算逻辑会导致模板难以维护。

计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。

2.计算属性如何使用?

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,相关用法如下:

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 函数,执行一些自定义的操作

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

  -计算属性是基于它们的依赖进行缓存的。

  -计算属性只有在它的相关依赖发生改变时才会重新求值

相关函数的案例转自:https://www.cnblogs.com/chaixiaozhi/p/8688820.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

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

 有关proxy与defineProperty的区别:

 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

             

猜你喜欢

转载自www.cnblogs.com/BR-Tao/p/11408306.html