生命周期
概念
生命周期:把vue3.0的App从创建到销毁的过程
钩子函数:运行过程中的一些函数
vue3.0的生命周期主要分成四个阶段,分别是create、mount、update和destroy。详见如下图:
其中钩子函数还有:
activated
:被缓存的组件激活时调用deactivated
:被缓存的组件停用时调用errorCaptured
:捕获到来自子组件的异常时调用renderTracked
:虚拟DOM重新渲染的时候调用tenderTriggered
:虚拟DOM被触发渲染时调用
<template>
<div id="application">
<sub-com>
{{ content }}
</sub-com>
</div>
<button @click="change">测试</button>
</template>
<script>
const sub = {
beforeUpdate() {
console.log("组件即将更新前")
},
updated() {
console.log("组件更新完成")
},
renderTracked({key, target, type}) {
console.log("虚拟DOM重新渲染时调用")
},
renderTriggered({key, target, type}) {
console.log("虚拟DOM被触发渲染时调用")
},
template:
<div>
<slot></slot>
</div>
}
const App = Vue.createApp({
data() {
return {
content: 0
}
},
methods: {
change(){
this.content += 1
}
},
})
App.component("sub-com", sub)
App.mount("#application")
</script>
钩子函数的使用
从vue中引入的生命周期在注册函数时,只能在setup方法中使用;且必须从vue中引入。
自定义指令
自定义指令解决的问题,或者说适用的场景是对普通DOM元素进行底层操作。所以不要盲目使用。
全局自定义指令
语法格式:
createApp(App).directive(‘自定义指令名称’,{ })
- 第一个参数是自定义指令名称,在声明的时候不要增加"v-"前缀,而在使用的时候需要增加
v-
前缀。 - 第二个参数是一个对象,也可以是定义的钩子函数,且这些钩子函数可以携带一些参数;其中
el
代表当前绑定自定义指令的DOM元素
局部自定义指令
全局定义的指令可以在框架中任何一个组件中使用。局部自定义指令只能在组件内进行使用,使用directives
进行注册。
directives:{
focus: {
mounted(el){
el.focus()
el.value="获取焦点"
}
}
}
自定义指令的钩子函数
区分上面的内容,上面的生命周期和钩子函数都是组件的,这里要说的钩子函数是指令的。
vue3.0提供以下钩子函数:
app.directive('directiveName', {
beforeMount(el){
// 指令绑定元素挂载前
},
mounted(el, binding){
// 指令绑定元素挂载后
},
beforeUpdate(el){
// 指令绑定元素数据修改前
},
updated(el){
// 指令绑定元素数据修改后
},
beforeUnmount(el){
// 指令绑定元素销毁前
},
unmounted(el){
// 指令绑定元素销毁后
},
})
参数说明:
- el:指令绑定的元素,可以用来操作dom元素
- binding:一个对象,拥有以下属性,但是除了对el进行操作外,其他都是只读的,属性如下:
- value:指令的绑定值
- oldValue:指定绑定的前一个值
- arg:传给指令的参数
- modifiers:一个包含修饰的对象
- vnode:Vue编译生成的虚拟节点
动态指令参数
格式:
v-mydirective:[argument]="value"
示例:
// main.js
import { createApp } from 'vue'
import App from './components/AllComp.vue'
const app = createApp(App)
app.directive('direct', {
mounted(el, binding){
el.style.position = 'fixed'
const s =binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
updated(el, binding){
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
})
<!-- AllComp.vue -->
<template>
<div>
<h2>滚动定位页面</h2>
<input type="range" max="1000" min="0" v-model="pinPadding" />
<p v-direct:[direction]="pinPadding">页面被定位到离本页{{ direction }}端{{ pinPadding }}像素</p>
</div>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default{
setup(){
const state = reactive({
direction: 'right',
pinPadding: 200
})
return {
...toRefs(state)
}
}
}
</script>
模态框
Teleport能够直接将组件渲染到页面中的任何地方,只要通过to属性指定渲染的目标对象即可。
<template>
<button @click="openModalHandle">使用Teleport全屏打开模态框</button>
<teleport to="body">
<div v-if="modalOpen" class="modal">
这是Teleported模态框
<button @click="closeModalHandle">Close</button>
</div>
</teleport>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default{
setup(){
const state = reactive({
modalOpen: false
})
const openModalHandle = ()=> {
state.modalOpen = true
}
const closeModalHandle = ()=> {
state.modalOpen = false
}
return {
...toRefs(state),
openModalHandle,
closeModalHandle
}
}
}
</script>