vue为什么要采用“声明式” 且要引入“虚拟DOM”

103 阅读2分钟

1.为什么选择“声明式”,而不是“命令式”

1.1 命令式关注的是过程,比如“jQuery”,就是典型的命令式框架

分析下面这段jQuery代码

$('#app') // 获取div
 .text('hello world') //设置文本内容
 .on('click', () => { alert('ok') }) //绑定点击事件

描述了 “获取div” -> "设置文本内容" -> "绑定点击事件" 这一过程, 这就是命令式框架的特点:关注过程

1.2 声明式关注的是结果, 比如 “vue”

以上代码用vue实现如下:

<div @click="() => alert('ok')">hello world</div>

可以发现, 以上代码提供的是一个结果,怎么实现这个“结果”,使用者并不关心。实现“结果”的过程,是在Vue.js内部完成的。也就是说, Vue.js帮我们封装了过程, 内部的实现是命令式的,暴露给外部用户的是声明式

1.3 两种范式对比

1.3.1 性能

  • 比如要修改div的内容,命令式代码代码如下

    div.textContent = '你好, 我是修改后的内容'
    

    直接调用相关命令

  • 声明式代码代码如下

    // 修改前的代码
    <div @click="() => alert('ok')">你好, 我是修改前的内容</div>
    
    // 修改后的代码
    <div @click="() => alert('ok')">你好, 我是修改后的内容</div>
    

    找到前后差异,然后更新差异的地方,最终完成跟新的代码仍然是

    div.textContent = '你好, 我是修改后的内容'
    

通过对比可以发现,声明式代码命令式代码 多了一步 找出前后差异的性能消耗

性能: 命令式代码 > 声明式代码

1.3.2 可维护性

命令式代码需要维护整个“过程”,

声明式代码展示最终的结果,不关心过程

声明式代码 > 命令式代码

1.4 总结

vue选择了声明式代码(维护性好),至于性能问题,做到损失最小化,也就是优化找出差异的性能消耗(比如虚拟DOM的出现就是为了最小化性能消耗)

2. 为什么要引入虚拟DOM, 虚拟DOM又是解决什么问题的

前面谈到, 声明式代码的更新性能消耗 = 找出差异的性能消耗 + 直接修改的性能消耗,虚拟DOM的出现就是为了最小化找出差异的性能消耗

虚拟DOM要解决的问题是: 写声明式代码且要保证程序的性能

2.1 性能、可维护性、心智负担对比

  • 创建阶段:

    虚拟DOM 和 原生DOM操作, 性能差别不大。

  • 更新阶段:

    虚拟DOM: 创建新的JavaScript对象 + Diff + 必要的DOM更新

    原生DOM操作: 必要的DOM更新

原生DOM操作,需要手动创建、删除DOM元素,所以它的心智负担大,可维护性差,但是性能好

虚拟DOM,不需要手动创建、删除DOM元素,所以它的心智负担小, 可维护性好,加上有Diff,性能虽没原生DOM好,但也不错