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好,但也不错