网站首页 > 技术文章 正文
在Vue中,有两种方法可以有条件地渲染部分应用程序:v-if和v-show。你可能会问:“为什么需要两种方式来控制元素的隐藏和显示,明明他们的功能和使用方式都一样?问的好,这也是我们在学习Vue时遇到的一个问题。在本教程中,我们将了解什么是两种显示内容的不同方式和工作原理。话不多说,直接进入主题吧。
一、官方介绍
v-if
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if 也是惰性的,如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show
v-show是不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
二、不同点
控制手段
v-if是通过控制dom节点是否存在来控制页面是否显示。
v-show则是节点已经存在,通过dom节点的display样式来控制显隐。display none为不显示 block为显示。
编译过程
v-if是真正的条件渲染,有局部编译和渲染的过程,它会确保切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-show的元素总是会被渲染,它只是简单的基于CSS进行切换。
编译条件
v-if 是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
性能消耗
v-if 有更高的切换消耗。
v-show 有更高的初始渲染消耗。
应用场景
基于以上区别,我们可以得出结论:元素进入页面后显示或者隐藏状态不会被修改,建议使用v-if。元素需要非常频繁地切换,则使用 v-show 较好。
三、原理分析
下面我们通过Vue2的源码,来看看v-if和v-show的原理。
1. v-if原理
在模板编译的parse阶段,会使用 processIfConditions 函数处理条件渲染指令的内容:
function genElement (el, state) {
if (el.if && !el.ifProcessed) {
return genIf(el, state)
} else {
let code
if (el.component) {
code = genComponent(el.component, el, state)
} else {
const data = el.plain ? undefined : genData(el, state)
const children = el.inlineTemplate ? null : genChildren(el, state, true)
code = `_c('${el.tag}'${
data ? `,${data}` : '' // data
}${
children ? `,${children}` : '' // children
})`
}
return code
}
}
function genIf (
el,
state,
altGen,
altEmpty
) {
el.ifProcessed = true;
return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
}
function genIfConditions (
conditions,
state,
altGen,
altEmpty
) {
if (!conditions.length) {
return altEmpty || '_e()'
}
var condition = conditions.shift();
if (condition.exp) {
return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty)))
} else {
return ("" + (genTernaryExp(condition.block)))
}
function genTernaryExp (el) {
return altGen
? altGen(el, state)
: el.once
? genOnce(el, state)
: genElement(el, state)
}
}
从代码可以看出,v-if指令特性是一个三元表达式。带有v-if指令的模版会进行判断,如果值为true,则会生成dom树。值为false,会生成一个注释节点占位。
2. v-show原理
v-show 的本质是 Vue 中内置的一个自定义指令,借助于 v-show 我们可以控制目标节点 style 中的 display 属性值。
我们看一下v-show 内置自定义指令源码。
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'
}
},
update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) {
if (value === oldValue) return
vnode = locateNode(vnode)
const transition = vnode.data && vnode.data.transition
if (transition) {
vnode.data.show = true
if (value) {
enter(vnode, () => {
el.style.display = el.__vOriginalDisplay
})
} else {
leave(vnode, () => {
el.style.display = 'none'
})
}
} else {
el.style.display = value ? el.__vOriginalDisplay : 'none'
}
},
unbind (
el: any,
binding: VNodeDirective,
vnode: VNodeWithData,
oldVnode: VNodeWithData,
isDestroy: boolean
) {
if (!isDestroy) {
el.style.display = el.__vOriginalDisplay
}
}
通过上述代码可以得知,v-show 指令核心代码就是:el.style.display = value ? el.__vOriginalDisplay : 'none'。通过控制元素的display属性来实现元素的显示隐藏。
- 上一篇: 阿勒泰机场地面服务部开展 “值机前端”系统培训
- 下一篇: 前端开发技术面试——情景版
猜你喜欢
- 2024-12-14 阿勒泰机场地面服务部开展 “值机前端”系统培训
- 2024-12-14 育知前端培训四期毕业20天就业率80%, 平均薪资12491
- 2024-12-14 Web前端培训:Angular的性能优化技术
- 2024-12-14 民办学生加薪无望参加达内Web前端培训 获得月薪10k告别“月光族”
- 2024-12-14 北京前端培训 育知H5-1602毕业30天就业率100% 最高薪资22K
- 2024-12-14 前端程序猿:你离成为男神还差一个百度传课
- 2024-12-14 金鸡湖IT培训怎么学?前端面试问什么?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)