
v-if有关的面试题目:
- Vue中的v-show和v-if怎么理解?
- 为什么Vue中的v-if和v-for不建议一起用?
一、 Vue中的v-show鱼v-if怎么理解?
0x00:相同点:
作用效果相同的,能够控制元素在页面是否显示
0x01: 区别:
控制手段:
v-show:通过css-display:none, dom元素依旧存在
v-if: 将dom元素添加或者删除
编译过程:
v-show: 简单的基于css切换
v-if:切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
编译条件:
v-if: 是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染
v-show: 由false变为true的时候不会触发组件的生命周期
v-if: 由false变为true的时候,组件创建生命周期,由true变为false的时候触发组件销魂周期
性能消耗:
v-if有更高的切换消耗;
v-show有更高的初始渲染消耗;
概括:
v-if:控制dom是否存在[创建和销魂]来控制隐藏,所以在切换的时候消耗资源
v-show: 通过css样式控制是否显示,元素一直存在的,初始化的时候创建。
0x02: 原理:
1)v-show 源码:控制style.display的css样式
export const vShow: ObjectDirective<VShowElement> = {
beforeMount(el, { value }, { transition }) {
el._vod = el.style.display === 'none' ? '' : el.style.display
if (transition && value) {
transition.beforeEnter(el)
} else {
setDisplay(el, value)
}
},
mounted(el, { value }, { transition }) {
if (transition && value) {
transition.enter(el)
}
},
updated(el, { value, oldValue }, { transition }) {
if (!value === !oldValue) return
if (transition) {
if (value) {
transition.beforeEnter(el)
setDisplay(el, true)
transition.enter(el)
} else {
transition.leave(el, () => {
setDisplay(el, false)
})
}
} else {
setDisplay(el, value)
}
},
beforeUnmount(el, { value }) {
setDisplay(el, value)
}
}
2)v-if源码:返回一个node节点,render函数通过表达式的值来决定是否生成DOM
export const transformIf = createStructuralDirectiveTransform(
/^(if|else|else-if)$/,
(node, dir, context) => {
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
// #1587: We need to dynamically increment the key based on the current
// node's sibling nodes, since chained v-if/else branches are
// rendered at the same depth
const siblings = context.parent!.children
let i = siblings.indexOf(ifNode)
let key = 0
while (i-- >= 0) {
const sibling = siblings[i]
if (sibling && sibling.type === NodeTypes.IF) {
key += sibling.branches.length
}
}
// Exit callback. Complete the codegenNode when all children have been
// transformed.
return () => {
if (isRoot) {
ifNode.codegenNode = createCodegenNodeForBranch(
branch,
key,
context
) as IfConditionalExpression
} else {
// attach this branch's codegen node to the v-if root.
const parentCondition = getParentCondition(ifNode.codegenNode!)
parentCondition.alternate = createCodegenNodeForBranch(
branch,
key + ifNode.branches.length - 1,
context
)
}
}
})
}
)
0x03: 使用场景
v-if:运行条件很少改变
v-show:运行条件频繁改变
二、 为什么Vue中的v-if和v-for不建议一起用?
0x00: 意义
v-if: 条件性渲染
v-for: 基于一个数组来渲染一个列表(建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化)
0x01: 优先级
v2: v-if < v-for
v3: v-if > v-for
0x02: 注意事项
v-if/v-for 不要放在同一个元素伤
1)v-if/v-for 在v2和v3上的优先级是相反的,在语义上难以区分
2)尽量是v-if的元素包括v-for, 这样先拿判断在确定要不要渲染循环,如果v-for在v-if外面渲染列表,每个循环都要判断
3)如果v-if出现在v-for内部,可通过计算属性来过滤那些不需要的选项
计算属性具有缓存的特性
computed: {
items: function() {
return this.list.filter(function (item) {
return item.isShow
})
}
}
概括:
1)如果v-if和v-for同时存在,应该使用v-if包括v-for
2)如果v-for内部确实需要包括v-if,里面的判断使用计算属性提高性。
网友评论