跟着官档学 Vue.js (四) - 模板语法

读到这里的时候,Vue 总算要来介绍一下自己的语法了。

把一些概念的名字深记在心,有助于阅读接下来的文档。

插值

在文档中使用了 插值(interpolations) 一词。顾名思义,就是在适当的地方插入适当的值。

mustache

我们在前面总是称 {{}} 为花括号,现在,人家总算把官方的名字介绍给我们,叫做 mustache语法

<div id="app-6">
    <p>{{ message }}</p>
</div>
<script>
    var app6 = new Vue({
        el: '#app-6',
        data: {
            message: 'Hello Vue!'
        }
    });
</script>

使用双大括号语法,在其中书写 表达式,将输出相应的结果,上例中便是把 Vue 实例中的 message 绑定到了 <p> 节点上。

再双大括号中可以书写表达式,意味着以下的例子都是正确的、合法的:

{{ num + 1 }}
{{ bool? 'true' : 'false' }}
{{ someStr.split('').reverse().join('') }}

它仅仅支持单句的表达式,但是像这样就不合法:

{{ if(a){ return a } }} //不支持流程控制
{{ var a = 1 }} //这是语句,不是表达式

当我尝试要使用多个vue数据的时候,有时候脑子抽了就可能会弄错。

<!--正确的例子-->
<p>{{ message }},{{ message }}</p>
<p>{{ message ,message }}</p>

<!--错误的例子-->
<p>{{ message ,{{ message }} }}</p>

v-html

但是有时候,我们可能想要让这对大括号保留在页面上,而不是被渲染成 vue 数据。我能想到的方法就是把大括号也给写在 data 中:

<div id="app">
    <p>{{ message }}</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            yeah: 1,
            message: '{{ yeah }}'
        }
    });
</script>

页面输出:

可以发现,message 中的 {{ yeah }} 并不会再被解析成 data 中定义的 1,也就是说,双大括号会将数据解释为 纯文本

那如果我们假设 message 中的内容是

message : '<p>hello</p>'

输出的结果如下:

好像,并不是我们期望的那样输出成html,这验证了我们前面说的,双大括号会将数据解释为 纯文本

那怎么才能输出成 html 呢?这个时候就需要用到一个指令 v-html 来绑定这个数据了:

<div id="app">
    <p v-html="message"></p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: '<p>hello</p>'
        }
    });
</script>

我们使用了 v-html 进行插值,就再也不用使用 双大括号语法 来插值了。

v-once

但是又有些时候,我们只希望在页面初始化的时候绑定这些数据,不希望如果以后数据发生改变的话,这些 DOM 中的内容也跟着改变,这个时候就需要用到 v-once 指令来插值了,v-once指令需要配合 v-html{{}} 来进行插值:

<p v-once v-html="message"></p>
<p v-once>{{message}}</p>

v-bind

在第一节的时候我们就提及过,{{}} 不能用在插值 html属性,但是如果我们想对某个标签的属性进行插值,该怎么办呢?

vue提供了 v-bind 指令,用来绑定标签属性:

<div id="app">
    <p v-bind:id="myId">hello</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            myId: 1
        }
    });
</script>

效果如下:

这个指令其实有点笨拙地说,如果我们现在想要让id的格式变成 hi-1 这样子的话,按照理想中的情况,如果能用 {{}} 来绑定,它会是这样的:

<p id="{{ `hi-` + myId }}">hello</p>

然而,梦想总是美好的,现实应该是这样的:

<p v-bind:id=" 'hi-'+ myId ">hello</p>

也就是我们把 v-bind 后面的双引号当成是 {{}} 了,然后里面的内容就像前面说的一样,可以是单句的js表达式。

需要注意一点,如果bind的属性值是 false 的话,vue不会将这个属性渲染出来。

指令

到目前为止我们已经接触了不少指令了,它们都是以 v- 开头的特殊的html属性,它的完整语法其实是这样的:

三个部分:指令(Directive)参数(Argument)修饰符(Modifier)

我们接触过的指令比如说 v-once ,他的用法就是直接写在某个标签里面,它不需要参数和修饰符。

比如说 v-bind,一般的用法形如 v-bind:id='myId',它的用法就需要一个参数 id 用来绑定到该元素的 id 属性上。

vue中还有一个 v-on 用来绑定事件,用法形如 v-on:click.prevent='someMethod',这里就有参数 click 用于绑定点击事件,还有一个 .prevent 修饰符用于处理这个事件的一些特殊细节。

大部分指令需要接收值,就是 等于号= 之后的内容,我们前面已经提及到了,它接受单一 JavaScript 表达式,当然也有例外,文档中就说除了 v-for

过滤器

原文中到这里实在是看不懂,后来捋了一圈才明白。

什么是过滤器?

过滤器(filters) 不能从中文的字面上来理解,翻译成过滤器不太恰当,我觉得把它理解成 文字格式化工具 会更好一些。因为 过滤器 在这里是用来处理一些常见的文本格式化,比如说,首字母大写、全部大写、添加软妹币符号等等。

不过要注意的是,这个操作一般是比较简单的格式化操作,而不是去改变它的内容。比如说,有一个记录分数的标签

<p>{{ score | formatScore }}</p>

假设 score = 50 经过过滤器之后应该显示为 <p> 50分 </p> 而不是 <p> 不及格 </p>

能用在什么场合?

在 vue 2.0 中,它硬性规定可以用在两个地方:mustache 插值和 v-bind 表达式

使用方法?

<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>

这是官方给的例子。其中可以看到 | 符号,被称之为 管道符(pipe symbol), 然后过滤器和过滤器是可以串联的:

{{ message | filterA | filterB }}

它将会先用 filterA 处理 message,再用 filterB 处理之前已经处理完成的东西再输出。

问题就来了,官方没有说的很清楚,这些过滤器是需要自己来实现的,官方并没有提供内置的过滤器。

在 Vue 1.x 的版本中就有提供内置的过滤器,但在 2.x 中移除了。

所以,我们需要自己写,下面提供一个例子,使得首字母大写:

<div id="app">
    <p>{{ message | capitalize }}</p>
</div>
<script>
    Vue.filter('capitalize', function(value) { // message 将作为过滤器的第一个参数传入到value 中
        if (!value) { return ''}
        value = value.toString();
        return value.charAt(0).toUpperCase() + value.slice(1);
    });

    var app = new Vue({
        el: '#app',
        data: {
            message: "hello"
        }
    });
</script>

需要注意的点有很多,首先就是我们必须在使用过滤器之前用 Vue.filter 注册过滤器。

第二点就是,过滤器函数总是接受 插值表达式的值 作为第一个参数。这意味着,我们可以为过滤器添加其他函数参数,并以下面的形式来使用过滤器:

{{ message | filterA('arg1', arg2) }}

这里,字符串 'arg1' 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。

缩写

因为,v-bindv-on 的使用率太高了,所以有了他们的缩写形式。

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

真是炒鸡棒棒呢。

  vue.js