【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 函数中。

模板:

<div id="app">
    <div>
      <input type="text" v-model="title">
      <button v-on:click="add">submit</button>
    </div>
    <div>
      <ul>
        <li v-for="item in list">{{item}}</li>
      </ul>
    </div>
  </div>

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

// _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)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值