vue 区分题
v-if 和 v-else
- v-if值为false时,在该位置创建一个注释节点,用来标识元素在页面中的位置。在值发生改变的时候,通过diff,新旧组件进行patch,创建DOM节点,从而动态显示隐藏。
- v-show值为false时,通过设置元素的样式,
display:none
来控制元素是否展示。
- | v-if | v-show |
---|---|---|
本质 | 操作DOM元素进行切换显示 | 设置css样式进行切换显示 |
首次渲染开销 | 较低 | 较高 |
切换开销 | 较高 | 较低 |
适用场合 | 不频繁切换 | 频繁切换 |
对生命周期的影响 | 会影响 | 不会影响 |
- 当v-if指令附属于普通元素时,v-if指令状态变化会使得父组件的dom发生变化,父组件将会更新视图,所以会触发父组件的
beforeUpdate
和updated
钩子函数。 - 当v-if指令令附属于组件时,v-if指令状态变化对父组件的影响和上一条一致,但是对于本身组件的生命周期的影响是不一样的。
- v-if从false切换到true时,会触发
beforeCreate
,created
,beforeMount
,mounted
钩子。 - v-if从true切换到false时,会触发
beforeDestroy
和destroyed
钩子函数。
- v-if从false切换到true时,会触发
v-if 与 v-for优先级,vue2如何优化得到更好的性能?
- vue2,在一个元素上同时使用
v-if
和v-for
时,v-for
优先作用 - vue3
v-if
优先作用
尽量避免在同一个元素上面同时使用v-if和v-for,因为每次渲染都会先循环完整个列表再进行条件判断,带来性能方面的浪费。
①如果要遍历的数组很大,而真正要展示的数据很少时
② 哪怕我们只渲染出一小部分用户的元素,也得在每次重渲染的时候遍历整个列表,不论活跃用户是否发生了变化。
https://juejin.cn/post/6844904183619944462
待补充:如何理解Vue中的模板编译原理,补充后进行笔记修改
vue2的优化方案
1.可以用计算属性替换
2.外层嵌套template
标签,页面渲染不生成DOM节点,在template
标签上使用v-if
,在内层使用v-for
案例
假设有一个 todoList:
const todoList = [
{
id: 0,
task: '吃饭',
done: true,
},
{
id: 1,
task: '睡觉',
done: false,
},
{
id: 2,
task: '洗澡',
done: true,
},
// ...,
];
vue2的写法,v-for
优先级高于v-if
所以可以用作于同一个元素
<ul>
<!-- vue2中,v-for优先级高于v-if -->
<li v-for="item in todoList" v-if="!item.done" :class="{todo: !item.done}" :key="item.id">
<span>{{item.task}}</span>
</li>
</ul>
查看生成的渲染函数,就可以知道执行的顺序。
渲染函数
render
中的_l 方法,它是列表渲染的函数,就是将来会循环输出所有 listdata,然后每循环一次执行的具体的函数会是后面的这个工厂函数。在这个工厂函数里面,return 才是最终的结果。
vue3中,v-if
优先级高于v-for
,所以像vue2一样用作于同一个元素。在外面套一层用作于循环。
<ul>
<template v-for="item in list" :key="item.id">
<li v-if="!item.done" :class="{todo: !item.done}">
<span>{{item.task}}</span>
</li>
</template>
</ul>
参考文章
作者:攻城狮_老李
链接:https://juejin.cn/post/6881581395068747790
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
scoped
一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,这样就可以使得组件之间的样式不互相污染。如果一个项目中的所有style标签全部加上了scoped,相当于实现了组件的私有化,样式的模块化。
原理
scope的本质是分别给 HTML 标签和 CSS 选择器添加 data-v-xxx
,来达到样式隔离的效果。
样式穿透问题
使用 scoped
后,父组件的样式将不会渗透到子组件中。
但是父组件可以修改子组件根节点样式。
解决办法
vue2 >>>
:>>> 会被编译成当前父组件的date-v-xxx
<style>
.a >>> .b >>> span{
color:red;
}
</style>
// 渲染结果,当有多个时只有最左边的>>>生效
.a[data-v-xxx] .b >>> span{
color:red;
}
vue3 ::v-deep(.class)
面试题
- vue样式穿透scoped
- scoped的原理
- vue中的scoped style是如何实现作用域样式以及为什么vue不使用css module来实现作用域?
- css样式隔离了解吗?有哪几种方法?