目录
Vue实例
Vue实例
创建Vue实例
每个Vue应用都是通过用Vue函数创建一个新的Vue实例开始的
var vm = new Vue({
// 选项
})
Vue虽然没有完全遵循MVVM模型,但是设计也受到了它的启发。因此在文档中经常会使用vm (ViewModel的缩写)这个变量名表示Vue实例
当创建一个Vue实例时,可以传入一个选项对象。
一个Vue应用由一个通过new Vue创建的根Vue实例,以及可选的嵌套的、可复用的组件树组成。
Vue组件都是Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外)
举个例子,一个 todo 应用的组件树可以是这样的:
根实例:
└─ TodoList
├─ TodoItem
│ ├─ TodoButtonDelete
│ └─ TodoButtonEdit
└─ TodoListFooter
├─ TodosButtonClear
└─ TodoListStatistics
Vue实例生命周期
每个Vue实例在被创建时都要经过一系列的初始化过程。例如:需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期的函数,这给了用户在不同阶段添加执行自己的代码的机会
生命周期允许在实例不同阶段执行各种操作,便于更好地控制和使用实例
生命周期的this上下文指向调用它的Vue实例(new Vue())
一般把Vue的生命周期分为三个阶段:①初始化、②运行中、③销毁
比如created可以用来在一个实例被创建之后执行代码:
new Vue({
data : {
a : 1
},
created : function() {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
new Vue()创建后输出:“a is: 1”
数据与方法(双向绑定)
当一个Vue实例被创建时,它将data对象中的所有的property加入到Vue的响应式系统中。当这些property的值发生改变时,视图将会产生“响应”,即匹配更新为新的值
使用双向绑定
// 数据对象
var data = { a: 1 }
// 该对象被加入到一个Vue实例中
var vm = new Vue({
①:
data: data
②:
data: { a: 1 }
})
// 获得这个实例上的property
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置property也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于data中的property才是响应式的。也就是说如果添加一个新的property,则没有效果
vm.b = 'hi'
那么对b的改动将不会触发任何视图的更新
注意:双向绑定只是针对构造时就已经存在的property(属性)
如果知道会在晚些时候需要一个property,但是一开始它为空或不存在,那么仅需要设置一些初始值。也就使用双向绑定
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}
取消双向绑定(Object.freeze())
Object.freeze():这会阻止修改现有的property,也意味着响应系统无法再追踪变化
var obj = { foo : 'bar' }
Object.freeze(obj)
new Vue({
el : '#app',
data : obj
})
<div id="app">
<p>{{ foo }}</p>
<!-- 这里的“foo”不会更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
除了数据property,Vue实例还暴露了一些有用的实例property与方法。它们都有前缀$,以便与用户定义的property区分开来
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 (newValue, oldValue) {
// 这个回调将在“vm.a”改变后调用
})
Vue生命周期方法
生命周期方法 | 描述 |
---|---|
beforeCreate | Vue实例创建前 |
created | Vue实例创建后 |
beforeMount | Vue实例挂载前 |
mounted | Vue实例挂载后 |
beforeUptate | Vue实例更新前 |
updated | Vue实例更新后 |
beforeDestroy | Vue实例销毁前 |
destroyed | Vue实例销毁后 |
注意:不要在选项property或回调上使用箭头函数
①:
created: () => console.log(this.a)
②:
vm.$watch('a', newValue => this.myMethod())
因为箭头函数并没有this,this会作为变量一直向上级词法作用域查找,直至找到为止,经常导致如下错误
Uncaught TypeError: Cannot read property of undefined
或
Uncaught TypeError: this.myMethod is not a function
(1)beforeCreate
在vue实例完全被创建出来之前(vue实例还没有被完全创建出来)被调用,此时数据还没有被初始化,所以无法访问数据(el、data等的值都是undefined)
(2)created
在vue实例创建完成后被调用,这个过程已完成了数据的初始化,可以被访问得到,也能获得methods方法;这个过程可以修改数据(渲染之前修改数据的机会)
(3)beforeMount
模版已经在内存中编译完成,挂载(注入反应性,双向绑定)之前被调用,render函数也是首次被调用,此时完成了虚拟DOM的构建,但并未被渲染(渲染前最后一次修改数据的机会)
(4)mounted
模版挂载之后被调用,完成渲染,所以可以操作DOM
(5)beforeUpdate
在重新渲染之前(更新前)调用,这个过程是不能更改数据的;如果在调用这个钩子函数之前数据没有改变的话,是无任何变化的;当数据发生改变之后,此时实例中的数据是最新的,而页面中的数据还是之前旧的,两者并没有达到同步;这个过程会再次调用render函数,它会重新构建虚拟Dom,然后与上次生成的虚拟Dom树利用diff算法进行对比找出差异,为下次的重新渲染做准备
(6)updated
在重新渲染之后(更新后调用)被调用,已渲染完成,页面更新,此时实例中的数据与页面中的数据是同步的
(7)beforeDestroy
在Vue实例销毁之前被调用,在这个过程中可以做一些事情。比如:清除计时器或事件等等
(8)destroyed
在Vue实例销毁后调用,并且Vue实例中所有的东西都会解绑,所有的事件监听器都会被移除,所有的子实例也会被销毁