Vue 声明式渲染

  • 插值:如果只使用 Vue 最基础的声明式渲染,则完全可以把 Vue 当做一个模板引擎来使用。
    • {{ Mustache }} 语法 — 双向数据绑定
    • 属性绑定 v-bind — JS 表达式支持
    • 过滤器 fliters
  • 指令,是带有 v- 前缀的特殊属性,本质上就是自定义属性。指令的属性值预期是单一 JS 表达式( v-for 除外 )。指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

插值

[ 双向数据绑定 ] 所谓数据绑定,就是将数据填充到标签中;而,数据的响应式,指的是数据的变化导致页面内容的变化。


[1] Mustache 语法数据绑定最常见的形式,就是使用 “Mustache” 语法( 双大括号 ) 的文本插值。

// 代码示例
<span>Message:{{msg}}</span>

# 渲染之后,<Mustache> 标签中的 msg 变量会被替换成其所代表的值,
# 而且无论何时,只要 msg 代表的值发生变化,<Mustache> 标签中的内容也会随之改变。
  • v-once  只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。
<span v-once>这个将不会改变: {{ msg }}</span>

# 简单来说,v-once,可以进行一次性的插值,当数据改变时,插值处的内容不会更新
# 需要注意的是,这会影响到该节点上所有的数据绑定
# 应用场景:如果要显示的内容后续不需要再修改,可以使用 v-once,这样可以提高一点性能(不需要响应式监控了)。
  • v-text    更新元素的 textContent。    // 如果要更新部分的 textContent,需要使用 {{Mustache}} 插值。
<span v-text="msg"></span>
     
# v-text 也可以实现类似的文本渲染,区别在于:
#   1. 默认 v-text 是没有闪烁问题的;
#   2. v-text 会覆盖元素中原本的内容,但插值表达式只会替换自己的占位符,不会把整个元素的内容清空。
  • v-clock  隐藏未编译的 Mustache 标签不显示,直到编译结束 — 解决 Mustache 插值的闪烁问题
// HTML
<span v-cloak>Message:{{msg}}</span>

// CSS
[v-cloak]{
	display: none;
}

# 其原理是,先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的结果
  • v-html  填充 HTML 片段
# rawHTML 代指HTML代码
<p>使用v-html指令:<span v-html="rawHTML"></span></p>

# <Mustache> 标签中的内容会被解析成文本,而不是 HTML 代码
# 同时,需要注意的是,v-html 存在数据安全问题,容易导致 XSS 攻击(跨站脚本攻击);
# 因此,基本原则是:只在可信内容上使用 v-html(本网站内部数据可以使用,来自第三方的数据不可以用)
  • v-pre  填充原始信息,跳过编译过程
<span v-pre>{{ msg }}</span>

# 不会编译,页面上会直接渲染 {{ msg }}

[2] 属性绑定 v-bind:Mustache 语法不能作用在 HTML 属性上,遇到这种情况应该使用 v-bind 指令:

// 值绑定
<div v-bind:id="dynamicId"></div>

# 对于布尔特性( 它们只要存在就意味着值为 true ),v-bind工作起来略有不同,在这个例子中:

<button v-bind:disabled="isButtonDisabled">Button</button>

// 如果 isButtonDisabled 的值是 null、undefined 或 false,则 disabled 特性甚至不会被包含在渲染出来的 <button> 元素中。

# v-bind 中,也可以写合法的 JS 表达式;实际上,vue.js 提供了完整的 JS 表达式支持。

// 对于任何复杂逻辑,推荐使用计算属性。

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>

# 上面的表达式会在所属 Vue 实例的数据作用域下作为 JS 被解析。
# 需注意的是,Vue 对 JS的支持有个限制:每个绑定都只能包含单个表达式。

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

[3] 过滤器 filters:Vue 允许自定义过滤器,被用作一些常见的文本格式化。

// 过滤器应该被添加在 mustache 插值的尾部,由“管道符”指示:
   {{ message | capitalize }}

# 过滤器可以用在两个地方:双花括号插值和 v-bind 表达式( 后者从 2.1.0+ 开始支持 )。
  # 为了在指令绑定中实现同样的行为,应该使用计算属性。

# 过滤器函数,总接受表达式的值作为第一个参数。可以在一个组件的选项中定义本地的过滤器:

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

或者在创建 Vue 实例之前全局定义过滤器:

Vue.filter('capitalize', function (value) {        // 当全局过滤器和局部过滤器重名时,会采用局部过滤器。
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})

# 过滤器可以串联:

{{ message | filterA | filterB }}

# 过滤器是 JavaScript 函数,因此可以接受参数:

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

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

指令

指令,是带有 v- 前缀的特殊属性,本质上就是自定义属性。指令的属性值预期是单一 JS 表达式( v-for 除外 )。

指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

# 基本语法
  v-指令名称:<参数 | [动态参数]>="表达式的值"      // 指令属性的值通常是单一的JS表达式
  如,<p v-if="show" v-on:click="clickBtn">{{msg}}</p>

# 常见指令
   v-if  根据表达式的值的 true / false 来插入或移除元素
   v-bind  属性绑定,用于响应式地更新 HTML 属性
   v-on  事件绑定,用来给目标元素进行事件绑定,事件的类型由参数决定
   ...

[1] 参数 / 动态参数

# 参数:一些指令能够接收一个“参数”,在指令名称之后以冒号表示

<a v-bind:href="url">...</a>  // 在这里,href是参数,告知v-bind指令将该元素的href特性与表达式url的值绑定。

<a v-on:click="doSomething">...</a>  // 在这里,参数是监听的事件名,该指令用于监听DOM事件。

# 动态参数:从2.6.0开始,可以用方括号括起来的JS表达式动态求值,作为一个指令的参数

<a v-bind:[attributeName]="url"> ... </a>

// 这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。
// 例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。
<a v-on:[eventName]="doSomething"> ... </a>

// 同样地,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus。

## 动态参数 - 约束:

  • 值的约束:动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
  • 表达式的约束:动态参数表达式有一些语法约束,因为某些字符,例如空格和引号,放在 HTML 特性名里是无效的。同样,在 DOM 中使用模板时你需要回避大写键名。
下面的代码是无效的:

<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>

// 变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。
# 如果在DOM中使用模板 (直接在一个HTML文件里撰写模板),需留意浏览器会把特性名全部强制转为小写:

<!-- 在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]` -->
<a v-bind:[someAttr]="value"> ... </a>

[2] 简写方式

Vue 为 v-bind和 v-on这两个最常用的指令,提供了特定的简写方式:

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

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