【Vue】Vue三要素模板解析、响应式、渲染

Vue 实现流程

        1、把模板解析为 render 函数

                       · 运用 with

                       · 模板中的所有信息都被 render 函数包含

                       · 模板中用到的 data 中的属性,都变成了 JS 变量

                       · 模板中的 v-model v-for v-on 都变成了 JS 逻辑
                       · render 函数返回 vnode

Vue三要素之模板解析

Vue模板的本质是字符串,有逻辑如 v-if v-for 等(模板转换成 js 后【 render 函数 】通过js来实现逻辑,因为前端语言中,只有 JS 是图灵完备的语言),与 html 格式很像,但有很大区别。html 是静态的, Vue 的模板是动态的。不过,最终 Vue 的模板都要通过 js 转换为 html 来显示。

模板中的所有内容都包含在了 render 函数中。

模板:

  • {{item}}

render 函数实例 (在 Vue 源码中通过 log(code.render)所得,vue.js 版本 5.2.13)

【Vue】Vue三要素模板解析、响应式、渲染_第1张图片

// _c 返回 Vnode
with(this){//this 就是 vm
  return _c(
    'div',
    {
      attrs:{"id":"app"}
    },
    [
      _c(
        'div',
        [
          _c(
            'input',
            {
              directives:[
                {
                  name:"model",
                  rawName:"v-model",
                  value:(title),
                  expression:"title"
                }
              ],
              attrs:{
                "type":"text"
              },
              domProps:{
                "value":(title)
              },
              on:{
                "input":function($event){
                  if($event.target.composing) return;
                  title=$event.target.value
                }
              }
            }
          ),
          _v(" "),
          _c(
            'button',
            {
              on:{
                "click":add
              }
            },
            [_v("submit")]
          )
        ]
      ),
      _v(" "),
      _c(
        'div',
        [
          _c(
            'ul',
            _l(
              (list),
              function(item){
                return _c(
                  'li',
                  [_v(_s(item))]
                )
              }
            )
          )
        ]
      )
    ]
  )
}

        2、响应式开始监听

                       · Object.defineProperty

                       · 将data 的属性代理到 vm 上

// 模拟 Vue 响应式
var vm = {}
  var data = {
    name: 'zhangsan',
    age: 20
  }
  var key, value
  for(key in data){
    (function (key){
      Object.defineProperty(vm, key, {
        get: function (){
          console.log('get', data[key])
          return data[key]
        },
        set: function (newVal){
          console.log('set', newVal)
          data[key] = newVal
        }
      })
    })(key)
  }

        3、首次渲染,显示页面且绑定依赖

                   · 初次渲染,执行 updateComponent, 执行 vm._render()

                   · 执行 render 函数,会访问到本篇文章例子的 vm.list 和 vm.title,也就是 data 下的数据

                   · 会被响应式的 get 方法监听到

                   · 执行 updateComponent,会走到 vdom 的 patch 方法

                   · patch 将 vnode 渲染成 DOM,初次渲染完成

        4、data 属性变化,触发 rerender (Dom repatch、模板 rerender)

你可能感兴趣的:(Vue)