这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
Vue.js双向绑定的实现原理
- 实现数据绑定的做法大致有如下几种:
- 发布者-订阅者模式(
backbone.js) - 脏值检查(
angular.js) - 数据劫持(
vue.js)
- 发布者-订阅者模式(
vue.js采用数据劫持的方式,结合发布者-订阅者模式,通过Object.defineProperty()来劫持各个属性的setter、getter以监听属性的变动,在数据变动时发布消息给订阅者,触发相应的监听回调。
<body>
<input type="text" name="" value="" id='J_vueInput'>
<p id="J_span"></span>
</body>
<script type="text/javascript">
var obj = {};
// 为obj定义一个名为 say 的访问器属性
Object.defineProperty(obj,'say',{
set: function (val) {
document.getElementById('J_vueInput').value = val;
document.getElementById('J_span').innerHTML = val;
}
})
document.addEventListener('keyup',function (e) {
obj.say = e.target.value;
})
</script>
getter是使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。
Vue中使用列表循环key的作用
- 给每个节点唯一的标识,可以高效渲染虚拟
DOM树 Vue更新使用v-for渲染的元素列表时,默认使用“就地更新”的策略- 使用
key给每个节点做一个唯一的标识,diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点diff的过程:调用名为“patch”的函数,比较新旧节点
v-show与v-if的区别
v-if:根据条件控制元素的创建与移除v-show:控制元素的显示与隐藏,通过displaycss样式属性控制,适合频繁的切换使用
区别
- 与
v-if不同的是:无论v-show的值为true还是false,DOM元素都会存在于HTML代码中;而只有当v-if的值为true,DOM元素才会存在于HTML代码中 v-if可以搭配template使用,而v-show不可v-if有配套的v-else-if与v-else,而v-show没有v-show有更高的切换开销,v-show切换开销小
相同点
- 都可以动态控制
DOM元素显示隐藏
vue组件通信
双向绑定和单项数据绑定的优缺点
- 单向绑定的优点:
- 带来单向数据流,这样的好处是流动方向可以跟踪、流动单一、没有状态。
- 单向数据流更利于状态的维护与优化,更利于组件之间的通信,更利于组件的复用
- 双向数据流的优点:
- 在一些需要实时反应用户输入的场合会非常方便,用户在视图上的修改会自动同步到数据模型中去,数据模型中值的变化也会立刻同步到视图中去
- 双向数据绑定的缺点
- 双向数据流是自动管理状态的,但是在实际应用中有很多需要手动处理状态变化的逻辑,使得程序复杂度上升,无法追踪局部状态的变化。
- 双绑跟单绑之间的差异只在于,双向绑定把数据变更的操作隐藏在框架内部,调用者并不会直接感知
谈谈你对组件的理解
- 可组合
- 可重用:每个组件都是具有独立功能的,它可以被使用多个场景(例如:添加和编辑)
- 可维护:每个组件仅仅包含自身的逻辑,更容易被理解和维护
- 可测试:因为每个组件都是独立的,那么对于各个组件分别测试显然要比对整个页面进行测试容易的多
在vue中,子组件为何不可以修改父组件传递的prop
- 为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。
- 官网解析
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解
vue的响应式原理中的Object.defineProperty有什么缺陷?
- 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应
Vue父组件和子组件生命周期钩子执行顺序?
- 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
- 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
- 父组件更新过程
父beforeUpdate->父updated
- 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
vue在create和mounted这两个生命周期中请求数据有什么区别?
- 在
created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html中的dom节点,一定找不到相关的元素 - 而在
mounted中,由于此时html已经渲染出来了,所以可以操作dom节点。
Route和Router区别
router是VueRouter的一个对象- 通过
Vue.use(VueRouter)和VueRouter构造函数得到的一个router的实例对象 - 这个对象是:全局对象,包含了所有的路由
- 通过
route是:跳转的路由对象- 每一个路由都会有一个
route对象,是局部对象 - 可以获取对应的
name\path\params\query等
- 每一个路由都会有一个