《vue基础学习-组件》提到组件传递数据方式:
1. props/$emit
- 父传子:子组件通过
props
显式声明 自定义 属性,接收父组件的传值。 - 子传父:子组件通过
$emit()
显式声明 自定义 事件,父组件调用自定义事件接收子组件返回的参数。
2. $ref / $parent
- 父传子:父组件的方法中通过
this.$refs
访问子组件的引用。 - 子传父:子组件中通过
this.$parent.$refs
访问父组件的引用。
本节将主要介绍组件调用中涉及的生命周期钩子。
1. <componet :is=“组件名” >
在 Vue.js 中,你可以使用 <component>
元素结合 :is
属性来动态地切换组件。这种方式非常灵活,可以根据数据的变化来渲染不同的组件。
<template><div><button @click="currentComponent = 'ComponentA'">Show Component A</button><button @click="currentComponent = 'ComponentB'">Show Component B</button><component :is="currentComponent"></component></div>
</template><script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';export default {components: {ComponentA,ComponentB},data() {return {currentComponent: 'ComponentA'};}
};
</script>
<component :is="currentComponent"></component>
:这里使用了<component>
元素,并通过:is
绑定一个变量currentComponent
。currentComponent
的值决定了要渲染哪个组件。currentComponent
:这是一个响应式的数据属性,初始值为'ComponentA'
。当点击按钮时,这个值会被更新,从而触发组件的切换。
假设你有两个组件 ComponentA.vue
和 ComponentB.vue
:
ComponentA.vue
<template><div><h1>Component A</h1><p>This is Component A</p></div>
</template><script>
export default {name: 'ComponentA'
};
</script>
ComponentB.vue
<template><div><h1>Component B</h1><p>This is Component B</p><p>Count: {{ count }}</p><p>Double Count: {{ doubleCount }}</p><button @click="increment">Increment</button></div>
</template><script>
export default {name: 'ComponentB',data() {return {count: 0};},computed: {doubleCount() {return this.count * 2;}},methods: {increment() {this.count++;}}
};
</script>
点击 “Show Component A”
,加载组件 ComponentA
:
点击 “Show Component B”
,加载组件 ComponentB
:
点击 “increment”
,数值改变:
但如果点击 “Show Component A”
后,再点击 “Show Component B”
,组件 ComponentB
状态没有保存:
如果你希望在切换组件时保留组件的状态,可以使用 <keep-alive>
包裹 <component>
。
2. <keep-alive>
在 Vue.js 中,<keep-alive>
是一个内置组件,用于缓存组件实例,以避免重复渲染和销毁。
<template><div><button @click="currentComponent = 'ComponentA'">Show Component A</button><button @click="currentComponent = 'ComponentB'">Show Component B</button><keep-alive><component :is="currentComponent"></component></keep-alive></div>
</template><script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';export default {components: {ComponentA,ComponentB},data() {return {currentComponent: 'ComponentA'};}
};
</script>
这样,即使组件被切换,它们的状态也会被保留。
点击 “Show Component A”
后,再点击 “Show Component B”
,组件 ComponentB
状态不变:
总结:
- 使用
<component :is="组件名"></component>
可以动态地切换组件。 - 结合
<keep-alive>
可以保留组件的状态。 - 通过改变
:is
绑定的变量值来控制显示哪个组件。
3. activated()
在 Vue.js 中,activated
和 deactivated
是 Vue 组件的 生命周期钩子,主要用于 <keep-alive>
包裹的组件。
activated
:当组件被 激活 时调用。这通常发生在组件从缓存中恢复并重新显示时。deactivated
:当组件被 停用 时调用。这通常发生在组件被隐藏并放入缓存时。
ComponentB.vue
<template><div><h1>Component B</h1><p>This is Component B</p><p>Count: {{ count }}</p><p>Double Count: {{ doubleCount }}</p><button @click="increment">Increment</button></div>
</template><script>
export default {name: 'ComponentB',data() {return {count: 0};},computed: {doubleCount() {return this.count * 2;}},methods: {increment() {this.count++;}},activated() {console.log('Component activated');},deactivated() {console.log('Component deactivated');}
};
</script>
点击 “Show Component B”
,加载组件 ComponentB
,打印 Component activated
:
点击 “Show Component A”
,加载组件 ComponentA
,打印 Component deactivated
:
再次点击 “Show Component B”
,加载组件 ComponentB
,打印 Component activated
:
注意:
- 生命周期钩子
activated
和deactivated
必须和<keep-alive>
结合使用才生效。
4. 生命周期钩子
在 Vue.js 中,生命周期钩子(Lifecycle Hooks)是一些特定的函数,你可以在这些函数中执行自定义逻辑。Vue 组件从创建到销毁的过程中会经历一系列的阶段,每个阶段都有相应的钩子函数可以让你插入自定义代码。
Vue 2 和 Vue 3 的生命周期钩子有一些差异。Vue 3 引入了一些新的生命周期钩子,并对一些旧的钩子进行了重命名。
- Vue 2 生命周期钩子
- 创建阶段:
beforeCreate
:在实例初始化之后,数据、事件配置之前被调用。created
:在实例创建完成后被调用。此时实例已完成数据、事件配置。但是挂载阶段还没开始,$el
属性目前不可见。
- 挂载阶段:
beforeMount
:在挂载开始之前被调用。相关的render
函数首次被调用。mounted
:在实例挂载到 DOM 之后被调用。
- 更新阶段:
beforeUpdate
:在数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM。updated
:在数据更新后调用,此时 DOM 已经更新。可以在这里执行依赖于 DOM 的操作。
- 销毁阶段:
beforeDestroy
:在实例销毁之前调用。在这一步,实例仍然完全可用。destroyed
:在实例销毁后调用。此时所有的事件监听器都被移除,所有的子实例也都被销毁。
- 其他钩子:
activated
:在keep-alive
组件激活时调用。deactivated
:在keep-alive
组件停用时调用。errorCaptured
:捕获一个来自后代组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
- 创建阶段:
- Vue 3 生命周期钩子
- 创建阶段:
setup()
:在 Vue 3 中,beforeCreate
和created
钩子被setup
函数取代。
- 挂载阶段:
beforeMount
:在挂载开始之前被调用。mounted
:在实例挂载到 DOM 之后被调用。
- 更新阶段:
beforeUpdate
:在数据更新时调用,发生在虚拟 DOM 打补丁之前。updated
:在数据更新后调用,此时 DOM 已经更新。
- 销毁阶段:
beforeUnmount
:代替beforeDestroy
。unmounted
:代替destroyed
。
- 其他钩子:
onActivated
:代替activated
。onDeactivated
:代替deactivated
。onErrorCaptured
:代替errorCaptured
。
- 创建阶段:
5. 常用生命周期钩子及使用场景
5.1 created
created
钩子在实例创建完成后被调用。此时实例已完成数据、事件配置。但是挂载阶段还没开始,$el
属性目前不可见。
典型用例:
- 初始化数据。
- 发起网络请求获取初始数据。
- 设置事件监听器。
export default {created() {console.log('Component is created');this.fetchData();},methods: {fetchData() {// 发起网络请求,获取初始数据。}}
};
5.2 mounted
mounted
钩子在实例挂载到 DOM 之后被调用。
典型用例:
- 操作 DOM。
- 初始化第三方库(如 jQuery 插件)。
- 启动定时器或动画。
export default {mounted() {console.log('Component is mounted');this.initThirdPartyLibrary();},methods: {initThirdPartyLibrary() {// 初始化第三方库}}
};
5.3 beforeUpdate
典型用例:
- 在数据更新前保存当前状态。
- 清理无效的数据或状态。
5.4 updated
典型用例:
- 操作更新后的 DOM。
- 更新 UI 状态。
5.5 beforeDestroy、beforeUnmount
典型用例:
- 清理定时器。
- 取消网络请求。
- 移除事件监听器。
5.6 destroyed、unmounted
典型用例:
- 最终清理工作。
- 记录日志。
完整示例 Lifecycle.vue:
<template><div><h1>{{ message }}</h1><button @click="updateMessage">Update Message</button><h1>{{ count }}</h1><button @click="increment">Increment</button></div>
</template><script>
export default {data() {return {message: 'Hello, Vue 3!',count: 0}},methods: {updateMessage() {this.message = 'Message Updated!';},increment() {this.count++;}},created() {console.log('Component is created');console.log(this.message);},mounted() {console.log('Component is mounted');console.log(this.message);},beforeUpdate() {// 在更新前保存当前状态console.log(this.message);console.log('Before update, current count:', this.count);console.log('onBeforeUpdate called');},updated() {// 更新后的操作console.log(this.message);console.log('After update, new count:', this.count);console.log('onUpdated called');},beforeDestroy() {// 清理资源console.log('onBeforeUnmount called');},destroyed() {// 最终清理console.log('onUnmounted called');}
};
</script><style scoped>
/* 添加一些样式 */
h1 {color: blue;
}
</style>
总结:
created
:初始化数据和设置事件监听器。mounted
:操作 DOM 和初始化第三方库。beforeUpdate
:在数据更新前保存状态。updated
:操作更新后的 DOM。beforeUnmount
/beforeDestroy
:清理资源。unmounted
/destroyed
:最终清理工作。