vue面试题7:key的原理和slot的理解

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

文章目录

说说vue中,key的原理

Key是什么

设置key与不设置key区别

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

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

slot是什么

使用场景

分类

说说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 = new Vue({

     el: '#demo',

     data: { items: ['a', 'b', 'c', 'd', 'e'] },

     mounted () {

       setTimeout(() => {

         this.items.splice(2, 0, 'f')  //

      }, 2000);

    },

  });

 </script>

</body>


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

在不使用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>

1

2

3

4

5

6

7

8

9

10

11

具名插槽

子组件用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>



1

2

3

4

5

6

7

8

9

10

11

12

13

14

作用域插槽

子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件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>


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

小结:

v-slot属性只能在上使用,但在只有默认插槽时可以在组件标签上使用

默认插槽名为default,可以省略default直接写v-slot

缩写为#时不能不写参数,写成#default

可以通过解构获取v-slot={user},还可以重命名v-slot=“{user: newName}“和定义默认值v-slot=”{user = ‘默认值’}”


目录
相关文章
|
23天前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
22天前
|
安全 Java 容器
【Java集合类面试二十七】、谈谈CopyOnWriteArrayList的原理
CopyOnWriteArrayList是一种线程安全的ArrayList,通过在写操作时复制新数组来保证线程安全,适用于读多写少的场景,但可能因内存占用和无法保证实时性而有性能问题。
|
7天前
|
消息中间件 Java 编译器
面试官:说说Lambda表达式底层原理?
面试官:说说Lambda表达式底层原理?
15 2
面试官:说说Lambda表达式底层原理?
|
15天前
|
消息中间件 算法 Java
面试官:Kafka中的key有什么用?
面试官:Kafka中的key有什么用?
28 3
面试官:Kafka中的key有什么用?
|
2天前
|
缓存 JavaScript 前端开发
|
23天前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
23天前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
|
10天前
|
缓存 JavaScript 容器
vue动态组件化原理
【9月更文挑战第2天】vue动态组件化原理
26 2
|
14天前
|
缓存 JavaScript 前端开发
[译] Vue.js 内部原理浅析
[译] Vue.js 内部原理浅析
|
22天前
|
Java
【Java集合类面试二十一】、请介绍TreeMap的底层原理
TreeMap基于红黑树实现,能够根据键的自然顺序或提供的Comparator排序,其基本操作的时间复杂度为O(log N)。