• Vue之计算属性


    示例:

    <template>
      <div id="app">
        <div ref="msg">{{ name }}</div>
        <button @click="change">change</button>
        <button @click="changeLast">changeLast</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {
          firstName: 'Yi',
          lastName: 'Huang',
          useless: 0
        };
      },
      computed: {
        name() {
          if (this.useless > 0) {
            return this.firstName + ',' + this.lastName;
          }
          return 'please click change'
        }
      },
      methods: {
        change() {
          this.useless++;
        },
        changeLast() {
          this.lastName = 'Zhang';
        }
      }
    }
    </script>
    1. 首先在App组件render生成vnode过程中,会访问name,访问name就会执行到以下代码:|
      function createComputedGetter (key) {
        return function computedGetter () {
          const watcher = this._computedWatchers && this._computedWatchers[key]
          if (watcher) {
            if (watcher.dirty) {
              watcher.evaluate()
              // 这一步Dep.target是这个computed watcher,完成了依赖收集,然后因为执行了popTarget,Dep.target 变回了渲染watcher
            }
            if (Dep.target) {
              watcher.depend()
              // 这一步将刚才收集的依赖又添加到了渲染watcher中
            }
            return watcher.value
          }
        }
      }
    2. 这个函数中,首先执行watcher.evaluate,执行过程中会对(用户写入的computed里面的name方法进行求值),求值的过程中就会访问到this.useless的getter方法,执行getter方法进行依赖收集,此时订阅的依赖是由computed的watcher订阅的依赖,也就是computed的watcher去订阅this.useless的变化,当this.useless的值发生变化时,就会触发set之后执行dep.notify而执行computed watcher自身的update。
    3. 执行完后返回值:'please click change'。接着执行watcher.depend方法,这一步将刚刚computed收集到的依赖,又添加进渲染watcher中,这样当值发生变化时,就会同时触发computed的update和重新渲染。
    4. 当点击change按钮时,this.useless发生变化,触发set,调用dep.notify,遍历dep.subs中的两个wacher,一个是computed wathcer一个是渲染wacher,依次执行update方法,如下
       update () {
          /* istanbul ignore else */
          if (this.lazy) {
            this.dirty = true
          } else if (this.sync) {
            this.run()
          } else {
            queueWatcher(this)
          }
        }
    5. 第一次是把this.dirty置为true,因为它是计算属性的watcher。第二次直接执行queueWatcher进行渲染,在渲染的过程中又会进行重新求值,在求值的过程中又会触发get,收集新的依赖(包括firstName和lastName的依赖),作用是为了当他们两个的值发生变化时,会触发computed的update过程。最后执行页面的重新渲染。

    在vue新版本中,只要修改了this.useless的值,不管计算属性最终返回什么值,都会进行重新渲染,而在旧版中会先判断值是否发生变化,如果计算属性返回的值没有变化,则不进行渲染。一句话说就是新版本:少计算,多渲染。旧版本:多计算,少渲染。

  • 相关阅读:
    终端ssh登录mac用shell打包ipa报错:replacing existing signature
    andrond mk通配符遍历文件夹
    一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
    (转)C++0x语言新特性一览
    (转)Xcode调试技巧
    (转)关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系
    自动编译和提交脚本(结合svn和visual studio)
    (转载)让XCode运行时自动更新资源
    cocos2dx3.0rc导出自定义类到lua的方法
    cocos2dx之lua派生类和方法重新
  • 原文地址:https://www.cnblogs.com/ltog/p/14451243.html
Copyright © 2020-2023  润新知