# part_three_module_one **Repository Path**: february23/part_three_module_one ## Basic Information - **Project Name**: part_three_module_one - **Description**: 拉勾教育3-1练习题 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-03 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # part_three_module_one #### 介绍 拉勾教育3-1练习题 #### 软件架构 软件架构说明 #### 练习题内容 ## 1. 当我们点击按钮的时候动态给 data 增加的成员是否是响应式数据,如果不是的话,如何把新增成员设置成响应式数据,它的内部原理是什么。 ``` let vm = new Vue({ el: '#el' data: { o: 'object', dog: {} }, method: { clickHandler () { // 该 name 属性是否是响应式的 this.dog.name = 'Trump' } } }) ``` 以代码中的方式,name属性是非响应式的。因为在vue初始化的时候,会遍历data中的所有属性,这些属性及属性中的属性都是相应是的,但是this.dog.name这种方式,name属性并不在vue的初始化过程中,所以是非响应式的。 通过this.dog = { name: 'Trump' } 或者 this.$set(this, dog, { name: 'Trump' })可以添加响应式属性 ## 2. 请简述 Diff 算法的执行过程 1. 判断两个虚拟dom是否是相同节点,如果是,对比其中的差异,并渲染;如果不是,将新节点直接渲染到dom,并删除旧节点 如何判断是否是相同节点:判断两个节点的sel是否相同 2. 对比差异时,只进行同级别子节点的比较,在进行同级别节点比较的时候,首先对新老节点数组的开始和结尾节点设置标记索引,通过移动索引实现循环遍历 前置假设: oldVNodes: 旧的虚拟节点集合 newVNodes: 新的虚拟节点集合 parentElm: 当前dom元素集合对应的虚拟节点集合,初始值为oldVNodes oldStartIndex: 旧的虚拟节点集合对应的开始索引,初始值为0 oldEndIndex: 旧的虚拟节点集合对应的结束索引,初始值为oldVNodes.length -1 newStartIndex: 新的虚拟节点集合对应的开始索引,初识值为0 newEndIndex: 新的虚拟节点集合对应的结束索引,初识值为newVNodes.length - 1 循环结束条件: oldStartIndex > oldEndIndex || newStartIndex > newEndIndex 比较条件: a. 判断 oldVNodes 当前开始节点元素是不是空的,如果是空的表示 DOM 已经移除,oldStartIndex++,进行下一轮比较 b. 判断 oldVNodes 当前结束节点元素是不是空的,如果是空的表示 DOM 已经移除,oldEndIndex--, 进行下一轮比较 c. 判断 newVNodes 当前开始元素是不是空的,如果是空的表示 DOM 已经移除,oldStartIndex++,进入下一轮比较 d. 判断 newVNodes 当前结束节点元素是不是空的,如果是空的表示 DOM 已经移除,oldEndIndex--, 进行下一轮比较 e. 判断 oldVNodes 与 newVNodes 当前开始节点元素是不是相同,如果相同,oldStartIndex++, newStartIndex++,进行下一轮比较 f. 判断 oldVNodes 与 newVNodes 当前结束节点元素是不是相同,如果相同,oldEndIndex--, newEndIndex--,进行下一轮比较 g. 判断 oldVNodes 当前开始节点元素与 newVNodes 的当前结束节点元素是否相同,如果相同,就将 parentElm 中当前开始节点(oldStartIndex)所对应的元素移动到 parentElm 的当前结束节点(oldEndIndex)所对应的元素的前面,oldStartIndex++, newEndIndex--,进行下一轮比较 h. 判断 oldVNodes 当前结束节点元素与 newVNodes 的当前开始节点元素是否相同,如果相同,就将 parentElm 中当前结束节点(oldEndIndex)所对应的元素移动到当前开始节点(oldStartIndex)所对应元素的前面,oldEndIndex--,newStartIndex++,进行下一轮比较 i. 如果上述判断条件都不满足,则需要新增节点,在parentElm的oldStartIndex所对应的元素前新增newStartIndex所对应的元素, newStartIndex++,进行下一轮比较 j. 如果 newVNodes 中的元素遍历完之后,oldVNodes中元素还没遍历完,oldVNodes中未遍历的元素即为需删除的元素 参考资料:https://www.jianshu.com/p/f45463e7be20 ## 3. 模拟 VueRouter 的 hash 模式的实现,实现思路和 History 模式类似,把 URL 中的 # 后面的内容作为路由的地址,可以通过 hashchange 事件监听路由地址的变化。 https://gitee.com/february23/imitate_vue_router.git ## 4. 在模拟 Vue.js 响应式源码的基础上实现 v-html 指令,以及 v-on 指令。 https://gitee.com/february23/mini_vue.git ## 5. 参考 Snabbdom 提供的电影列表的示例,利用Snabbdom 实现类似的效果 https://gitee.com/february23/snabbdom_test.git