组件生命周期钩子函数执行情况
- 初次挂载到第一个目标:
beforeCreate
:在实例初始化之后,数据观测(data observer)和事件配置之前被调用。
created
:实例已经创建完成之后被调用。在这一步,实例已完成数据观测、属性和方法的运算,$el属性还没有。
beforeMount
:在挂载开始之前被调用:相关的render函数首次被调用。
mounted
:实例被挂载后调用,这时$el
已被新创建的vm.$el
替换,并挂载到了实例上去。
- 切换到新目标:
beforeUnmount
:实例从当前目标卸载之前调用。在这一步,实例仍然完全可用。
unmounted
:实例从当前目标卸载后调用。该钩子被调用后,对应Vue组件实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被卸载。
- 然后在新目标上再次执行挂载相关钩子,即
beforeMount
和mounted
。
确保组件切换目标后正确传递和接收数据原理及方法
- 原理:
- Vue的响应式系统会跟踪数据的变化。当组件切换目标时,只要数据绑定正确,Vue会自动更新组件视图。对于父子组件间的数据传递,props是单向数据流,父组件更新props,子组件会响应变化。对于非父子组件间的数据传递,可以使用Vuex(状态管理库)、事件总线等方式。
- 方法:
- 使用props传递数据:父组件将数据通过props传递给Teleport包裹的子组件。子组件通过定义props来接收数据。
- 事件监听与回调:子组件可以通过
$emit
触发事件,父组件监听该事件并执行相应的回调函数,实现数据从子组件到父组件的传递。
- Vuex:如果应用比较复杂,可以使用Vuex管理状态。组件从Vuex的store中读取数据,并通过提交mutations或分发actions来更新数据,确保不同目标下组件数据的一致性。
示例代码
<template>
<div>
<button @click="changeTarget">切换目标</button>
<teleport :to="target">
<ChildComponent :data="parentData" @child-event="handleChildEvent"/>
</teleport>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
target: '#target1',
parentData: '初始数据'
};
},
methods: {
changeTarget() {
this.target = this.target === '#target1'? '#target2' : '#target1';
},
handleChildEvent(newData) {
this.parentData = newData;
}
}
};
</script>
<style scoped>
</style>
ChildComponent.vue
<template>
<div>
<p>{{data}}</p>
<button @click="sendDataToParent">发送数据到父组件</button>
</div>
</template>
<script>
export default {
props: ['data'],
methods: {
sendDataToParent() {
this.$emit('child - event', '子组件更新的数据');
}
}
};
</script>
<style scoped>
</style>
HTML 目标元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF - 8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Teleport示例</title>
</head>
<body>
<div id="app"></div>
<div id="target1">目标1</div>
<div id="target2">目标2</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="main.js"></script>
</body>
</html>