vue中的三要素,你知道几个呢?

veu中的三要素

  • 响应式:vue如何监听到 data 每个属性变化?
  • 模板引擎:vue的模板如何被解析,指令如何处理?
  • 渲染:vue 的模板如何被渲染成 html?以及渲染过程

vue 如何实现是响应式

  • 什么是响应式
  • Object.defineProperty
  • 模拟

1) 什么是响应式

  • 修改 data 属性之后, vue 立刻监听
  • data 属性被代理到 vm 上

2) Object.defineProperty

语法:
Object.defineProperty(obj, prop, descriptor)
参数说明:
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性
基础
var obj = {
  name: 'zhangsan',
  age: 25
}

console.log(obj.name); // 获取属性的时候,如何监听
obj.age = 26; // 赋值属性的时候,如何监听

我们用defineProperty方法实现上面的操作:如下

var obj = {}

var name = 'zhangsan'

Object.defineProperty(obj, "name", {
  get: function () {
    console.log('get');
    return name;
  },
  set: function (newVal) {
    console.log('set');
    name = newVal;
  }
});

console.log(obj.name); // 可以监听到
obj.name = 'lisi'; // 可以监听到

使用defineProperty我们就可以监听到数据变化了。其中这个也是 vue 做响应工做核心的方法了。

3) 模拟

var mv = {}

var data = {
  price: 100,
  name: 'zhangsan'
}

var key, value;
for (key in data) {

  // 命中闭包。新建一个函数,保证 key 的独立的作用域
  (function (key) {
Object.defineProperty(mv, key, {
  get: function () {
    console.log('get');
    return data[key];
  },
  set: function (newVal) {
    console.log('set');
    data[key] = newVal
  }
})
  })(key);
}

vue的模板如何被解析

  • 模板是什么
  • render 函数
  • render 函数 与 vdom

1) 模板是什么

  1. 本质:字符串
  2. 有逻辑,如 v-if v-for等
  3. 与 html 格式很像,但有很大的区别
  4. 最终还要转换成 html 来显示
  5. 模板最终必须转换成 JS 代码, 因为:

    • 有逻辑(v-if v-for),必须用 JS 才能实现( 图灵完备)
    • 转换为 html 渲染页面,必须用 JS 才能实现
    • 因此,模板最重要转换成一个 JS 函数
基础事例
 <div id="app">
    <div>
      <input v-model="title">
      <button v-on:click="add">submit</button>
    </div>
    <ul>
      <li v-for="item in list">{{item}}</li>
    </ul>
  </div>

以上就是一个模板。

2) render 函数

with 用法(vue render有用到,所以说下用法 ,具体开发中建议不使用)

clipboard.png

简要说明

with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。

render 函数

基础事例

VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数。
比如如下我想要实现如下html:

clipboard.png

我们来尝试使用 render函数重写上面的demo,如下:

clipboard.png

  1. 模板中所有信息都包含在了 render 函数中
  2. this 即 vm
  3. price 即 this.price 即 vm.price, 即 data 中的 price
  4. _c 即 this._c 即 vm._c

clipboard.png

通过控制台打印,我们就知道了 _c就是一个创建dom 元素的方法, _v 是一个创节点的方法, _s 是 toString 方法。

3) render 函数 与 vdom

clipboard.png

  • updateComponent 中实现了 vdom 的 patch
  • 页面首次渲染执行 updateComponent
  • data中每次修改属性,执行 updateComponent

vue 的整个实现流程

  • 第一步: 解析模板成 render 函数
  • 第二步: 响应式开始监听
  • 第三步: 首次渲染,显示页面,且绑定依赖
  • 第四步: data 属性变化,触发 render
例子

clipboard.png

简要说明:通过 input 输入,我们点击按钮把输入的内容放进:list 中,通过 li 展示出来。

第一步: 解析模板成 render 函数

clipboard.png

通过vue 原码高度生成对应的 render 函数如下:

clipboard.png

  • with 用法
  • 模板中的所有信息都被 render ,函数包含
  • 模板中用到的 data 中属性,都变成了 JS 变量
  • 模板中的 v-model v-for v-on 都变成了 JS 逻辑
  • render 函数返回 vnode
第二步:响应式开始监听

clipboard.png

  • Object.defineProperty
  • 将 data 的属性代理到 vm 上
第三步:首次渲染,显示页面,且绑定依赖

clipboard.png

  • 初次渲染,执行 updateComponent,执行 updateComponent,执行 vm._render()
  • 执行 render 函数,会访问到 vm.list 和 vm.title
  • 会被响应式的 get 方法监听到
  • 执行 updateComponent, 会走到 vdom 的 patch 方法
  • patch 将 vnode 渲染成 DOM,初次渲染完成

clipboard.png

为何要监听 get, 直接监听 set 不行吗
  1. data 中有很多属性,有些被用到,有些可能不被用到
  2. 被用到的会走 get, 不被用到的不会走 get
  3. 未走到 get 中的属性, set的时候我们也无需关心
  4. 避免不必要的重复渲染

clipboard.png

js 中有 title, list, aaa,其中aaa 在html中没有用到,所以走不了 get监听,那以后在对 aaa的值进行修改,vue 就不管它,不会重新渲染。

第四步:data 属性变化

clipboard.png

clipboard.png

  • 修改属性,被响应式的 set 监听到
  • set 中执行 updateComponent
  • updateComponent 重新执行 vm._render()
  • 生成 vnode 和 preVnode, 通过 patch 进行对比
  • 渲染到 html 中
愿你成为终身学习者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值