目录
生命周期
自定义hook函数
toRef
shallowReactive与shallowRef
readonly与shallReadonly
toRaw与markRaw
生命周期
Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但是有两个被更名:Vue2中的beforeDestroy改名为:beforeUnmount;Vue2中的destroyed改名为:unmounted。由原来的挂载到销毁变成现在的挂载到卸载。
总的来说,变化虽然有但是不大;Vue2的生命周期讲解可参考:Vue2生命周期讲解 。Vue3官方给的生命周期图示如下:
根据代码来去实现它的过程:
<template>
<h2>现在的数值是:{{ num }}</h2>
<button @click="num++">点我加1</button>
</template>
<script>
import {ref} from 'vue'
export default {
name:'Mydemo',
setup(){
let num = ref(0)
return {
num
}
},
// 通过配置项的形式使用生命周期钩子
beforeCreate() {
console.log('---beforeCreate---');
},
// 当组件在内存中被创建完毕之后,会自动调用created函数
created(){
console.log('---created---');
},
beforeMount(){
console.log('---beforeMount---');
},
// 当组件被成功的渲染到页面上之后,会自动调用mounted函数
mounted(){
console.log('---mounted---');
},
beforeUpdate(){
console.log('---beforeUpdate---');
},
// 当组件被重新渲染完毕之后,会自动调用updated函数。
updated(){
console.log('---updated---');
},
beforeUnmount(){
console.log('---beforeUnmount---');
},
// 当组件被卸载完毕之后,会自动调用unmounted函数
unmounted(){
console.log('---unmounted---');
}
}
</script>
通过App根组件去导入注册该组件,通过按钮的切换来实现组件的创建与销毁过程:
<template>
<button @click="isShowDemo = !isShowDemo">切换显示与隐藏</button>
<Demo v-if="isShowDemo"></Demo>
</template>
<script>
import {ref} from 'vue'
import Demo from './components/test/demo.vue'
export default {
name:'MyApp',
components:{
Demo
},
setup(){
let isShowDemo = ref(true)
return{
isShowDemo
}
},
}
</script>
当然,Vue3.x也提供了Composition API形式的生命周期钩子,与Vue3.0中配置项钩子对应关系如下:
beforeCreate与created 两者就相当于 setup()
beforeMount 相当于 onBeforeMount ;mounted 相当于 onMounted
beforeUpdate 相当于 onBeforeUpdate ;updated 相当于 onUpdated
beforeUnmount 相当于 onBeforeUnmount ;unmounted 相当于 onUnmounted
这些生命周期的钩子都是函数,如果你想在 setup 中去使用的话,肯定的是需要去从vue中按需导入的,和ref一样。如下:
这里可能会有人有想法了,我能不能同时在配置项里和setup的组合式API里 ,同时使用生命周期钩子,好吧,如果你这么干了,你可能就会发现这么一个现象,在setup中的组合式API里调用的生命周期钩子的执行时机是比配置项里面的生命周期钩子快的。但是我们正常开发来说,要么就在配置项里写,要么就在setup里面写。同时写的人感觉是挺无聊的。鱿鱼须:你有我了解Vue?行,只要你不嫌麻烦,随你!
自定义hook函数
hook本质上是一个函数,把setup函数中使用的Composition API进行了封装,类似 Vue2.x 中的mixin,其优势在于:复用代码,让setup中的逻辑更加清楚易懂。
我们在外部声明了一个js函数方法,只要程序员有需要,就只要引入该文件,使用该方法即可。
import {onMounted, reactive, onBeforeUnmount} from 'vue'
export default function(){
// 数据
let point = reactive({
x:0,
y:0
})
// 坐标方法
function showPoint(event){
point.x = event.pageX
point.y = event.pageY
console.log(event.pageX,event.pageY);
}
onMounted(()=>{
window.addEventListener('click',showPoint)
})
onBeforeUnmount(()=>{
window.removeEventListener('click',showPoint)
})
// 将得到的数据给返回出去
return point
}
引入该文件进行使用:
<template>
<h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{ point.y }}</h2>
</template>
<script>
// 引入
import usePoint from '../hook/hook.js'
export default {
name:'Mydemo',
setup(){
let point = usePoint()
return {
point
}
},
}
</script>
toRef
创建一个ref对象,其value值指向另一个对象中的某个属性。主要用于将响应式对象中的某个属性单独提供给外部使用。
所以接下来,我们把这些响应式对象中的数据属性单独叉出来,通过toRef进行调理:
有人觉得,这种不是更麻烦了吗?还不如一层层将数据点出来了呢,别急,toRef只是负责单个对象属性,如果项目中对象数据成百上千可能效率很低,我们可以使用 toRefs ,这种会负责一个对象数据中的多个属性数据处理,极大的方便了书写,如下:
shallowReactive与shallowRef
shallowReactive:只处理对象最外层属性的响应式(浅响应式)。如果有一个对象数据,结构比较深,但变化只是在外层变化,可以使用。节省了一些资源!
shallowRef:只处理基本数据类型的响应式,不进行对象处理。如果有一个对象数据,后续功能不会修改该对象中的属性,而是生成新的对象来替换,可以使用。
readonly与shallReadonly
readonly能让一个响应式数据变为只读的(深只读);shallowReadonly能让一个响应式数据变为只读的(浅只读)
这种方法一般应用场景是在引入别人组件时,调用的数据上来就设置只读的,为了避免把别人组件中的数据进行修改。
toRaw与markRaw
toRaw作用:是将一个由reactive生成的响应式对象转为普通对象。用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
markRaw作用:标记一个对象,使其永远不会再成为响应式对象。有些值不应被设置为响应式的,例如复杂的第三方类库等。当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。