Vue.js 的指令是带有前缀 v- 的特殊 HTML 属性,其中的v-pre 指令用于指示 Vue 编译器跳过含有该指令的元素及其子元素,该指令主要有如下两个用途:
- 显示原始插值标签
- 跳过大量没有指令的节点以降低编译时间
编写较复杂的 Vue.js 模板时可以适当使用 v-pre 指令,提升编译效率。
数据绑定插值
使用Mustache语法:
- {{ msg }}
-
{{{ HTMLFragment }}}
插值类型: - 文本
- 原始HTML
- HTML属性
指令
带有前缀 v- 的特殊属性v-if、v-text、v-html、v-bind、v-on....
作用就是把某些特殊的行为应用到DOM上
v-bind和v-on的缩写形式
v-bind和v-on都必须带有参数才有意义
- v-bind:src => :src
- v-on:click => @click
绑定表达式
- 支持全功能的JavaScript表达式
- 表达式将在其所在Vue实例的作用域内进行计算
- 不支持多于一个JavaScript表达式
- 不支持语句及流程控制
<!-- 插值 -->
{{ message }}
{{{ htmlSegment }}}
<img src="{{ photoURL }}" />
Vue.js 的双大括号插值和三大括号插值其实是语法糖,双大括号会被编译成一个 textNode,然后使用 v-text 指令插入插值内容,而三大括号插值则被编译成一个锚节点,然后使用 v-html 指令替换为插值内容,上述过程比直接在 DOM 元素中使用 v-text 或 v-html 在性能上略有降低。
可以使用 Vue.config 全局配置对象的 delimiters 和 unsafeDelimiters 属性设置自定义的插值定界符,以避免与其他模板冲突,自定义插值定界符的语句应该写在 Vue 实例化之前。
例如:
// ES6 模板字符串
Vue.config.delimiters = ['${', '}']
// 使之看起来更危险
Vue.config.unsafeDelimiters = ['{!!', '!!}']
Vue.js 使用了将插值内容直接赋值给 textNode 元素的 data 属性或其他元素的 textContent 属性这样一种精巧的方式进行 HTML 转义,充分利用了浏览器自身的处理能力。这种方式也会产生无伤大雅的副作用,如对 textNode 元素的 data 属性赋值其实是调用了该属性的 setter() 方法,实际生成的 DOM 元素的代码与绑定表达式的值有可能不完全相同。
Vue.js 2.0 中移除所有内置过滤器Vue.js 2.0 版中移除所有内置过滤器,过滤器的使用方式也将发生改变,在新版本中,过滤器后使用括号而非空格来添加参数,并只可应用于插值方式的数据绑定,其他使用过滤器的场景使用计算属性替代,并根据需要选择使用针对不同专业领域的第三方独立库,如针对日期时间处理使用 Moment.js,针对金融货币处理使用 Accounting.js,针对数组和对象处理使用 lodash。
修饰符不同修饰符的作用互相独立,因此串联顺序不会影响使用效果;self 修饰符的作用是阻止响应由其他元素冒泡的事件,stop 修饰符用于停止冒泡,但这两者并不矛盾,可以应用于同一元素绑定事件;大部分 HTML 属性不区分大小写,使用 camel 修饰符时,对应的属性会被移除“-”号,但并不会呈现为驼峰样式,仅对类似于 SVG 元素的 viewBox 这样的特殊属性才会改为驼峰样式。
v-if和v-showv-if 指令的切换性能消耗较高,当条件切换时,v-if 指令会根据条件创建或删除 DOM 元素,在条件满足时编译生成相应的元素并插入 DOM 结构,在条件不满足时将元素从 DOM 结构中删除;当使用 <template>
元素包装多个元素时,最终的渲染结果仅包含 <template>
元素的内容。
v-show 指令的初始性能消耗较高,v-show 指令会在初始编译时创建元素并插入 DOM 结构,同时根据条件决定该元素是否显示;v-show 指令不能使用 <template>
元素包装多个元素;v-if 和 v-show 指令后面都可以紧跟一个 v-else 指令表示当条件不满足时渲染/显示的内容。
- 多于一个元素的 v-if 需要使用
<template>
- v-show 不支持
<template>
- v-else 必须紧跟在 v-if/v-show 指令后面
- 组件条件下不能使用
<v-else>
有两种方法可以实现列表内容的过滤和排序而不用修改原始数据:
- 使用内置的 limitBy、filterBy 和 orderBy 过滤器;
- 创建一个计算属性,返回过滤/排序过的数组。
通常使用过滤器较为方便,而计算属性有更好的控制力,也更灵活。基于满足灵活性和复杂性的考虑,推荐使用专业的第三方类库 lodash 创建计算属性来实现列表内容的过滤和排序。
track-by的使用使用 track-by 可以增加复用,提升数据变动时的渲染性能;可以 track-by 数组中的唯一键值来指示当键值一致时复用使用域和 DOM 元素;若数组没有唯一键值,可以使用 track-by="$index" 指示 v-for 指令进行原位更新模式,该模式也可用于处理数组中的重复值。
- 如果每个对象都有一个唯一的ID属性,设置track-by该属性,可以最大化复用DOM元素,避免重新渲染。
- 允许重复值,设置track-by $index
Vue.js 包装的数组变异方法有:push、pop、shift、unshift、splice、sort、reverse,这些方法均对原始数组进行了修改。
类与样式绑定的增强为了更灵活地进行类绑定,Vue.js 支持在数组语法中使用对象的混合绑定语法。对象语法支持驼峰式和短横分隔式的 CSS 属性名;对于需要厂商前缀的 CSS 属性名,Vue.js 并不是粗暴地直接添加,而是自动侦测后添加相应的前缀,若无必要,不会添加;采用数组语法时,会对绑定的数组使用 reduce 方法执行从前到后的对象 extend 操作(类似于 jQuery.extend 方法),其结果是若不同数组元素中有相同的 CSS 属性,后出现元素中的 CSS 属性值覆盖结果中的 CSS 属性值,因此是后出现的优先应用;对象语法常常结合返回对象的计算属性使用,实现数据响应式的效果。
类绑定的对象语法
<span class="switch" :class="{switched: gender}" @click="gender = Math.abs(~-gender)">
<span class="switch-item-1" data-pseudo-content="男"></span>
<span class="switch-item-2" data-pseudo-content="女"></span>
</span>
var vm = new Vue({
el: '#app',
data: {
gender: 0,
off: true,
nameType: 'Eng'
}
})
类绑定的数组语法
<table class="table" :class="tableClasses">
<caption>
Table Caption
</caption>
<thead>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
<script>
var vm = new Vue({
el: 'body',
data: {
tableClasses: ['table-striped', 'table-bordered']
}
})
</script>
样式绑定的对象语法
<div class="container">
<h1>
样式绑定对象与数组语法
</h1>
<div class="row">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">
颜色:红,字体:30px
</div>
<hr>
<div :style="styleObject">
颜色一样红,字体也是30px
</div>
<hr>
<div :style="[styleObjectA, styleObjectB]">
颜色继续红,字体保持30px,并且增加了阴影
</div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
var vm = new Vue({
el: 'body',
data: {
activeColor: 'red',
fontSize: 30,
styleObject: {
color: 'red',
'font-size': '30px'
},
styleObjectA: {
color: 'red',
},
styleObjectB: {
fontSize: '30px',
boxShadow: '10px 10px 5px #888888'
}
}
})
</script>
样式绑定的数组语法
<div v-bind:style="[styleObjectA, styleObjectB]"></div>
styleObjectA: {
color: red
},
styleObjectB: {
fontSize: '30px',
boxShadow: '10px 10px 5px #888'
}