Vue实例构造器
Vue实例通过构造函数Vue来构建,传入一个对象作为参数
let vm=new Vue({
//...
})
Vue实例的属性和方法
在Vue中不提倡使用DOM来操作元素,更多的是通过Vue实例来进行各种操作,每个Vue实例都会代理data对象中的属性,在实例创建时其上的属性是响应的,其后添加的属性不是响应的,我们可以通过Vue实例中的data对象中的属性值来设置某些元素的值。
Vue实例中通过el来指定操作的DOM元素。
<div id="app">
<p>{{msg}}</p>
</div>
let vm = new Vue({
el:'#app',
data:{
msg:'vue'
}
});
最后页面中会显示vue,即msg指向了data中的msg属性的值。
Vue实例中的methods对象用于定义方法,在methods对象中的方法使用this可以指向data对象,即可以调用data对象中的属性
<div id="app">
<p @click="fn">{{msg}}</p>
</div>
let vm = new Vue({
el:'#app',
data:{
msg:'vue'
},
methods:{
fn(){
console.log(this.msg);
}
}
});
这里在p标签上绑定了点击事件,当点击p标签时,就会在控制台打印vue。
Vue实例生命周期
取自http://doc.vue-js.com/v2/guide/instance.html
对上面的图片流程分几个部分来解析
实例的初始化
首先,实例的初始化是通过new Vue({})来实现的,这样会构建一个空的Vue实例
let vm=new Vue({});
顺着箭头往下,在创建Vue实例后,会首先执行一个beforeCreate函数,该函数执行时,data(数据)和Events(事件,方法)还没被定义。
let vm = new Vue({
el: "#app",
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
beforeCreate() {
console.log(this.msg); // undefined
this.fn(); // 报错
}
});
如上代码,在执行beforeCreate函数时,打印出来的会是undefined,而调用fn()会报错。这是因为data(数据)和Events(事件,方法)是在执行该函数后才被定义。
定义完data和Events后,就会执行created函数,该函数是Vue实例创建后第一个可以访问data和methods的函数。
let vm = new Vue({
el: "#app",
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
created() {
console.log(this.msg); // 1
this.fn(); // fn
}
});
模板的编辑
进入模板的编辑,首先查看Vue实例中是否有el,如果有则查看是否有template(模板),如果没有template,则把el指向的内容编译为模板进行操作,如果有template,则直接使用该模板进行操作。下面两段代码结果是相同的
有template
<div id="app"></div>
<script>
let vm = new Vue({
el: "#app",
template: `<div>{{msg}}</div>`,
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
created() {
console.log(this.msg);
this.fn();
}
});
</script>
无template
<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
created() {
console.log(this.msg);
this.fn();
}
});
</script>
要注意的是,在这一部分中,Vue对代码中的指令进行执行,然后生成一个编译好的模板字符串,将这个模板字符串喧染成内存中的DOM,但没有把模板挂载到真正的页面中去。在挂载之前,还会执行一个beforeMount函数
模板到页面的渲染
经过上面的步骤后,模板只是在内存中编译好了,但未正式渲染到页面上,关于渲染到页面上也有两个钩子函数在其前后。
beforeMount是在渲染之前执行的,而mounted是在渲染完成后执行的,即在beforeMount执行时无法获取渲染后的内容。
<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
beforeMount() {
console.log(this.msg); // 1
console.log(document.getElementById('app').innerHTML); // {{msg}}
},
mounted() {
console.log(this.msg); // 1
console.log(document.getElementById('app').innerHTML); // 1
}
});
</script>
执行后发现在beforeMount中的第二条语句打印出来的结果是{{msg}},这正是因为页面还没把Vue实例中的数据渲染上去。
当mounted执行完毕时,Vue实例的初始化就结束了,即已经脱离了创建的阶段,进入了运行阶段
实例中数据的更新
在进入了运行阶段后,主要就是Vue实例中数据的更新,在更新Vue实例中的数据时就会触发beforeUpdate和updated两个钩子函数,要注意的是这两个函数都是在数据更新后才会被执行的,如果在Vue实例创建到销毁这段时间里数据没有被修改过,那么这两个函数永远不会被执行。
beforeUpdate执行时数据虽然已经更新了,但是仍未渲染到页面上,updated执行时DOM数的重新渲染和挂载就都完成了。
<div id="app">
<p id="data">{{msg}}</p>
<input type="button" value="修改数据" @click="msg='2'">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: '1'
},
methods: {
fn: () => {
console.log('fn');
}
},
beforeUpdate() {
console.log(`Vue实例中的数据:${this.msg}`); // Vue实例中的数据:2
console.log(`页面上的内容:${document.getElementById('data').innerHTML}`); // 页面上的内容:1
},
updated() {
console.log(`Vue实例中的数据:${this.msg}`); // Vue实例中的数据:2
console.log(`页面上的内容:${document.getElementById('data').innerHTML}`); // 页面上的内容:2
}
});
</script>
在控制台打印后可以看到,在beforeUpdate执行时虽然msg已经变为2了,但是页面中还是为1,此时页面还没有进行重渲染,在updated执行时,页面的重渲染才正式完成。
实例的销毁
实例在运行阶段如果数据没有更新会一直停留在mouted状态,当实例被销毁时,会触发beforeDestroy和destroyed两个钩子函数。
在执行beforeDestroy时,实例还是可以使用的,但如果到了执行destroyed时,实例上所有的组件和监听器都会无效,包括子实例也会被销毁,事件的绑定也会无效了。
使用上面的代码,在控制台中运行vm.$destroy()就会执行这两个钩子函数了。
这就是我学习理解的Vue实例的构建和Vue实例生命周期,有什么出错请大佬指出