2

计算属性computed

1.什么计算属性

  • 基础使用:同样是实现data中数据的反转表示,有以下两种不同写法,,显然第一种比第二种结构简洁和清晰,特别是在多次使用的时候,template里面的代码将更加混乱。

    <p>Computed reversed message: "{{ reversedMessage }}"</p>
    <p>Computed reversed message: "{{message.split('').reverse().join('')}}"</p> 
     var vm = new Vue({
      el: '#example',
      data: {
          message: 'Hello'
             },
      computed: {
      reversedMessage: function () {
             // `this` points to the vm instance
           return this.message.split('').reverse().join('')
      }}})
  • 使用场景:通过以上的使用我们可知,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。

  • 特点

    • ①使得数据处理结构清晰;

    • ②依赖于数据,数据更新,处理结果自动更新;

    • ③计算属性内部this指向vm实例;

    • ④在template调用时,直接写计算属性名即可;

    • ⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;

    • ⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

2.computed原理

//初始化计算属性
  function initComputed (vm: Component, computed: Object) {
     const watchers = vm._computedWatchers = Object.create(null)
     for (const key in computed) {
        const userDef = computed[key]
        const getter = typeof userDef === 'function' ? userDef : userDef.get
        //通过watch为计算属性添加动态响应.
        watchers[key] = new Watcher(vm, getter, noop, computedWatcherOptions)
        //组件定义的计算属性已经在组件原型上定义了。我们只需要在这里定义实例化的计算属性。
        if (!(key in vm)) {
        defineComputed(vm, key, userDef)}}
     }

  function defineComputed (target: any, key: string, userDef: Object | Function) {
       //userDef如果是函数类型,只有getter
       if (typeof userDef === 'function') {
          sharedPropertyDefinition.get = createComputedGetter(key)
          sharedPropertyDefinition.set = noop
       } else {
        //userDef如果是对象类型,可能存在getter或者setter
          sharedPropertyDefinition.get = userDef.get
          ? userDef.cache !== false
          ? createComputedGetter(key): userDef.get: noop
          sharedPropertyDefinition.set = userDef.set? userDef.set: noop}

      Object.defineProperty(target, key, sharedPropertyDefinition)}

  function createComputedGetter (key) {
        return function computedGetter () {
        const watcher = this._computedWatchers && this._computedWatchers[key]
        if (watcher) {
            if (watcher.dirty) {
                  watcher.evaluate()}
            if (Dep.target) {
                  watcher.depend()}
          return watcher.value}}}

  

何凯
966 声望174 粉丝

Never too late to learn!