插值
1、文本
<span>Message: {{ msg }}</span>
2、原始的html
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
3、属性
Mustache 语法不能作用在 HTML 属性上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
<button v-bind:disabled="isButtonDisabled">Button</button>
4、使用js表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
有个限制就是,每个绑定都只能包含单个表达式。模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。你不应该在模板表达式中试图访问用户定义的全局变量。
指令 (Directives) 是带有 v- 前缀的特殊属性。指令属性的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。
<a v-bind:href="url">...</a>
|
在这里 href 是参数,告知 v-bind 指令将该元素的 href 特性与表达式 url 的值绑定。
修饰符
修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
<form v-on:submit.prevent="onSubmit">...</form>
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
|
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
}) |
<p>Reversed message: "{{ reversedMessage() }}"</p>
|
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
|
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
<div id="demo">{{ fullName }}</div>
|
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
|
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
}) |
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
|
现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
<div v-bind:class="classObject"></div>
|
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
<div v-bind:class="[activeClass, errorClass]"></div>
|
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
|
渲染为:
<div class="active text-danger"></div> |
|
例如,如果你声明了这个组件:
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
|
然后在使用它的时候添加一些 class:
<my-component class="baz boo"></my-component>
|
HTML 将被渲染为:
<p class="foo bar baz boo">Hi</p>
|
对于带数据绑定 class 也同样适用:
<my-component v-bind:class="{ active: isActive }"></my-component>
|
当 isActive 为 truthy[1] 时,HTML 将被渲染成为:
<p class="foo bar active">Hi</p> |
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
|
data: {
activeColor: 'red',
fontSize: 30
} |
<div v-bind:style="styleObject"></div>
|
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
} |
<div v-bind:style="[baseStyles, overridingStyles]"></div>
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
|
现在,每次切换时,输入框都将被重新渲染。请看:
注意,<label> 元素仍然会被高效地复用,因为它们没有添加 key 属性。
在 v-for 块中,我们拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引。
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
|
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
}) |
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
|
<div v-for="(value, key) in object">
{{ key }}: {{ value }}
</div>
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
}) |
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
npm install
npm run serve
npm run build