首先来看看使用v-if时vue是如何执行的
<div v-if="true">hello</div>
👆这行代码转成vue执行代码为
function render() {
with(this) {
return (true) ? _c('div', [_v("hellow")]) : _e()
}
}
可以看到vue使用的是render函数,创建了一个dom节点,并且用一个三元表达式判断,当为true时创建虚拟dom 再转成真实的div节点,当为false时创建一个注释节点
再看看使用v-show时是如何执行的
<div v-show="true">hellow</div>
👆这行代码转成vue执行代码为
function render() {
with(this) {
return _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: (true),
expression: "true"
}]
}, [_v("hellow")])
}
}
<div v-show="false">hellow</div>
function render() {
with(this) {
return _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: (false),
expression: "false\n"
}]
}, [_v("hellow")])
}
}
可以看到当使用v-show时创建一个节点,之后只是expression的值不同,再去vue源码中看看
bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
vnode = locateNode(vnode)
const transition = vnode.data && vnode.data.transition
const originalDisplay = el.__vOriginalDisplay =
el.style.display === 'none' ? '' : el.style.display
if (value && transition) {
vnode.data.show = true
enter(vnode, () => {
el.style.display = originalDisplay
})
} else {
el.style.display = value ? originalDisplay : 'none'
}
}
可以看到v-show底层是通过传入的value值,进行一个三元表达式判断,display的属性值。
所以使用v-show每次只是切换display的属性,不会频繁创建dom节点,但是,v-if每次改变都会频繁生产虚拟dom真实dom和注释节点,非常消耗性能。
但是当你只需要判断一次是否显示是可以使用v-if,可以优化结构。
推荐一个看vue执行代码的网站 Vue Template Explorer