创建一个实例
每一个Vue 应用都是通过 Vue 函数创建一个新的Vue 实例开始的:
var vm = new Vue({
//选项
});
Vue 虽然未完全按照MVVM 模型,但是Vue 的设计也受到了它的启发。因此文档中经常会使用vm(viewModel 的缩写)这个变量名表示Vue实例。
当创建一个Vue 实例时,你可以传入一个选项对象。一个Vue应用由一个通过 new Vue 创建的 根Vue实例, 以及可选的嵌套的、可复用的组件树组成。eg.
根实例–TodoList
TodoItem
DeleteTodoButton
EditTodoButtonTodoListFooter
ClearTodosButton
TodoListStatistics⚠️ 所有的Vue组件都是Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外)
数据与方法
当一个 Vue 实例被创建时,它向Vue的响应式系统中加入了其data对象中所能找到的所有的属性。当这些属性的值发生改时,视图将会产生响应,即匹配更新为新的值。
//数据对象
var data = {
a: 1
};
//该对象加入到Vue实例之中
var vm = new Vue({
data: data
});
//对象引用是否一致
vm.a === data.a; //true
//设置属性也会影响到原始值
vm.a = 2;
data.a // =>2
//反之亦然
data.a = 3;
vm.a // =>3
当这些数据改变时,视图会重新进行渲染。 值得注意的是只有当实例被创建时 data 中存在的属性才是响应式的。也就是说新添加的属性,eg.
vm.b = 'hi';
那么对 b 的改动将不会触发任何视图的更新。如果预知晚些时候会用到一个新的属性,但是一开始的时候它为空或者不存在,那么你仅需要设置一些初始值。 eg.
data: {
newTodoText:'',
visitCount: 0,
hideCompletedTodos:false,
todos:[],
error:null
}
这里唯一的例外是使用 Object.freeze(),这会组织修改现有属性,也意味着响应式系统无法再追踪变化。
vue.js:3271 Uncaught TypeError: Cannot assign to read only property 'init' of object '#<Object>'。
除了数据属性,Vue 实例还暴露了一些有用的实力属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。
var exampleData = {
a: 1
};
var example = new Vue({
el:'.example',
data: {
a: 1
},
methods: {
changeA: function () {
this.a = 2;
console.log(this.a);
}
}
});
console.log(example.$data === exampleData);
console.log(example.$el === document.getElementsByClassName('example')[0]);
example.$watch('a',function (newVal,oldVal) {
console.log('新值:'+newVal);
console.log('旧值:'+oldVal);
});
实例生命周期钩子
每个Vue 实例在被创建时都要经过一系列的初始化过程–例如,需要设置数据监听、编译模板、将实例挂载到DOM 并在数据变化时更新DOM等。 同时在这个过程中也会运行一些叫做生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。
比如created 钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data:{
a: 1
},
created: function(){
// 'this' 指向 vm 实例
console.log('a is:' + this.a);
}
});
也有其它的一些生命周期钩子, 在实例生命周期的不同阶段被调用,如 mounted、updated 和 destoryed。 声明周期钩子 this 上下文指向调用它的 Vue实例。
⚠️ 不要在选项属性或回调上使用箭头函数,比如created:() => console.log(this.a); 或 vm.$watch('a',newValue => this.myMethod());。 因为箭头函数是和父级上下文绑定在一起的, this 不会是预估的Vue实例,经常会导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。
生命周期示意图
st=>start: new Vue( )
e=>end: Destroyed
opInitBeforeCreate=>operation: Init(Events & Lifecycle)
opInitCreated=>operation: Init ( Injections & Reactivity)
opX=>operation: ?
condHasEl=>condition: Has "el" option ?
condHasTemp=>condition: Has "template" option ?
opVm.$mountedCall=>operation: vm.$mounted(el)
st->opInitBeforeCreate->opInitCreated->condHasEl
condHasEl(yes)->condHasTemp
condHasEl(no)->opVm.$mountedCall->condHasTemp
opCompileTempIntoRender=>operation: Compile template into render function*
opCompileElOutHtmlAsTemp=>operation: Compile el's outerHTML as template*
opCreateVm.$elAndReplace=>operation: Create vm.$el and replace 'el' with it
opMounted=>operation: Mounted
condDataChange=>condition: when data changes
opUpdate=>operation: Virtual DOM re-render and patch
condDestroy=>condition: when vm.$destroy() is called
opDestroy=>operation: Teardown watchers,child components and event listeners
condHasTemp(yes)->opCompileTempIntoRender->opCreateVm.$elAndReplace
condHasTemp(no)->opCompileElOutHtmlAsTemp->opCreateVm.$elAndReplace
opCreateVm.$elAndReplace->opMounted->condDestroy
condDestroy(yes)->opDestroy->e
condDestroy(no)->condDataChange
condDataChange(yes)->opUpdate
condDataChange(no)->opMounted