每个Vue应用都是通过用Vue函数创建一个新的Vue实例开始的。
当创建一个Vue实例时,你可以传入一个选项对象。一个Vue应用由一个通过new Vue创建的根Vue实例,以及可选的嵌套的、可复用的组件树组成。
当一个 Vue 实例被创建时,它将 data
对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>数据与方法</title> <script src="../static/vue.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="app-8"> {{a}} </div> <script type="text/javascript"> var data = {a: 1} var vm = new Vue({ el: '#app-8', data: data }) // 获得这个实例上的 property,返回源数据中对应的字段 console.log(vm.a == data.a) // 设置 property 也会影响到原始数据 vm.a = 2 console.log(data.a) data.a = 3 console.log(vm.a) </script> </body> </html>
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data
中的 property 才是响应式的。
如果你知道你会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你仅需要设置一些初始值。比如:
data: { newTodoText: '', visitCount: 0, hideCompletedTodos: false, todos: [], error: null }
Object.freeze()会阻止修改现有的property,也就是意味着响应系统无法再追踪变化。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>数据与方法</title> <script src="../static/vue.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="app-9"> <p>{{foo}}</p> <button v-on:click="foo = 'abc'">change it</button> </div> <script type="text/javascript"> var obj = {foo: 'bar'} Object.freeze(obj) new Vue({ el: '#app-9', data: obj }) </script> </body> </html>
除了数据property,Vue实例还暴露了一些有用的实例property与方法。它们都有前缀$,以便与用户定义的 property 区分开来。例如:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>数据与方法</title> <script src="../static/vue.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="example"> {{a}} </div> <script type="text/javascript"> var data = {a: 1} var vm = new Vue({ el: '#example', data: data }) console.log(vm.$data === data) console.log(vm.$el === document.getElementById('example')) // $watch 是一个实例方法 vm.$watch('a', function (newVal, oldVal) { console.log("newVal = %s oldVal = %s", newVal, oldVal) }) </script> </body> </html>
每个Vue实例在被创建时都要经过一系列的初始化过程。例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>数据与方法</title> <script src="../static/vue.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="app"> {{msg}} </div> <script type="text/javascript"> var vm = new Vue({ el: "#app", data: { msg: "hi vue", }, //在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 beforeCreate: function () { console.log('beforeCreate'); }, //在实例创建完成后被立即调用。 //在这一步,实例已完成以下的配置:数据观测 (data observer),property和方法的运算,watch/event 事件回调。 //然而,挂载阶段还没开始,$el property目前尚不可用。 created: function () { console.log('created'); }, //在挂载开始之前被调用:相关的渲染函数首次被调用。 beforeMount: function () { console.log('beforeMount'); }, //实例被挂载后调用,这时el被新创建的vm.$el替换了,挂载成功。 //如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内。 mounted: function () { console.log('mounted'); }, //数据更新时调用,发生在虚拟 DOM 打补丁之前。 //该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。 beforeUpdate: function () { console.log('beforeUpdate'); }, //当这个钩子被调用时,组件DOM已经更新,组件更新完毕 updated: function () { console.log('updated'); }, //被keep-alive缓存的组件激活时调用。 activated: function () { console.log('activated'); }, //被keep-alive缓存的组件停用时调用。 deactivated: function () { console.log('deactivated'); }, //实例销毁之前调用。在这一步,实例仍然完全可用。 beforeDestroy: function () { console.log('beforeDestroy'); }, //实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 destroyed: function () { console.log('destroyed'); } }) </script> </body> </html>