# fed-e-task-03-01 **Repository Path**: rpyoyo/fed-e-task-03-01 ## Basic Information - **Project Name**: fed-e-task-03-01 - **Description**: No description available - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-12-11 - **Last Updated**: 2020-12-19 ## 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' } } }) ``` 动态给data增加的成员不是响应式的 可以通过Vue.set()或vm.$set()方法设置新的响应式属性 Vue在创建实例初始化的时候,会将data中的属性转换成响应式的,并注入到Vue实例中 + Vue 2.x 通过`Object.defineProperty() ` 将对象中的属性转换为 getter/setter 方法 + Vue 3.x 通过ES6新增的 `Proxy` 来实现 data中的属性重新赋值时会触发属性的set方法,此时会将新赋值的内容转换成响应式的 而新增加成员属性不会触发转换响应式的过程,因此不是响应式的,通过Vue.set()或vm.$set()方法,可以为对象添加属性的同时,触发转换属性为响应式数据的过程 ### 2、请简述 Diff 算法的执行过程 + Diff算法只对同级别的节点进行依次比较 + 在同级别比较时,对新老节点数组的开始与结尾设置标记索引并获取相应的节点vnode(oldStartVnode、oldEndVnode、newStartVnode、newEndVnode),比较过程中移动索引的位置 + 循环比较时先依次使用四种方式 + oldStartVnode vs newStartVnode + oldEndVnode vs newEndVnode + oldStartVnode vs newEndVnode + oldEndVnode vs newStartVnode + 如果比较的新旧节点相同,则调用patchVnode更新DOM,并移动标记索引,开始索引++,结尾索引-- + 如果上述四种方式均没有找到相同的节点,则使用newStartVnode.key在旧节点数组中寻找是否存在相同key的节点 + 如果没找到相同key的节点,则当前节点是新增节点,调用createElm创建新的DOM元素,并插入到oldStartVnode之前 + 如果找到相同key的节点,但是sel不同,则认为节点被修改,调用createElm创建新的DOM元素,并插入到oldStartVnode之前 + 如果找到相同key的节点,且sel相同,认为是相同节点,将该节点移动到oldStartVnode之前 + 移动新节点数组的开始索引,开始下一轮循环 + 循环比较执行完成之后,比较新老节点数组的长度是否一致 + 老节点数量大于新节点数量,则删除多余的老节点 + 老节点数量小于新节点数量,则创建多余的新节点 ## 二、编程题 ### 1、模拟 VueRouter 的 hash 模式的实现,实现思路和 History 模式类似,把 URL 中的 # 后面的内容作为路由的地址,可以通过 hashchange 事件监听路由地址的变化。 > 详见 code/01/vue-router-demo/vue-router/index.js ### 2、在模拟 Vue.js 响应式源码的基础上实现 v-html 指令,以及 v-on 指令。 > 详见 code/02/vue-app/vue/compiler.js ### 3、参考 Snabbdom 提供的电影列表的示例,利用Snabbdom 实现类似的效果,如图: ![img](https://s0.lgstatic.com/i/image/M00/26/F2/Ciqc1F7zUZ-AWP5NAAN0Z_t_hDY449.png) > 详见 code/03/snabbdom-demo