# fed-e-task-03-01
**Repository Path**: yang_154/fed-e-task-03-01
## Basic Information
- **Project Name**: fed-e-task-03-01
- **Description**: 31作业
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-05-28
- **Last Updated**: 2021-06-01
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 一、简答题
### 1、当我们点击按钮的时候动态给 data 增加的成员是否是响应式数据,如果不是的话,如何把新增成员设置成响应式数据,它的内部原理是什么。
```js
let vm = new Vue({
el: '#el'
data: {
o: 'object',
dog: {}
},
method: {
clickHandler () {
// 该 name 属性是否是响应式的
this.dog.name = 'Trump'
}
}
})
```
答:不是响应式的数据。如果需要把新增的成员设置成响应式数据,需要使用vue官方提供的vm.set(target,key,value)函数。
不是响应式数据的原因:vue2中响应式实现依赖的是object.definePorperty函数,而且在vue实例初始化的时候,所有的数据都被绑定到vm实例上以实现响应式数据。直接使用dog.name的方式设置属性的时候,vm实例上并不能挂载name的set函数,也就无法实现name属性的响应式。
使用vm.set()函数可以实现响应式的原因:很明显是set函数将name属性挂载到了vm实例中,并且为其挂载了set、get方法,实现了响应式。
### 2、请简述 Diff 算法的执行过程
答:diff算法的目的是找到新旧dom树的差异然后用尽可能少的操作对dom树进行更新。如果让每个节点都和其他节点进行比较,则光是比较阶段就需要n的二次方时间复杂度,再加上增删改差异节点的步骤,时间复杂度会变为n的三次方。
由于dom树很少在跨层级上面对节点进行修改,所以只比对同级别的dom节点,能够大大降低比对次数,降低时间复杂度。
在同一级别节点的diff算法执行过程是:
- 给新dom节点序列添加头指针和尾指针,头指针移动方向为序列尾部方向,尾指针移动方向为序列头部方向。
- 给旧dom节点序列同样的加上头指针和尾指针,运动方向同上
- (新dom序列头指针、尾指针) 与 (旧dom序列头指针、尾指针)组合方式共有四种,头头、尾尾、头尾、尾头。
- 上一条的四种组合方式依次执行,进行dom节点的比对。如果头头比对成功,是同一节点,则新dom头指针和旧dom头指针移动一次,继续比较,直到不是同一节点。然后对 尾尾 进行比较,以此类推。
- 经过上一条的执行。如果新dom节点序列有未匹配的dom节点,则按顺序补齐未匹配的dom节点。如果是旧dom节点序列出现多出的dom节点,则直接删除多出的dom节点。如果出现顺序错误,则空间换时间,改正顺序。
## 二、编程题
### 1、模拟 VueRouter 的 hash 模式的实现,实现思路和 History 模式类似,把 URL 中的 # 后面的内容作为路由的地址,可以通过 hashchange 事件监听路由地址的变化。
答案见 code/编程题——1.js,测试用例在 编程题——1测试用例 文件夹。
### 2、在模拟 Vue.js 响应式源码的基础上实现 v-html 指令,以及 v-on 指令。
答案见 编程题2/minivue/js/compiler.js ,并且已经在Index.html中加入了测试用例。
### 3、参考 Snabbdom 提供的电影列表的示例,利用Snabbdom 实现类似的效果,如图:
Snabbdom 版本升级过快, 新版本中 h、init 函数的引入方式如下:
```js
import { h } from 'snabbdom/build/package/h'
import { init } from 'snabbdom/build/package/init'
// 下面内容请按需导入
import { classModule } from 'snabbdom/build/package/modules/class'
import { propsModule } from 'snabbdom/build/package/modules/props.js'
import { styleModule } from 'snabbdom/build/package/modules/style.js'
import { eventListenersModule } from 'snabbdom/build/package/modules/eventlisteners.js'
```
答案见 编程题——3 文件夹。