Vue
函数创建一个新的 Vue 实例开始的:var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
将new Vue创建出来的对象实例赋给变量vm是为了后续使用该实例对象时直接通过vm变量调用。例如调用实例对象的属性:
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
每个 Vue 实例在被创建时都要经过一系列的初始化过程,在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created 钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
生命周期示意:
下图展示了实例的生命周期。暂时不需要立马弄明白所有的东西,随着不断学习和使用,它的参考价值会越来越高。
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
Message: {{ msg }}
Mustache 标签将会被替代为对应数据对象上 msg
property 的值。无论何时,绑定的数据对象上 msg
property 发生了改变,插值处的内容都会更新。
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用v-html
指令:
Using mustaches: {{ rawHtml }}
Using v-html directive:
这个 span
的内容将会被替换成为 property 值 rawHtml
,直接作为 HTML。
显示结果:
Mustache 语法不能作用在 HTML attribute(即HTML 元素) 上,遇到这种情况应该使用 v-bind
指令:
v-bind指令也是绑定属性的。
v-bind的缩写:
...
...
...
v-on的缩写:
...
...
...
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
{{ message.split('').reverse().join('') }}
所以,对于任何复杂的逻辑,都应当使用计算属性,计算属性和属性的作用是一致的,这里着重强调一点的是理解它的意义,计算属性也是一种属性,只不过它是一个函数,函数的返回结果就是属性值。所以可以像绑定普通 property 一样在模板中绑定计算属性。
Original message: "{{ message }}"
Computed reversed message: "{{ reversedMessage }}"
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
结果(页面加载完成之前就早已经计算完毕返回计算结果了):
Original message: "Hello"
Computed reversed message: "olleH"
这里我们声明了一个计算属性 reversedMessage
。我们提供的函数将用作 property vm.reversedMessage
的 getter 函数:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
Vue 知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生改变时,所有依赖 vm.reversedMessage
的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。
计算属性 VS 方法:
刚刚说了计算属性是一个函数方法。所以方法也能完成计算属性的功能,结果也完全一致。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。【说得通俗点就是计算属性使用了缓存,只有属性发生变化时才会重新计算,而函数方法则每次都需要计算,所以在系统开销比较大时使用计算属性比较合适,如果不希望有缓存,请用方法来替代。】
侦听器:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
简介:因为Class 与 Style都是 attribute,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
使用的是:v-bind:class
上面的语法表示 active
这个 class 存在与否将取决于数据 property isActive
是true还是false。
可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class
指令也可以与普通的 class attribute 共存。例如:
data:
data: {
isActive: true,
hasError: false
}
结果渲染为:
当 isActive
或者 hasError
变化时,class 列表将相应地更新。例如,如果 hasError
的值为 true
,class 列表将变为 "static active text-danger"
。
使用的是:v-bind:style
v-else-if
v-if
是一个指令,所以必须将它添加到一个元素上,它是有条件的渲染一块内容。这块内容只会在指令的表达式返回值为true的时候被渲染。
也可以用 v-else
添加一个“else 块”:
Vue is awesome!
Oh no
v-else
元素必须紧跟在带 v-if
或者 v-else-if
的元素的后面,否则它将不会被识别。
v-else-if
元素类似于 v-else
也必须紧跟在带 v-if
或者 v-else-if
的元素之后。
用来标识元素的唯一性。使用方法:https://cn.vuejs.org/v2/guide/conditional.html#用-key-管理可复用的元素
v-show
用于根据条件展示元素,用法和v-if大致一样:
Hello!
不同的是带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS property display
。
注意,v-show
不支持 <template>
元素,也不支持 v-else
。
v-if VS v-show:
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
2.7.1 v-for:
可以基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
-
{{ item.message }}
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
结果:
在 v-for
块中,我们可以访问所有父作用域的 property。v-for
还支持一个可选的第二个参数,即当前项的索引。
-
{{ parentMessage }} - {{ index }} - {{ item.message }}
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
结果:
-
{{ value }}
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
结果:
也可以提供第二个的参数为 property 名称 (也就是键名):
{{ name }}: {{ value }}
结果:
还可以用第三个参数作为索引:
{{ index }}. {{ name }}: {{ value }}
结果:
使用key来维护状态,以便v-for能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
attribute。key最好是字符串或数值类型的值。
2.7.4.1 Vue 将侦听的数组的变更方法进行了包裹,所以这些也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
在自定义组件上,你可以像在任何普通元素上一样使用 v-for
。
注意:
1、2.2.0+ 的版本里,当在组件上使用 v-for
时,key
现在是必须的。
2、任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:
不自动将 item
注入到组件里的原因是,这会使得组件与 v-for
的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。
可以用 v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法:
// ...
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
v-model
指令在表单 、
及
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model
会忽略所有表单元素的 value
、checked
、selected
attribute 的初始值而总是将 Vue 实例的数据作为数据来源。所以需要通过 JavaScript 在组件的 data
选项中声明初始值。