Skip to content

vue 原理

仲灏约 1 分钟

vue 原理

  • 响应式
  • vdom
  • 模板解析
  • 渲染过程
  • 异步渲染

响应式

响应式的作用:监听 data 数据变化,仅此而已。所以,不要掺杂进其他功能进来。

回顾 Object.defineProperty 方式

vdom

回顾 vdom

  • h 函数
  • vnode 结构
  • patch 函数

模板解析

with 语法

  • 改变 {} 内自由变量,当做 obj 属性来查找
  • 如果找不到会报错
  • with 要慎用,因为它打破了作用域的规则
js
const obj = {a: 100, b: 200}

console.log(obj.a)
console.log(obj.b)
console.log(obj.c) // undefined

// 使用 with ,能改变 {} 内自由变量的查找方式
// 将 {} 内自由变量,当做 obj 的属性来查找
with(obj) {
    console.log(a)
    console.log(b)
    console.log(c) // 会报错 !!!
}

编译 render 函数

  • 原生 html 不识别指令
  • html 是静态标记语言,不具备运算能力(不是图灵完备的语言,不能顺序、判断、循环运算)
  • 将 html 模板转换为 js 函数(render 函数)
  • 执行 render 函数,生成 vnode。重要!!!

如何转换,参考 vue-template-compiler 示例

vue 函数式组件

https://cn.vuejs.org/v2/guide/render-function.html#函数式组件

使用 render 函数代替 template

js
Vue.component('heading', {
  // template: `xxxx`,
  render: function (createElement) {
    return createElement(
      'h' + this.level,
      [
        createElement('a', {
          attrs: {
            name: 'headerId',
            href: '#' + 'headerId'
          }
        }, 'this is a tag')
      ]
    )
  }
})

渲染过程

回顾 3 个要点

  • 响应式 监听数据 get set
  • 模板解析 生成 render 函数,执行则返回 vnode
  • vdom 根据 vnode 渲染/更新 DOM

初次渲染过程

  • 对 data 进行响应式处理,监听 get set
  • 解析模板为 render 函数(这一步可能在开发环境打包时就已经完成,重要!!!
  • 执行 render 函数,生成 vnode
    • 这一步会触发 data getter ,收集依赖,重要!!!
    • 将该数据 “观察”起来
    • 注意,不一定所有的 data 都会被观察,得看模板中是否用到了,如下图。
  • 将 vnode 渲染到页面上
html
<p>{{message}}</p>

<script>
export default {
    data() {
        return {
            message: 'hello', // 会触发 get
            city: '北京' // 不会触发 get ,因为模板没用到,即和视图没关系
        }
    }
}
</script>

数据更新过程

  • 修改“被观察的”数据,触发 data setter
  • 重新执行 render 函数,生成 newVnode
  • patch(vnode, newVnode)

图示

vue 官网的流程图 https://cn.vuejs.org/images/data.png


异步渲染

回顾 nextTick

  • 异步渲染
  • 汇总 data 变化,一次性渲染
  • 尽量减少渲染次数,提高性能

上次更新:

讨论区

欢迎留下想法与补充