# 一、介绍

Vue是一套构建用户界面的 渐进式框架。Vue的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。
# 二、Vue实例
构造器
- 每个
Vue.js应用都是通过构造函数Vue创建一个Vue的根实例 启动的
var vm = new Vue({
// 选项
})
- 在实例化
Vue时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。全部的选项可以在API文档中查看
属性与方法
- 每个
Vue实例都会代理其data对象里所有的属性
var data = { a: 1 }
var vm = new Vue({
data: data
})
vm.a === data.a
// -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
- 除了
data属性,Vue实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀$,以便与代理的data属性区分。例如:
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data
// -> true
vm.$el === document.getElementById('example')
// -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
})
实例生命周期
var vm = new Vue({
data: { a: 1 },
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// -> "a is: 1"
- 也有一些其它的钩子,在实例生命周期的不同阶段调用,如
mounted、updated、destroyed。钩子的this指向调用它的Vue实例。一些用户可能会问Vue.js是否有“控制器”的概念?答案是,没有。组件的自定义逻辑可以分布在这些钩子中
生命周期图示

# 三、模板语法
-
Vue.js使用了基于HTML的模版语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue.js的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。 -
在底层的实现上,
Vue将模板编译成虚拟DOM渲染函数。结合响应系统,在应用状态改变时,Vue能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上。
# 插值
文本
- 数据绑定最常见的形式就是使用 “Mustache” 语法(双大括号)的文本插值
<span>Message: {{ msg }}</span>
Mustache标签将会被替代为对应数据对象上msg属性的值。无论何时,绑定的数据对象上msg属性发生了改变,插值处的内容都会更新- 通过使用
v-once指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上所有的数据绑定
<span v-once>This will never change: {{ msg }}</span>
纯 HTML
- 双大括号会将数据解释为纯文本,而非
HTML。为了输出真正的HTML,你需要使用v-html指令:
<div v-html="rawHtml"></div>
- 被插入的内容都会被当做
HTML—— 数据绑定会被忽略 - 你的站点上动态渲染的任意
HTML可能会非常危险,因为它很容易导致XSS攻击。请只对可信内容使用HTML插值,绝不要对用户提供的内容插值
属性
- Mustache 不能在
HTML属性中使用,应使用v-bind指令:
<div v-bind:id="dynamicId"></div>
使用 JavaScript 表达式
- 对于所有的数据绑定,
Vue.js都提供了完全的JavaScript表达式支持。
{{ number + 1 }}{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
- 这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析
过滤器
Vue.js允许你自定义过滤器,被用作一些常见的文本格式化。过滤器应该被添加在mustache插值的尾部,由“管道符”指示:
{{ message | capitalize }}
指令
- 指令(
Directives)是带有v-前缀的特殊属性。指令属性的值预期是单一JavaScript表达式(除了v-for,之后再讨论) - 指令的职责就是当其表达式的值改变时相应地将某些行为应用到 DOM 上
<p v-if="seen">Now you see me</p>
- 这里,
v-if指令将根据表达式 seen 的值的真假来移除/插入<p>元素
参数
- 一些指令能接受一个“参数”,在指令后以冒号指明。例如,
v-bind指令被用来响应地更新HTML属性
<a v-bind:href="url"></a>
-
在这里
href是参数,告知v-bind指令将该元素的href属性与表达式url的值绑定 -
另一个例子是
v-on指令,它用于监听DOM事件:
<a v-on:click="doSomething">
修饰符
- 修饰符(Modifiers)是以半角句号
.指明的特殊后缀,用于指出一个指令应该以特殊方式绑定 - 例如,
.prevent修饰符告诉v-on指令对于触发的事件调用event.preventDefault()
<form v-on:submit.prevent="onSubmit"></form>
缩写
-
v-前缀在模板中是作为一个标示Vue特殊属性的明显标识 -
Vue.js为两个最为常用的指令提供了特别的缩写 -
v-bind缩写
<!-- 完整语法 --><a v-bind:href="url"></a>
<!-- 缩写 --><a :href="url"></a>
v-on缩写
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
# 四、计算属性
- 在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example"> {{ message.split('').reverse().join('') }}</div>
- 在这种情况下,模板不再简单和清晰。在实现反向显示
message之前,你应该确认它。这个问题在你不止一次反向显示message的时候变得更加糟糕。 - 这就是为什么任何复杂逻辑,你都应当使用计算属性
基础例子
<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: {
//a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
} }})
-
结果:
- Original message: “Hello”
- Computed reversed message: “olleH”
-
这里我们声明了一个计算属性
reversedMessage。我们提供的函数将用作属性
计算缓存 vs Methods
- 你可能已经注意到我们可以通过调用表达式中的
method来达到同样的效果:
<p>Reversed message: "{{ reverseMessage() }}"</p>
// in component
methods: {
reverseMessage: function () {
return this.message.split('
').reverse().join('')
}}
-
不经过计算属性,我们可以在
method中定义一个相同的函数来替代它。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新 取值。这就意味着只要message没有发生改变,多次访问reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数。 -
这也同样意味着如下计算属性将不会更新,因为
Date.now()不是响应式依赖:
computed: { now: function () { return Date.now() }}
-
相比而言,每当重新渲染的时候,
method调用总会执行函数 -
我们为什么需要缓存?假设我们有一个重要的计算属性
A,这个计算属性需要一个巨大的数组遍历和做大量的计算。然后我们可能有其他的计算属性依赖于A。如果没有缓存,我们将不可避免的多次执行A的getter!如果你不希望有缓存,请用method替代
计算属性 vs Watched Property
Vue.js提供了一个方法$watch,它用于观察Vue实例上的数据变动
计算 setter
- 计算属性默认只有
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也会被对应更新
观察 Watchers
对象语法