CompositionAPI生命周期函数新写法
【例子】
const app = Vue.createApp({
setup() {
// beforMount => onBeforeMount 当Vue实例即将挂载到页面时自动执行的函数
// mounted => onMounted 当Vue实例挂载到页面时自动执行的函数
// beforUpdate => onBeforUpdate 当数据发生变化页面重新渲染前自动执行的函数
// updated => onUpdated 当数据发生变化后页面重新渲染后自动执行的函数
// beforeUnmount => onBeforeUnmount 当组件即将从页面上移出的时候自动执行的函数
// unmounted => onUnmounted 当组件从页面上移出之后自动执行的函数
// onRenderTracked`指的是在收集响应式依赖时自动执行的函数
// onRenderTrigger 指的是页面重新渲染被触发时自动执行的函数
const { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onRenderTracked, onRenderTriggered} = Vue
const name = ref('LeBrown')
const handleClick = () => {
name.value = "James"
}
onBeforeMount(()=>{
console.log('onBeforeMount');
})
onMounted(()=>{
console.log('onMounted');
})
onBeforeUpdate(()=>{
console.log('onBeforUpdate');
})
onUpdated(()=>{
console.log('onUpdated');
})
onRenderTracked(()=>{
console.log('onRenderTracked');
})
onRenderTriggered(()=>{
console.log('onRenderTriggered');
})
return {name,handleClick}
},
template: `
<div @click = "handleClick">
{{name}}
</div>
`
})
const vm = app.mount('#root')
【备注】
- 由于
setup
函数的执行时间就是处于brforeCreate
和created
之间,因此如果要在这两个钩子函数中写的逻辑直接写在stup
中就可以了,所以CompositionAPI
中没有与brforeCreate
和created
钩子函数对应函数的新写法 CompositionAPI
中提供了新的生命周期函数,如:onRenderTracked
指的是在收集响应式依赖时自动执行的函数(首次就执行且每次重新渲染到都会重新收集下依赖);onRenderTriggered
指的是只有在页面重新渲染被触发时自动执行的函数(惰性,首次不执行,内容发生变化才执行)
Provide、Inject
【例1】
const app = Vue.createApp({
setup() {
const { provide } = Vue
provide('name', 'leBrown')
return {}
},
template: `
<div>
<child />
</div>
`
})
app.component('child', {
setup() {
const { inject } = Vue
const name = inject('name','hello')
return {name}
},
template: `
<div>
{{name}}
</div>
`
}
)
const vm = app.mount('#root')
【备注】
- 如果父组件没有使用
provide
传值给子组件,那么inject
的第二个参数表示默认值,如例子中的hello
就是name的默认值 Provide
不仅可以适用于父子组件的传值,而且它适合多层嵌套组件之间的传值
【例2: 子组件改变父组件传递过来的值】
需求: 点击子组件中的值,改变父组件传递过来的值
const app = Vue.createApp({
setup() {
const { provide, ref, readonly } = Vue
const name = ref('leBrown')
// 使用readonly封装后再传给子组件
provide('name', readonly(name))
// 修改父组件中的数据并传递方法给子组件
provide('changeName', (value) => {
name.value = value
})
return {}
},
template: `
<div>
<child />
</div>
`
})
app.component('child', {
setup() {
const { inject } = Vue
const name = inject('name')
// 子组件接收父组件传递过来的方法
const changeName = inject('changeName')
const handleClick = () => {
// 调用父组件传递过来的方法并传值
changeName('James')
}
return { name, handleClick }
},
template: `
<div @click="handleClick">{{name}}</div>
`
})
const vm = app.mount('#root')
【备注】
-
由于vue中有单向数据流,因此父组件传递过来的数据,如果子组件想要修改,子组件不可以直接修改,而是应该子组件通知父组件,由父组件去修改,即谁提供的数据就在就由谁修改数据。实现的方法就是,在父组件中定义一个修改值的函数,父组件通过
provide
将这个函数传给子组件,子组件通过inject
调用函数并传参,就可以修改父组件中的数据了 -
如何避免不小心在子组件中直接修改了父组件传递过来的值呢?
==> 使用关键字readonly
将传给子组件的值变成只读,再传给子组件,这样父组件传给子组件的值,子组件就没法直接修改了 -
为什么子组件通过调用父组件传递过来的
changeName
可以修改变量name
呢?因为changeName
中修改的是name
,而传给子组件的name是包装过的只读的name
模板Ref
【例子:使用CompositionAPI获取真实DOM元素节点
】
const app = Vue.createApp({
setup() {
const { ref, onMounted } = Vue
// 定义空的响应式对象hello,这个名字要和模板中引用DOM的ref的名字hello要一样
const hello = ref(null)
onMounted(() => {
console.log(hello.value)
})
return {hello}
},
template: `
<div>
<div ref="hello">Hello World</div>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
【备注】
-
这里的
Ref
是获取DOM节点的引用,而不是获取响应式引用的Ref
,上面的例子是要使用DOM的fef和获取响应式引用的ref配合使用,来获取真实DOM元素节点 -
定义空的响应式对象hello,这个名字要和模板中引用DOM的ref的名字hello要一样,实际上空的响应式对象hello保存的就是ref为hello的div的DOM引用了
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END