Vue2的一些原理

2020-07-18  本文已影响0人  hellomyshadow

keep-alive

keep-alive - 多看源码,方知原理,才能优化

Vue的编译运行

vue runtime + complier

一个单文件组件的模式:template、script、style

vue的编译运行.png

所以,直接使用 render 函数可以在一定程度上优化编译过程。

Look实现原理

  1. computedwatch
    实际上它们都是通过 watcher 实现的,最大区别就是 computed 具有缓存功能。

在创建计算属性时,它会创建一个watcher,其中有两个属性lazy:true, dirty: true
创建过程默认是不执行的,只有当用户取值时才会判断 dirty:true 则让这个watcher去取值,求值结束后则改为dirty:false,不再重新求值,再次取值直接返回上次求值结果。
那什么时候会重新计算求值呢?
只有当计算属性中依赖的值发生变化时,它会调用对应的update(),更改dirty:true,从而重新执行watcher求值。

  1. v-ifv-for 不能一起使用,必要时应使用 computed 先过滤出需要的数组元素。
    原因是 v-forv-if 的优先级更高,即使只需要其中一个元素(只有一个元素的v-if="true"),每一次仍然需要遍历整个数组,严重影响性能。
    源码编译
    // 1. v-if 在父元素上,v-for 在子元素上
    VueTemplateCompiler.compile(`<div v-if="true"><span v-for="i in 3">hello</span></div>`);
    // 模板的编译结果
    with(this) {
        return (true) ? _c('div', _l((3), function (i) {
            return _c('span', [_v("hello")])
        }), 0) : _e() // _e()方法创建一个空的虚拟dom等等。
    }
    // 2. v-for 与 v-if 连用的编译结果
    VueTemplateCompiler.compile(`<div v-if="false" v-for="i in 3">hello</div>`);
    with(this) {
        return _l((3), function (i) {
            return (false) ? _c('div', [_v("hello")]) : _e()
        })
    }
    
  2. v-show 的底层实现
    v-show编译出来里面没有任何东西,只有一个directives,它里面有一个指令叫做v-show
    源码编译
    VueTemplateCompiler.compile(`<div v-show="true"></div>`);
    with(this) {
        return _c('div', {
            directives: [{
                name: "show",
                rawName: "v-show",
                value: (true),
                expression: "true"
            }]
        })
    }
    
    只有在运行的时候它会去处理这个指令,它正是在操作DOM的 display 属性
    // v-show 操作的是样式  定义在platforms/web/runtime/directives/show.js
    bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
        vnode = locateNode(vnode)
        const transition = vnode.data && vnode.data.transition
        const originalDisplay = el.__vOriginalDisplay =
          el.style.display === 'none' ? '' : el.style.display
        if (value && transition) {
          vnode.data.show = true
          enter(vnode, () => {
            el.style.display = originalDisplay
          })
        } else {
          el.style.display = value ? originalDisplay : 'none'
        }
    }
    
上一篇下一篇

猜你喜欢

热点阅读