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 函数

基础事例

 
  • {{item}}

以上就是一个模板。

2) render 函数

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

vue中的三要素,你知道几个呢?_第1张图片

简要说明

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

render 函数

基础事例

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

vue中的三要素,你知道几个呢?_第2张图片

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

vue中的三要素,你知道几个呢?_第3张图片

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

vue中的三要素,你知道几个呢?_第4张图片

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

3) render 函数 与 vdom

vue中的三要素,你知道几个呢?_第5张图片

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

vue 的整个实现流程

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

例子

vue中的三要素,你知道几个呢?_第6张图片

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

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

vue中的三要素,你知道几个呢?_第7张图片

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

vue中的三要素,你知道几个呢?_第8张图片

  • with 用法
  • 模板中的所有信息都被 render ,函数包含
  • 模板中用到的 data 中属性,都变成了 JS 变量
  • 模板中的 v-model v-for v-on 都变成了 JS 逻辑
  • render 函数返回 vnode

第二步:响应式开始监听

vue中的三要素,你知道几个呢?_第9张图片

  • Object.defineProperty
  • 将 data 的属性代理到 vm 上

第三步:首次渲染,显示页面,且绑定依赖

vue中的三要素,你知道几个呢?_第10张图片

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

vue中的三要素,你知道几个呢?_第11张图片

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

vue中的三要素,你知道几个呢?_第12张图片

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

第四步:data 属性变化

vue中的三要素,你知道几个呢?_第13张图片

vue中的三要素,你知道几个呢?_第14张图片

  • 修改属性,被响应式的 set 监听到
  • set 中执行 updateComponent
  • updateComponent 重新执行 vm._render()
  • 生成 vnode 和 preVnode, 通过 patch 进行对比
  • 渲染到 html 中
愿你成为终身学习者

你可能感兴趣的:(vue中的三要素,你知道几个呢?)