# Vue模板语法

# 概述

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

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

一般地,模板内容包括文本内容和元素特性

# 文本渲染

# 文本插值

文本渲染最常见的形式是使用双大括号语法来进行文本插值

<div id="app">
    <!-- message相当于一个变量或占位符,最终会表示为真正的文本内容  -->
    {{ message }}  
</div>

# 表达式插值

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

上面这些表达式会在所属Vue实例的数据作用域下作为JS被解析

WARNING

有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

# v-text

实现插值类似效果的另一种写法是使用v-text指令,该指令用于更新元素的innerText

WARNING

如果要更新部分的innerText,需要使用模板插值

[注意] v-text优先级高于模板插值的优先级

<div id="app" v-text="message"></div>
data(){
    message:'hello world!'
}

# v-html

如果要输出真正的 原始HTML ,需要使用 v-html 指令,该指令用于更新元素的 innerHTML

WARNING

[注意] 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。

只在可信内容上使用 v-html,而不用在用户提交的内容上

<div id="app" v-html="message"></div>
data(){
    message:'<h1>this is v-html directive</h1>'
}

# 静态插值

一般地,模板插值是动态插值。即无论何时,绑定的数据对象上的占位符内容发生了改变,插值处的内容都会更新

# v-once

如果要实现静态插值,即执行一次性插值,数据改变时,插值处内容不会更新,这时需要用到v-once指令

<div id="app" v-once>{{ message }}</div>
data(){
    message: '测试内容'
}

无论message的值如何变化,DOM结构中元素内容仍然是“测试内容”。

# 不解析渲染v-pre

如果要跳过这个元素和它的子元素的编译过程,只用来显示原始大括号及标识符,则可以使用v-pre指令。可以减少编译时间

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

<!-- 界面仅显示{{ message }} -->

# 隐藏未编译v-clock

TIP

一般地,使用模板差值时,页面上会显示大括号及占位符。编译完成后,再转换为真正的值。如果在网络条件不好的情况下,这种现象更加明显

这个指令保持在元素上直到关联实例结束编译。 和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕

<style>
    [v-cloak]{display:none;} 
</style>
<div id="example" v-cloak>{{ message }}</div>

# 特性渲染v-bind

v-bind指令可以动态地绑定一个或多个特性

<div id="app" v-bind:title="message"></div>

<!-- 缩写 -->
<div id="app" :title="message"></div>
data(){
    message:"hello vue!"
}

# class绑定

数据绑定一个常见需求是操作元素的class列表和它的内联样式。 因为它们都是属性 ,可以用v-bind处理它们:只需要计算出表达式最终的字符串。 不过,字符串拼接麻烦又易错。因此,在v-bind用于class和style时, Vue.js 专门增强了它。 表达式的结果类型除了字符串之外,还可以是对象或数组

# 对象语法

我们可以传给 v-bind:class 一个对象,以动态地切换 class:

<!-- 1、内联对象语法 -->
<div v-bind:class="{ active: isActive }"></div>
<!-- 渲染结果 -->
<div class="active"></div>

<!-- 2、传入多个 -->
<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>
<!-- 渲染结果 -->
<div class="static active"></div>


<!-- 3、非内联绑定对象 -->
<div :class="classObject"></div>
<!-- 渲染结果 -->
<div class="static active"></div>

<!-- 4、绑定一个返回对象的计算属性 -->
<div :class="innerClassObject"></div>
<!-- 渲染结果 -->
<div class="static active"></div>
data() {
    isActive: true,
    hasError: false,
    error: null,

    // 非内联绑定对象
    classObject: {
        active: true,
        'text-danger': false
     }
}

computed: {
  innerClassObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

# 数组语法

可以把一个数组传给 v-bind:class,以应用一个 class 列表:

<div v-bind:class="[activeClass, errorClass]"></div>

<!-- 渲染为 -->
<div class="active text-danger"></div>
data(){
  activeClass: 'active',
  errorClass: 'text-danger'
}

# style绑定

# 对象语法

  • v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。
  • CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名
<!-- 
data: {
    activeColor: 'red',
    fontSize: 30,
    styleObject:{
        color: 'red',
        fontSize: '13px'
    }
}
-->

<!-- 1、内联对象 -->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

<!-- 2、直接绑定到一个样式对象通常更好,这会让模板更清晰 -->
<div v-bind:style="styleObject"></div>

<!-- 3、对象语法常常结合返回对象的计算属性使用。 -->

# 数组语法

v-bind:style 的数组语法可以将多个样式对象应用到一个元素上

<div id="app" :style="[baseStyles, overridingStyles]"></div>
 data: {
    baseStyles: {
      color: 'red',
      fontSize: '13px'
    },
    overridingStyles:{
      height:'100px',
      width:'100px'
    }
}

# 前缀

v-bind:style使用需要特定前缀的CSS属性时,如transformVue.js会自动侦测并添加相应的前缀。

可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值。

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">

这会渲染数组中最后一个被浏览器支持的值。在这个例子中,如果浏览器支持不带浏览器前缀的 flexbox,那么渲染结果会是 display: flex

# 过滤器

Vue.js允许自定义过滤器,可被用作一些常见的文本格式化。 过滤器可以用在两个地方:模板插值和v-bind表达式。过滤器应该被添加在JS表达式的尾部,由“管道”符 即 | 指示

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!--`v-bind`-->
<div v-bind:id="rawId | formatId"></div>

# 组件的选项中局部过滤器

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

# 全局定义过滤器

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})

WARNING

当全局过滤器和局部过滤器重名时,会采用局部过滤器。

# 过滤器可以串联

{{ message | filterA | filterB }}

filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。

# 过滤器可以接收参数

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

filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 arg1 作为第二个参数,表达式 arg2 的值作为第三个参数。

Last Updated: 1/15/2023, 1:03:09 AM