Vue学习—深入剖析相关指令

tech2025-06-04  11

相关指令

一、v-相关指令1.v-pre2.cloak3.v-once4.v-text5.v-html 二、条件渲染1.v-if2.v-else3.v-else-if4.v-show5.v-if VS v-show

一、v-相关指令

1.v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

vue的渲染数据的规则 将dom里<div id="app">{{ msg }}</div>的内部编译成<div id="app">天气真好!</div>替换原来的<div id="app">{{ msg }}</div>

<div id="app" v-pre> {{ msg }} <span>{{ msg }}</span> </div> <script> const vm = new Vue({ el: '#app', data: { msg: '天气真好!' } }) </script>

<div id="app"> {{ str }} <span v-pre>{{ str }}</span> </div>

2.cloak

这个指令保持在元素上直到关联实例结束编译(1.中讲述的vue渲染数据的规则)可以解决闪烁的问题(当某些原因,vue还未加载完成,页面会显示出‘{{ *** }}’等,加载完成后会闪烁一下渲染我们设置的数据)和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕 <style> [v-cloak]{ display: none; } </style> <div id="app" v-cloak>{{ msg }}</div>//加载出vue.js前不会显示{{ msg }},直到加载完成后直接渲染成数据 <script> const vm = new Vue({ el: '#app', data: { msg: '天气真好!' } }) </script>

3.v-once

只渲染元素一次。随后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能 <div id="app" v-once>{{ msg }} <span>{{ msg }}</span> </div> <script> const vm = new Vue({ el: '#app', data: { msg: '天气真好!' } }) </script>

页面不会响应,div#app和子元素span都不会重新渲染 如果:

<div id="app">{{ msg }} <span v-once>{{ msg }}</span> </div>

4.v-text

更新元素的 textContent <div id="app"> -+{{ msg }}+- //插值表达式-+不会被替换渲染 <span v-text='msg'>-+{{ msg }}+-</span> //v-text元素内所有文本被替换 </div> <script> const vm = new Vue({ el: '#app', data: { msg: '天气真好!' } }); </script> v-text 优先级高于 {{ 插值表达式 }}

textContent VS innerText

设置文本替换时,两者都会把指定节点下的所有子节点也一并替换掉。textContent 会获取所有元素的内容,包括 <script>和 <style>元素,然而 innerText 不会。 <div id="demo"> ---+++ <script> const a = 1; </script> <style> #demo{border: 1px solid red} </style> </div> <script> console.log(demo.textContent); console.log(demo.innerText); </script>

innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,而textContent会。由于 innerText 受 CSS 样式的影响,它会触发重排(reflow),但textContent 不会。 <div id="demo"> <span style="display: none;"> span元素 </span> </div> <script> console.log(demo.textContent); console.log(demo.innerText); </script>

innerText 不是标准制定出来的 api,而是IE引入的,所以对IE支持更友好。textContent虽然作为标准方法但是只支持IE8+以上的浏览器,在最新的浏览器中,两个都可以使用。综上,Vue这里使用textContent是从性能的角度考虑的。

5.v-html

更新元素的innerHTML注意:内容按普通 HTML 插入,不会作为 Vue 模板进行编译在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。 <input type="text" /> <button>点击</button><!-- 放在vue模板外面,防止渲染数据时被替换 --> <div id="app"> <div v-html="msg"></div> </div> <script> const vm = new Vue({ el: '#app', data: { msg: '今天阳光明媚!' } }); const oInput = document.getElementsByTagName('input')[0]; const oButton = document.getElementsByTagName('button')[0]; oButton.onclick = function () { vm.msg = oInput.value; }; </script>

如果被XSS注入攻击:

二、条件渲染

1.v-if

用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true 值的时候被渲染。 <div id="app"> <span v-if='A'>今天天气怎么样?</span> <span v-else-if='B'>阳光明媚!</span> <span v-else-if='C'>鬼的,风雨大作!</span> <span v-else='D'>你们怕是中邪了!</span> </div> <script> const vm = new Vue({ el: '#app', data: { msg: '天气真好!', A: undefined, B: null, C: '', D: [] } }) </script>

切换多个元素:因为 v-if 是一个指令,所以必须将它添加到一个元素上,但是如果想切换多个元素呢?此时可以把一个 <template>元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template>元素 <template v-if="ok">//其它元素包裹会使页面多一个元素,使用template则不会 <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>

2.v-else

为 v-if 或者 v-else-if 添加“else 块”。注意:前一兄弟元素必须有 v-if 或 v-else-if <div id="app"> <span v-if='A'>今天天气怎么样?</span>//A:null,为真则显示该文本值 <span>阳光明媚!</span> <span v-else='C'>鬼的,风雨大作!</span> </div>

3.v-else-if

表示 v-if 的 “else if 块”。可以链式调用。注意:前一兄弟元素必须有 v-if 或 v-else-if <div id="app"> <span v-if='A'>今天天气怎么样?</span>//A:null,为真则显示该文本值 <span>阳光明媚!</span> <span v-else-if='C'>鬼的,风雨大作!</span> </div>

4.v-show

根据表达式之真假值,切换元素的 display CSS 属性。 <div id="app"> <span v-show='B'>你能看见我吗?</span> </div>

5.v-if VS v-show

v-if 是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。v-show则不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 <div id="app"> <span v-if='A'>Anull</span> <span v-show='B'>你能看见我吗?</span> </div>

v-if 有更高的切换开销,v-show 有更高的初始渲染开销,如果需要非常频繁地切换,则使用 v-show 较好,如果在运行时条件很少改变,则使用 v-if 较好v-show不支持<template>元素,因为它是通过改变元素的stylev-show不支持v-else/v-else-if
最新回复(0)