Vue 2.0学习笔记:v-text和v-html

Vue使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。

在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,在应用状态改变时,Vue能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上。

如果你熟悉虚拟DOM并且偏爱JavaScript的原始力量,你也可以不用模板,直接写渲染函数render,使用可选的JSX语法。

插值

大家在前面的教程中可能看到了我们使用{{}}的形式来渲染文本。这种形式就是Mustache语法。

<h1>Name: {{ name }}</h1>

Mustache标签将会被替代为对应数据对象上name属性的值,无论何时,绑定的数据对象上name属性发生了改变,插值片的内容都会更新。比如:

v-text and v-html

通过使用v-once指令(我们后面会学习这个指令),你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心,这会影响到该节点上所有的数据绑定:

<h1 v-once>Name: {{ name }} (绑定v-once不会改变name)</h1>

v-text and v-html

使用Mustache语法(也就是双大括号{{}})可以很方便的让我们将数据源对象的属性渲染到Vue的DOM元素中。但其也有一定的弊端,比如让你的网速慢,或者数据加载失败的时候会在浏览器中直接渲染插值,比如{{name}}。或者说,当你的JavaScript报错,或者你的用户禁用页面所有JavaScript时,也会有类似现象:

v-text and v-html

在这种情况之下,对用户的体验并不好,因为我们的用户并不知道{{xxx}}表示的是什么?不过,值得庆幸的是,在Vue中,除了使用{{}}这样的插值语法渲染数据之外,还提供了两个相关的指令,也就是我们今天需要学习的v-textv-html。在学习这两个指令之前,咱位回忆一下JavaScript中相关的几个知识。

JavaScript相关知识点

在JavaScript中有textContentinnerHTMLinnerTextouterTextouterHTMLnodeValue。这些属性都可以用来获取某个元素的内容,也可以将内容或标签插入到某个元素中。看上去和渲染内容有点相关。

简单的理解一下这几个属性:

  • innerHTML:获取从对象的起始位置到终止位置的全部内容,包括HTML标签。当内容都是文本的时候,可以把这个属性当做textContent属性来用
  • innerText:获取从对象的起始位置到终止位置的内容,但它不会包括HTML标签
  • outerHTML:除了包含innerHTML的全部内容外,还会包含对象标签本身
  • textContent:设置或返回指定节点的文本内容,以及它的所有后代。有时候,此属性可用于取代nodeValue属性,但请记住此属性同时会返回所有子节点的文本。得到的结果跟innerText的结果是一样的。如果是设置,则原本的子元素会被同时替换掉
  • nodeValue:和textContent很像,都是用来获取某个元素中的内容,不过nodeValue并不能直接操作某个DOM元素,它只能用来获取某段文本节点中的内容
  • outerText:和outerHTML有同样的功能,它们都包括自身,不同的是outerText获取的是元素内容,而outerHTML获取到的内容包括元素

简单点来看看他们之间对元素操作的结果:

v-text and v-html

v-text

在JavaScript中可以使用innerText或者textContent来操作元素中的纯文本。在Vue中,如前面的示例所展示的一样,使用{{}}Mustache语法操作元素中的纯文本。不过在Vue中,我们还可以使用v-text起到同等的作用。

先来看一个例子:

<div id="app">
    <h1>用户名:{{ name }}</h1>
    <h1 v-text="'用户名:' + name"></h1>
</div>

效果如下:

v-text and v-html

从效果图上可以看出来,v-text{{}}起到的效果是一样的。同样的,动态修改对象name的值时,渲染的结果也会有对应的变化:

v-text and v-html

从上面的示例,我们可以看出v-text=""指令中的双引号并不是代表字符串,而是Vue自定义的划定界限的符号。如果我们里面输出字符串,就需要在里面再添加一对单引号。比如<h1 v-text="'用户名:' + name"></h1>。而且,在Vue中要想输出字符串,必须添加单引号,否则会报错

另外{{}}代表的就是"",所以在v-text=""中,我们在内容里面就不需要再写{{}}了,直接写数据属性就行了。

v-for一节中,我们看到{{}}方法可以采用对象的形式传递多个数据。其实在v-text中,也具备同等的功能。比如下面这个示例:

<!-- Template -->
<div id="app">
    <h2>{{}}方法:</h2>
    <ul>
        <li v-for="(value, key) in person">{{ key }}: {{ value }}</li>
    </ul>
    <hr>
    <h2>v-text方法:</h2>
    <ul>
        <li v-for="(value, key) in person" v-text="key + ':' + value"></li>            
    </ul>
</div>

// JavaScript
var app = new Vue({
    el: '#app',

    data: {
        person: {
            name: '大漠',
            set: '男',
            age: 30
        }
    }
})

得到的效果是一致的:

v-text and v-html

Vue中的v-text等同于文本插值{{}}方法,也类似于JavaScript中的textContent

v-html

前面提到过,在JavaScript中使用innerHTML获取一个元素的HTML标签(包括标签里的内容),也可以用它设置来重置HTML标签(包括标签里的内容),配合JavaScript的一些操作DOM的方法:

let h1Element = document.createElement('h1')
h1Element.classList.add('title')
h1Element.textContent = '把大漠塞进去'
document.getElementById('app').appendChild(h1Element)

创建了一个带有title类名的h1元素插入到#app元素中,相当于把下面的代码插进去了:

<h1 class=​"title">​把大漠塞进去​</h1>​

结果可以看到的效果如下:

v-text and v-html

如果你对DOM的操作不太熟悉,建议花点时间阅读下面几篇文章:

在Vue中,我们可以使用v-html来操作元素中的HTML标签,事情会变得容易得多。比如:

<!-- Template -->
<div v-html="cat"></div>

// JavaScript
var app = new Vue({
    el: '#app',

    data: {
        cat: "<img src='//www.w3cplus.com/sites/default/files/blogs/2017/1709/cat.jpg' />"
    }
})

我效果中,我们可以看到:

<img src="//www.w3cplus.com/sites/default/files/blogs/2017/1709/cat.jpg">

插入到了div元素中,效果如下:

v-text and v-html

v-text一样,如果我们动态修改数据源中cat的属性值,就会有相应的变化:

v-text and v-html

注意:你不能使用v-html来复合局部模板,因为Vue不是基于字符串的模板引擎。反之,对于用户界面(UI),组件更适合作为可重用和可组合的基本单位。

在Vue中,不能通过{{}}v-text将HTML的元素插入到模板中。如果你感兴趣,不仿自己动手试试。

在Vue中,使用v-html动态渲染的任意HTML都可能会非常危险,因为它容易导致XSS攻击。这个和JavaScript中的innerHTML类似。所以在实际使用的时候,请只对可信内容使用HTML插值,绝不要对用户提供的内容使用插值。

总结

在Vue中,我们可以使用{{}}将数据插入到相应的模板中,这种方法是一种文本插值。使用这种方法,如果网络慢或者JavaScript出错的话,会将{{}}直接渲染到页面中。值得庆幸的是,Vue还提供了v-textv-html来渲染文本或元素。其中v-text{{}}类似,只是用来渲染文本内容,而v-htmlinnerHTML非常相类,可以将HTML元素渲染。

简单说,这篇文章主要介绍了怎么渲染文本,虽然方法有多种,但个人建议不要使用v-html,因为会引起XSS攻击,对于动态渲染应该尽量使用v-text

由于作者是Vue的初学者,如果文中有不对之处,还请大婶拍正,如果你有更好的经验,欢迎在下面的评论中与我们一起分享。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.w3cplus.com/vue/v-text-and-v-html.html

返回顶部