1 changed files with 454 additions and 1 deletions
@ -1 +1,454 @@
@@ -1 +1,454 @@
|
||||
# Vue sheng'm |
||||
# Vue 生命周期笔记 |
||||
|
||||
生命周期 |
||||
什么是生命周期? |
||||
一个实例从创建到销毁的一个过程。 |
||||
|
||||
vue初始化做了什么? |
||||
创建vue实例后,调用init方法,做了以下事情: |
||||
|
||||
// 初始化生命周期 |
||||
// |
||||
initLifecycle(vm) |
||||
|
||||
// 初始化事件中心 |
||||
initEvents(vm) |
||||
|
||||
// 初始化渲染 |
||||
initRender(vm) |
||||
callHook(vm, 'beforeCreate') |
||||
|
||||
// 初始化注入 |
||||
initInjections(vm) // resolve injections before data/props |
||||
|
||||
// 初始化状态 |
||||
// 初始化 props、data、methods、watch、computed 等属性 |
||||
initState(vm) |
||||
|
||||
initProvide(vm) // resolve provide after data/props |
||||
callHook(vm, 'created') |
||||
|
||||
// 在初始化最后,如果检测到有el属性,则调用函数挂载vm |
||||
if (vm.$options.el) { |
||||
vm.$mount(vm.$options.el); |
||||
} |
||||
复制代码 |
||||
有哪些生命周期?分别做了什么?生命周期的执行过程? |
||||
--> 首先创建一个vue实例,Vue(),然后执行初始化init()函数,初始化生命周期、事件中心、渲染; |
||||
|
||||
--> 然后调用beforeCreate:这里拿不到任何数据,数据观察(dataobserver)和事件配置(event/watcher)都没有准备好,没有数据,没有dom |
||||
|
||||
--> 初始化data数据,实现监听,初始化vue内部事件,进行属性和方法的计算。 |
||||
|
||||
--> 初始化完成,调用created:这里可以调用methods中的方法,修改data数据, 并且可触发computed重新计算,watch变更等。但是dom还没有挂载,无法访问$el。 |
||||
|
||||
--> 然后进行模板编译:将data的数据,和vue的模板语法编译成html,这里会分两种情况,1.是实例内部有模板属性,直接调用,然后用render函数渲染,2.是没有模板属性调用外部html |
||||
|
||||
--> 模板编译完成后,调用beforeMount:这里也可以拿到data数据,可以拿到el,且成功关联到了dom,但是此时的data,并没有渲染到页面中。 |
||||
|
||||
--> 然后执行render函数,将渲染的内容挂载到dom节点上 |
||||
|
||||
--> 挂载完毕,调用mounted:在这里,dom挂载完毕,data也已经渲染到页面中。mounted仅执行一次。 |
||||
|
||||
--> 数据发生变化,调用beforeUpdate:当检测到我们要修改数据的时候,就会触发beforeUpdate的钩子 |
||||
|
||||
--> 然后Vue会利用diff算法重新比较新的虚拟dom和旧的虚拟dom,对页面重新渲染。 |
||||
|
||||
--> 更新完成,执行updated:当修改vue的data时,vue会自动帮我们更新渲染视图,此时页面上是最新的数据, |
||||
|
||||
避免在这期间更改状态,可能会导致无限循环 钩子不常用,一般用computed,watch |
||||
|
||||
--> 在销毁之前触发,beforeDestroy:所有实例都可以用 |
||||
|
||||
--> 然后解除绑定,销毁子组件,事件监听器 |
||||
|
||||
--> 销毁完毕,调用destroyed:销毁之后,所有的事件监听器会被移除,所有的子实例也都会被销毁 |
||||
|
||||
|
||||
子组件的生命周期 |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Vue 实例</title> |
||||
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> |
||||
<script src='js/jquery.min.js'></script> |
||||
</head> |
||||
<body> |
||||
<div id="app"> |
||||
<v-sss></v-sss> |
||||
</div> |
||||
<script> |
||||
var app = new Vue({ |
||||
el: '#app', |
||||
data: { |
||||
name:0 |
||||
// someName:'zheli', |
||||
}, |
||||
components:{ |
||||
'v-sss':{ |
||||
'template':`<div>子组件</div>`, |
||||
beforeCreate(){ |
||||
console.log('子-->beforeCreate') |
||||
}, |
||||
created() { |
||||
console.log('子-->created') |
||||
}, |
||||
beforeMount(){ |
||||
console.log('子-->beforeMount') |
||||
}, |
||||
mounted(){ |
||||
console.log('子-->mounted') |
||||
}, |
||||
beforeUpdate(){ |
||||
console.log('子-->beforeUpdate') |
||||
}, |
||||
updated(){ |
||||
console.log('子-->updated') |
||||
}, |
||||
beforeDestroy(){ |
||||
console.log('子-->beforeDestroy') |
||||
}, |
||||
destroyed(){ |
||||
console.log('子-->destroyed') |
||||
} |
||||
} |
||||
}, |
||||
beforeCreate(){ |
||||
console.log('父-->beforeCreate') |
||||
}, |
||||
created() { |
||||
console.log('父-->created') |
||||
}, |
||||
beforeMount(){ |
||||
console.log('父-->beforeMount') |
||||
}, |
||||
mounted(){ |
||||
console.log('父-->mounted') |
||||
}, |
||||
beforeUpdate(){ |
||||
console.log('父-->beforeUpdate') |
||||
}, |
||||
updated(){ |
||||
console.log('父-->updated') |
||||
}, |
||||
beforeDestroy(){ |
||||
console.log('父-->beforeDestroy') |
||||
}, |
||||
destroyed(){ |
||||
console.log('父-->destroyed') |
||||
} |
||||
}) |
||||
</script> |
||||
</body> |
||||
</html> |
||||
复制代码 |
||||
没有显示和隐藏的情况下 |
||||
第一种情况: |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> mounted |
||||
|
||||
复制代码 |
||||
有v-if控制子组件的显示和隐藏。 |
||||
|
||||
v-if初始值为true,顺序同第一种情况 |
||||
v-if初始值为false,且一直不为true,子组件的生命周期不会触发。 |
||||
v-if初始值为false,在父组件的(created,beforeMount)生命周期变为true时,顺序同第一种情况 |
||||
v-if初始值为false,在父组件的(mounted)生命周期将变为true时,顺序如下: |
||||
第二种情况: |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
父 --> mounted |
||||
|
||||
父 --> beforeUpdate |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> updated |
||||
|
||||
复制代码 |
||||
有v-show控制子组件的显示和隐藏。 |
||||
|
||||
v-show初始值为true,顺序同第一种情况。 |
||||
v-show初始值为false,且一直不为true,顺序同第一种情况。 |
||||
v-show初始值为false,在父组件的(created,beforeMount)生命周期变为true时,顺序同第一种情况。 |
||||
v-show初始值为false,在父组件的(mounted)生命周期将变为true时,顺序如下: |
||||
第三种情况 |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> mounted |
||||
|
||||
父 --> beforeUpdate |
||||
|
||||
父 --> updated |
||||
|
||||
复制代码 |
||||
孙组件的生命周期 |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>Vue 实例</title> |
||||
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> |
||||
<script src='js/jquery.min.js'></script> |
||||
</head> |
||||
<body> |
||||
<div id="app"> |
||||
<v-sss v-show="isActive"></v-sss> |
||||
</div> |
||||
<script> |
||||
var app = new Vue({ |
||||
el: '#app', |
||||
data() { |
||||
return { |
||||
isActive:false |
||||
// someName:'zheli', |
||||
} |
||||
}, |
||||
components:{ |
||||
'v-sss':{ |
||||
'template':`<div>子组件<v-sonson></v-sonson></div>`, |
||||
components:{ |
||||
'v-sonson':{ |
||||
'template':`<div>孙儿组件</div>`, |
||||
beforeCreate(){ |
||||
console.log('孙-->beforeCreate') |
||||
}, |
||||
created() { |
||||
console.log('孙-->created') |
||||
}, |
||||
beforeMount(){ |
||||
console.log('孙-->beforeMount') |
||||
}, |
||||
mounted(){ |
||||
console.log('孙-->mounted') |
||||
}, |
||||
beforeUpdate(){ |
||||
console.log('孙-->beforeUpdate') |
||||
}, |
||||
updated(){ |
||||
console.log('孙-->updated') |
||||
}, |
||||
beforeDestroy(){ |
||||
console.log('孙-->beforeDestroy') |
||||
}, |
||||
destroyed(){ |
||||
console.log('孙-->destroyed') |
||||
} |
||||
} |
||||
}, |
||||
beforeCreate(){ |
||||
console.log('子-->beforeCreate') |
||||
}, |
||||
created() { |
||||
console.log('子-->created') |
||||
}, |
||||
beforeMount(){ |
||||
console.log('子-->beforeMount') |
||||
}, |
||||
mounted(){ |
||||
console.log('子-->mounted') |
||||
}, |
||||
beforeUpdate(){ |
||||
console.log('子-->beforeUpdate') |
||||
}, |
||||
updated(){ |
||||
console.log('子-->updated') |
||||
}, |
||||
beforeDestroy(){ |
||||
console.log('子-->beforeDestroy') |
||||
}, |
||||
destroyed(){ |
||||
console.log('子-->destroyed') |
||||
} |
||||
} |
||||
}, |
||||
beforeCreate(){ |
||||
console.log('父-->beforeCreate') |
||||
}, |
||||
created() { |
||||
|
||||
console.log('父-->created') |
||||
}, |
||||
beforeMount(){ |
||||
console.log('父-->beforeMount') |
||||
}, |
||||
mounted(){ |
||||
console.log('父-->mounted') |
||||
this.isActive = true |
||||
}, |
||||
beforeUpdate(){ |
||||
console.log('父-->beforeUpdate') |
||||
}, |
||||
updated(){ |
||||
console.log('父-->updated') |
||||
}, |
||||
beforeDestroy(){ |
||||
console.log('父-->beforeDestroy') |
||||
}, |
||||
destroyed(){ |
||||
console.log('父-->destroyed') |
||||
} |
||||
}) |
||||
</script> |
||||
</body> |
||||
</html> |
||||
复制代码 |
||||
没有显示和隐藏的情况下,子组件和孙组件都不隐藏 |
||||
第一种情况: |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
孙 --> beforeCreate |
||||
|
||||
孙 --> created |
||||
|
||||
孙 --> beforeMount |
||||
|
||||
孙 --> mounted |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> mounted |
||||
|
||||
复制代码 |
||||
子组件由v-if控制,孙组件无控制 |
||||
|
||||
v-if初始值为true,顺序同第一种情况 |
||||
v-if初始值为false,且一直不为true,子组件和孙组件的生命周期不会触发。 |
||||
v-if初始值为false,在父组件的(created,beforeMount)生命周期变为true时,顺序同第一种情况。 |
||||
v-if初始值为false,在父组件的(mounted)生命周期将变为true时,顺序如下: |
||||
第二种情况: |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
父 --> mounted |
||||
|
||||
父 --> beforeUpdate |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
孙 --> beforeCreate |
||||
|
||||
孙 --> created |
||||
|
||||
孙 --> beforeMount |
||||
|
||||
孙 --> mounted |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> updated |
||||
|
||||
复制代码 |
||||
子组件由v-show控制,孙组件无控制。 |
||||
|
||||
v-show初始值为true,顺序同第一种情况。 |
||||
v-show初始值为false,且一直不为true,顺序同第一种情况。 |
||||
v-show初始值为false,在父组件的(created,beforeMount)生命周期变为true时,顺序同第一种情况。 |
||||
v-show初始值为false,在父组件的(mounted)生命周期将变为true时,顺序如下: |
||||
第三种情况 |
||||
|
||||
父 --> beforeCreate |
||||
|
||||
父 --> created |
||||
|
||||
父 --> beforemount |
||||
|
||||
子 --> beforeCreate |
||||
|
||||
子 --> created |
||||
|
||||
子 --> beforeMount |
||||
|
||||
孙 --> beforeCreate |
||||
|
||||
孙 --> created |
||||
|
||||
孙 --> beforeMount |
||||
|
||||
孙 --> mounted |
||||
|
||||
子 --> mounted |
||||
|
||||
父 --> mounted |
||||
|
||||
父 --> beforeUpdate |
||||
|
||||
父 --> updated |
||||
|
||||
复制代码 |
||||
其实从上面看,就可以总结出来子孙组件的生命周期。 |
||||
|
||||
如果子组件被v-if控制,且初始值为false,那么子组件一开始就不会被渲染,没有执行生命周期。 |
||||
|
||||
如果子组件被v-if控制,且初始值为true,或者子组件被v-show控制,不论初始值,或者,子组件在父组件的created,beforemount阶段显示值为true,那么,子组件总是会在父组件beforemount之后开始执行生命周期。 |
||||
|
||||
如果子组件在父组件的mounted阶段被渲染出来,这里会分两种情况, |
||||
|
||||
第一种是v-show,因为v-show无论为true还是false,它都会存在dom节点,在父组件生命周期的beforemount之后,子组件已经开始执行自己的生命周期,直到父组件mounted阶段之后,这一轮生命周期已经完成,data已经有了,页面也已经渲染完毕。所以,当v-show的子组件变为true显示后,会触发父组件的更新函数。 |
||||
|
||||
第二种是v-if,因为v-if如果为false,是不会存在节点的,也就一开始不会显示,也就不会执行生命周期,所以,当v-if的子组件被渲染显示后,也会触发父组件的更新函数,不同的是,v-if子组件会在父组件的beforeupdate之后开始执行它的生命周期。 |
||||
|
||||
引申提问: |
||||
|
||||
Vue的beforeCreate钩子函数意义在哪里?我们可以在里面实现哪些特殊效果? |
||||
1.可以加载一些在页面渲染前出现的内容,比如loading动画 |
||||
|
||||
2.可以做页面拦截,和重定向。 |
||||
|
||||
Loading…
Reference in new issue