文章目录
前言
Wisdom is a gem, if use modest edge, will be more brilliant.
智慧是宝石,如果用谦虚镶边,就会更加灿烂夺目。
------ 马克西姆·高尔基
一、Vue双向数据绑定的原理
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
当把一个普通 Javascript 对象传给 Vue实例来作为它的 data选项时,Vue将遍历它的属性,用Object.defineProperty()将它们转为getter/setter。用户看不到getter/setter,但是在内部它们让Vue追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
二、key的作用
key是为Vue中的vnode(虚拟节点)标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速。
diff算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的key与旧节点进行比对,然后超出差异。
简单来说,主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们。
三、data,computed和watch的作用,和区别
data:
data是一个对象,和数据相关的属性一般都放在data中。
data对象内部所有的内容都是成对的,也就是键值对,我们叫属性比如site、url、alexa、msg这样的属性是我们自己定义的。
Vue内部把data中的属性使用数据代理的方式直接绑定到了vm对象上。
Vue 会递归的将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。
computed:
computed是计算属性,也就是计算值,它更多用于计算值的场景。
computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算。
computed适用于计算比较消耗性能的计算场景。
watch:
更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作。
无缓存性,页面重新渲染时值不变化也会执行。
四、vue生命周期
什么是Vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
Vue生命周期的作用是什么?
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
Vue生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子。
DOM渲染在哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了
每个生命周期适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发。
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用。
mounted : 挂载元素,获取到DOM节点。
updated : 如果对数据统一处理,在这里写上相应函数。
beforeDestroy : 可以做一个确认停止事件的确认框。
nextTick : 更新数据后立即操作dom。
beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。
created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有
beforeMount阶段:vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点。
mounted阶段:vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点。
beforeUpdate阶段:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器。
updated阶段:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环。
beforeDestroy阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件。
destroyed阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁。
五、v-show与v-if区别
实现本质方法区别
v-show本质就是标签display设置为none,控制隐藏;
v-if是动态的向DOM树内添加或者删除DOM元素。
编译的区别
v-show其实就是在控制css;
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件。
编译的条件
v-show都会编译,初始值为false,只是将display设为none,但它也编译了;
v-if初始值为false,就不会编译了。
性能
v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
总的来说:
v-show是css切换,v-if是完整的销毁和重新创建。
使用 频繁切换时用v-show,运行时较少改变时用v-if。
v-if是条件渲染,当false的时候不会渲染。