vue官网给出的流程图传送门
https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
实例创建以前调用的 beforeCreate
实例创建以后调用的 created
dom节点挂载到页面以前 beforeMount
dom节点挂载到页面之后 mounted
改数据的时候会调用这一对
beforeUpdate
updated
数据销毁的时候 会调用这一对
beforeDestroy
destroyed
————————————————————分割线————————————————————
以下演示会让老手看着很不爽 代码冗余严重 但是我为了表达清楚不惜耗费笔墨 牺牲一点 新手会看得很明白。具体为什么写这个顺序,参照刚给你们的官网流程图。有一位csdn的朋友也写了一篇不错的个人理解,但没得到他本人允许我没进行转载,这里面只写我个人理解方式。
一步步演示:读者可以和我一起做
新建life.html
(前面需要引入vue.js 这个不用我说了吧!)
<body>
<div id="box">
</div>
<script>
new Vue({
el:"#box",
data:{
flag:false
},
beforeCreate(){
console.log(this.flag);
},
methods:{
}
})
</script>
</body>
由此得出beforeCreate此时还没有实例化,数据是访问不到的,这个不是很常用。
<div id="box">
{{curIndex}}
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false
},
beforeCreate(){
},
created(){
this.flag=true;
console.log(this.flag);
},
methods:{
}
})
</script>
由此得出此时实例被创建以后调用的created能够拿到数据,而且能对数据进行修改。
但是这里有一点说明,在这里进行修改数据不会触发beforeUpdate和updated钩子函数。(可以再这个钩子函数发请求访问后端接口拿数据) 修改的数据必须是渲染在页面上的,不然不论是否能触发这两个钩子函数的都不会触发。所以特意新写了一个。
<body>
<div id="box">
{{curIndex}}
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false
},
beforeCreate(){
},
created(){
this.curIndex=8;
console.log(this.curIndex);
},
updated(){
console.log('updated');
},
methods:{
}
})
</script>
</body>
数据被成功修改,updated函数没有被执行。
beforeMount
编译模板已经结束 虚拟dom已经存在 可以访问数据 也可以更改数据 而且在这里面修改数据不会触发beforeUpdate和updated钩子函数。
<body>
<div id="box">
{{curIndex}}
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false
},
beforeCreate(){
},
created(){
},
beforeMount(){
this.curIndex=8;
console.log(this.curIndex);
},
updated(){
console.log('updated');
},
methods:{
}
})
</script>
</body>
结果和上一个相同。
注意:事实上beforeMount和mounted之间有一个render函数,但是最好不要自己去动人家系统的东西,它默认是渲染我们给出的odom元素,不做赘述。
接下来是mounted 此时dom节点挂载到了页面上,有了真是的dom节点,可以对节点进行操作了,Vue有自己的渲染节点的方法。
用实例的$refs找到ref表示的节点 可以访问和更改数据 修改页面上渲染的数据会触发beforeUpdate和updated钩子函数
<body>
<div id="box">
{{curIndex}}
<input type="text" ref='txt' />
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false
},
beforeCreate(){
},
created(){
},
beforeMount(){
//console.log(this.curIndex);
},
mounted(){
this.$refs.txt.focus();
this.curIndex=8;
},
updated(){
console.log('updated');
},
methods:{
}
})
</script>
</body>
接下来再单独说说update这一对,不要在update beforeUpdate里面修改数据 比如上面这种 += 会引起死循环
作用:可以监听数据的变化 而且是对于data里面所有数据的变化都能监听
做个小例子 监听一下颜色变化
<body>
<div id="box">
{{curIndex}}
<p :style="{background:'rgb('+r+','+g+','+b+')'}">123</p>
<input type="text" ref='txt' />
<input type="text" v-model="r">
<input type="text" v-model="g">
<input type="text" v-model="b">
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false,
r:0,
g:0,
b:0
},
beforeCreate(){
},
created(){
},
beforeMount(){
//console.log(this.curIndex);
},
mounted(){
this.$refs.txt.focus();
this.curIndex=8;
},
updated(){
console.log('updated');
},
methods:{
}
})
</script>
</body>
稍作修改。
<body>
<div id="box">
{{curIndex}}
<p :style="{background:ys}">123</p>
<input type="text" ref='txt' />
<input type="text" v-model="r">
<input type="text" v-model="g">
<input type="text" v-model="b">
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false,
r:0,
g:0,
b:0,
ys:''
},
beforeCreate(){
},
created(){
},
beforeMount(){
//console.log(this.curIndex);
},
mounted(){
this.$refs.txt.focus();
this.curIndex=8;
},
updated(){
console.log('updated');
this.ys='rgb('+this.r+','+this.g+','+this.b+')'
},
methods:{
}
})
</script>
</body>
这个说好也不好,他可以监听所有的data变化,但是如果我只想监听一个特定的值,我们可以换一个方法,watch(),专门用来监听特定值的变化。
用watch只监听curIndex的变化,注意写法。
<body>
<div id="box">
{{curIndex}}
<p :style="{background:ys}">123</p>
<input type="text" ref='txt' />
<input type="text" v-model="r">
<input type="text" v-model="g">
<input type="text" v-model="b">
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false,
r:0,
g:0,
b:0,
ys:''
},
beforeCreate(){
},
created(){
},
beforeMount(){
//console.log(this.curIndex);
},
mounted(){
this.$refs.txt.focus();
this.curIndex=8;
},
updated(){
console.log('updated');
this.ys='rgb('+this.r+','+this.g+','+this.b+')'
},
methods:{
},
watch:{
curIndex(newV,oldV){
console.log(newV,oldV);
}
}
})
</script>
</body>
还有需要注意的是,如果想监听对象,用监听函数的方法是监听不到对象的变化的。
写一个对象,测试一下,加的比较少,就不粘贴全部代码了。
在页面修改值 测试一下 并没有输出111111
写成对象格式
定义一个定时器看看。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
{{curIndex}}
<p :style="{background:ys}">123</p>
<input type="text" ref='txt' />
<input type="text" v-model="r">
<input type="text" v-model="g">
<input type="text" v-model="b">
<input type="text" v-model="obj.n"/>
<button @click="kill">卸载</button>
</div>
<script>
new Vue({
el:"#box",
data:{
curIndex:0,
flag:false,
r:0,
g:0,
b:0,
ys:'',
obj:{
n:7
},
timer:''
},
beforeCreate(){
},
created(){
},
beforeMount(){
//console.log(this.curIndex);
},
mounted(){
this.$refs.txt.focus();
this.curIndex=8;
this.timer=setInterval(()=>{
console.log("11111")
},1000);
},
updated(){
console.log('updated');
this.ys='rgb('+this.r+','+this.g+','+this.b+')'
},
beforeDestroy(){
clearInterval(this.timer);
console.log('beforeDestroy');
},
destroyed(){
console.log('destroyed');
},
methods:{
kill(){
this.$destroy();
}
},
watch:{
curIndex(newV,oldV){
console.log(newV,oldV);
},
obj:{
handler(newV,oldV){
console.log(newV,oldV,"object change");
},
deep:true,
immediate:true
}
}
})
</script>
</body>
</html>
还有两个不太常用的activated和deactivated,这两个要配合keep-alive去用。
activated是缓存组件的时候调用
deactivated是缓存的组件卸载的时候调用(没激活的时候)