0


vue面试题7

文章目录


说说vue中,key的原理

Key是什么

key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点

我们在使用v-for时,需要给单元加上key
●如果不用key,Vue会采用就地复地原则:最小化element的移动,并且会尝试尽最大程度在同适当的地方对相同类型的element,做patch或者reuse。
●如果使用了key,Vue会根据keys的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed

用+new Date()生成的时间戳作为key,手动强制触发重新渲染
当拥有新值的rerender作为key时,拥有了新key的Comp出现了,那么旧key Comp会被移除,新key Comp触发渲染

设置key与不设置key区别

创建一个实例,2秒后往items数组插入数据

<body><div id="demo"><p v-for="item in items":key="item">{{item}}</p></div><script src="../../dist/vue.js"></script><script>// 创建实例const app =newVue({
      el:'#demo',
      data:{ items:['a','b','c','d','e']},
      mounted (){setTimeout(()=>{this.items.splice(2,0,'f')// },2000);},});</script></body>

在不使用key的情况,vue会进行这样的操作:
在这里插入图片描述

分析下整体流程:
●比较A,A,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较B,B,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较C,F,相同类型的节点,进行patch,数据不同,发生dom操作
●比较D,C,相同类型的节点,进行patch,数据不同,发生dom操作
●比较E,D,相同类型的节点,进行patch,数据不同,发生dom操作
●循环结束,将E插入到DOM中

一共发生了3次更新,1次插入操作
在使用key的情况:vue会进行这样的操作:
●比较A,A,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较B,B,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较C,F,不相同类型的节点
●比较E、E,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较D、D,相同类型的节点,进行patch,但数据相同,不发生dom操作
●比较C、C,相同类型的节点,进行patch,但数据相同,不发生dom操作
●循环结束,将F插入到C之前

一共发生了0次更新,1次插入操作
通过上面两个小例子,可见设置key能够大大减少对页面的DOM操作,提高了diff效率

设置key值一定能提高diff效率吗?

其实不然,文档中也明确表示
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升

说说你对slot的理解? slot使用场景有哪些?

slot是什么

在HTML中 slot 元素 ,作为 Web Components 技术套件的一部分,是Web组件内的一个占位符
该占位符可以在后期使用自己的标记语言填充

Slot 名插槽,我们可以理解为solt在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填坑(替换组件模板中slot位置),作为承载分发内容的出口

使用场景

通过插槽可以让用户可以拓展组件,去更好地复用组件和对其做定制化处理

如果父组件在使用到一个复用组件的时候,获取这个组件在不同的地方有少量的更改,如果去重写组件是一件不明智的事情

通过slot插槽向组件内部指定位置传递内容,完成这个复用组件在不同场景的应用

比如布局组件、表格列、下拉选、弹框显示内容等

分类

默认插槽
子组件用标签来确定渲染的位置,标签里面可以放DOM结构,当父组件使用的时候没有往插槽传入内容,标签内DOM结构就会显示在页面
父组件在使用的时候,直接在子组件的标签内写入内容即可

//子组件Child.vue<template><slot><p>插槽后备的内容</p></slot></template>//父组件<Child><div>默认插槽</div></Child>

具名插槽
子组件用name属性来表示插槽的名字,不传为默认插槽
父组件中在使用时在默认插槽的基础上加上slot属性,值为子组件插槽name属性值

//子组件Child.vue<template><slot>插槽后备的内容</slot><slot name="content">插槽后备的内容</slot></template>//父组件<child><template v-slot:default>具名插槽</template><!-- 具名插槽⽤插槽名做参数 --><template v-slot:content>内容...</template></child>

作用域插槽
子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件v-slot接受的对象上
父组件中在使用时通过v-slot:(简写:#)获取子组件的信息,在内容中使用

//子组件Child.vue<template><slot name="footer" testProps="子组件的值"><h3>没传footer插槽</h3></slot></template>//父组件<child><!-- 把v-slot的值指定为作⽤域上下⽂对象 --><template v-slot:default="slotProps">
      来⾃⼦组件数据:{{slotProps.testProps}}</template><template #default="slotProps">
      来⾃⼦组件数据:{{slotProps.testProps}}</template></child>

小结:
v-slot属性只能在上使用,但在只有默认插槽时可以在组件标签上使用
默认插槽名为default,可以省略default直接写v-slot
缩写为#时不能不写参数,写成#default
可以通过解构获取v-slot={user},还可以重命名v-slot=“{user: newName}“和定义默认值v-slot=”{user = ‘默认值’}”


本文转载自: https://blog.csdn.net/xiaolu567/article/details/126131913
版权归原作者 小卢要刷力扣题 所有, 如有侵权,请联系我们删除。

“vue面试题7”的评论:

还没有评论