VUE面试题系列03(带数字,带序号),前端面试题
24、为何vue采用异步渲染?
1、vue采用异步队列渲染是为了提高性能,在异步队里会去掉重复的无效的渲染。
当vue中的数据发生改变后,vue框架会把该数据引起的dom更新放入异步队列( 缓冲在同一事件循环中发生的所有数据变更 ),进行排队。 如果同一个 watcher 被多次触发,只会被推入到队列中一次 。 这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的 。
2、如果不采用 异步渲染,而是在数据发生改变后,立即更新dom,如果有重复无效的渲染,那么,就会造成性能的浪费。
25、nextTick实现原理?
1)、为什么用Vue.nextTick()
首先,JS是单线程的,那么,它如何处理异步操作。
-
所有同步任务都在主线程上执行,形成一个执行栈。
-
主线程之外,会存在一个任务队列,只要异步任务有了结果,就在任务队列中放置一个事件(所以,也叫事件队列),进行排队(处于等待状态)。
-
当执行栈中的所有同步任务执行完后,就会读取任务队列(事件队列)中的任务(事件)。即:任务队列中的任务就结束了等待状态,进入执行栈。
-
主线程不断重复第三步。直到任务队列和执行栈里的代码执行完毕。
其次,vue更新DOM的思路。使用的就是异步更新队列,所以,就使用了事件循环。目的是提高性能,避免无效的重复的DOM更新。即:vue中更新数据后,并不会立即更新DOM,而是把数据引起的DOM更新放入到异步更新队列里。等待下次事件循环(tick),并在两个tick之间进行UI渲染。这样程序员就不能在更改数据后,立即获取更新后的DOM,也不知道什么时候DOM能够更新。基于此,vue提供了nextTick函数。让程序员操作更新后DOM的代码放入到nextTick的回调函数里。由nextTick内部,在更新完DOM后,调用回调函数。
示例代码:
this.msg = "hello"
this.$nextTick(()=>{
操作更新后DOM的代码。
});
2)、什么是Vue.nextTick()
Vue.nextTick的代码思路示意
function nextTick(cb){
//DOM 更新
cb();
}
那么,vue是如何知道DOM更新了?
-
MutationObserver:这是HTML5新增的API。用于监视DOM变动的接口,它可以监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等
-
另外,考虑到,微任务比宏任务耗时少,浏览器的兼容性。所以,vue中延迟调用优先级如下: Promise > MutationObserver > setImmediate > setTimeout
3)、应用场景:
在Vue生命周期的created()钩子函数里,如果要进行DOM操作,一定要把DOM操作放在Vue.nextTick()的回调函数中。
在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作应该放在Vue.nextTick()的回调函数中。
26、何时需要使用beforeDestroy?
总体来说,需要清除的是:当前组件不会自动销毁的数据(不属于当前组件的数据),并且该数据只是在当前组件里使用。
1)、清除定时器(定时器是window对象的,不主动清除,是不会清除的)
2)、$on方法,那需要在组件销毁前解绑。($on虽然属于Vue的实例方法,但是,这个实例很有可能不是当前vue组件(如:事件总线中的用法))
3)、解除事件的绑定 scroll mousemove (这些事件是绑定在window对象或者document对象上的)
27、Vue中v-html会导致哪些问题
1)、可能会导致XSS攻击。因为V-html更新的是元素的 innerHTML 。内容按普通 HTML 插入, 不会作为 Vue 模板进行编译 。
2)、在单文件组件里,scoped 的样式不会应用在 v-html 内部。因为那部分 HTML 没有被 Vue 的模板编译器处理。怎么解决呢?如果你希望针对 v-html 的内容设置带······作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局style元素手动设置类似 BEM 的作用域策略。
3)、后台返回的html片段,以及css样式和js,但是返回的js是不执行的,因为浏览器在渲染的时候并没有将js渲染,这时要在$nextTick中动态创建script标签并插入
28、为什么v-for与v-if不能连用
应该说,建议不要连用,或者说,在循环时,通过if只能拿到少部分数据时,建议不要使用。
原因: v-for比v-if优先级高,如果遍历的数组元素个数比较多,但是满足v-if条件比较少的情况下。会浪费性能。而且,每次刷新页面时,都会执行这样性能不高的代码。
解决:可以在computed里循环数组,通过filter的方式,过滤出需要的数据。而computed是有缓存的,这样可以节约内存
如下示例:
computed:{
isCompleteTask:function(){
return this.todos.filter(item=>item.isComplete);
}
}
29、如何自定义v-model
答: 使用vue组件中的选项model。
首先,官方组件里可以使用v-model。而且,vue框架针对官方组件(文本框,单选钮,复选框,下拉框)都有绑定的属性和事件。如:文本框所绑定的属性是value,绑定的事件是input。
那么,自定义组件里,如何使用v-model指令。就需要在vue组件里增加model选项。
如下示例:
Vue.component('my-checkbox', {
props:['ccc','ddd'],//声明了自定义组件的属性。
model: {
prop: 'ccc', //表示v-model所绑定的属性是 ccc
event: 'change'//表示v-model所绑定的事件是是 change
},
……………………
}