面试题答案
一键面试父子组件通信
- 父传子:
- 在父组件中,定义传递给子组件的数据。在子组件中,使用
props
接收并定义类型。 - 示例:
- 定义数据类型接口:
// 定义一个接口用于描述父传子的数据类型 interface ParentToChildProps { message: string; count: number; }
- 子组件:
<template> <div> <p>接收到的消息: {{ message }}</p> <p>接收到的数字: {{ count }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ParentToChildProps } from './types';// 假设接口定义在 types.ts 文件 export default defineComponent({ name: 'ChildComponent', props: { message: { type: String, required: true }, count: { type: Number, default: 0 } } as ParentToChildProps }); </script>
- 父组件:
<template> <div> <ChildComponent :message="parentMessage" :count="parentCount"/> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default defineComponent({ name: 'ParentComponent', components: { ChildComponent }, data() { return { parentMessage: 'Hello from parent', parentCount: 10 }; } }); </script>
- 定义数据类型接口:
- 在父组件中,定义传递给子组件的数据。在子组件中,使用
- 子传父:
- 子组件通过
$emit
触发事件并传递数据,父组件监听事件接收数据。需要定义事件传递数据的类型。 - 示例:
- 定义事件传递数据类型接口:
// 定义子传父事件传递数据的接口 interface ChildToParentEvent { (newValue: string): void; }
- 子组件:
<template> <button @click="sendDataToParent">发送数据给父组件</button> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ChildToParentEvent } from './types';// 假设接口定义在 types.ts 文件 export default defineComponent({ name: 'ChildComponent', methods: { sendDataToParent() { const data = 'Data from child'; this.$emit('child - to - parent', data); } } }); </script>
- 父组件:
<template> <div> <ChildComponent @child - to - parent="handleChildData"/> <p>接收到子组件的数据: {{ receivedData }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default defineComponent({ name: 'ParentComponent', components: { ChildComponent }, data() { return { receivedData: '' }; }, methods: { handleChildData(data: string) { this.receivedData = data; } } }); </script>
- 定义事件传递数据类型接口:
- 子组件通过
兄弟组件通信
- 通过事件总线(mitt 等库):
- 安装
mitt
:npm install mitt
- 定义事件传递数据类型。
- 示例:
- 定义事件类型接口:
// 定义兄弟组件间事件传递数据的接口 import mitt from'mitt'; type BroEvent = { 'brother - to - brother': string; }; const emitter = mitt<BroEvent>(); export default emitter;
- 发送数据的兄弟组件:
<template> <button @click="sendDataToBrother">发送数据给兄弟组件</button> </template> <script lang="ts"> import { defineComponent } from 'vue'; import emitter from './emitter';// 假设 emitter 定义在 emitter.ts 文件 export default defineComponent({ name: 'BrotherComponent1', methods: { sendDataToBrother() { const data = 'Data from brother 1'; emitter.emit('brother - to - brother', data); } } }); </script>
- 接收数据的兄弟组件:
<template> <div> <p>接收到兄弟组件的数据: {{ receivedData }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import emitter from './emitter';// 假设 emitter 定义在 emitter.ts 文件 export default defineComponent({ name: 'BrotherComponent2', data() { return { receivedData: '' }; }, mounted() { emitter.on('brother - to - brother', (data) => { this.receivedData = data; }); }, beforeUnmount() { emitter.off('brother - to - brother'); } }); </script>
- 定义事件类型接口:
- 安装
跨层级组件通信
- 使用 Vuex:
- 安装
vuex
:npm install vuex
- 定义
state
、mutations
、actions
等的类型。 - 示例:
- 定义
state
类型接口:// 定义 Vuex state 的类型 interface GlobalState { globalMessage: string; }
- 定义
mutations
类型接口:// 定义 Vuex mutations 的类型 import { MutationTree } from 'vuex'; import { GlobalState } from './types';// 假设 GlobalState 定义在 types.ts 文件 const mutations: MutationTree<GlobalState> = { SET_GLOBAL_MESSAGE(state, newMessage: string) { state.globalMessage = newMessage; } }; export default mutations;
- 定义
actions
类型接口(如果有):// 定义 Vuex actions 的类型 import { ActionTree } from 'vuex'; import { GlobalState } from './types';// 假设 GlobalState 定义在 types.ts 文件 const actions: ActionTree<GlobalState, GlobalState> = { updateGlobalMessage({ commit }, newMessage: string) { commit('SET_GLOBAL_MESSAGE', newMessage); } }; export default actions;
store
配置:import { createStore } from 'vuex'; import mutations from './mutations'; import actions from './actions'; import { GlobalState } from './types';// 假设 GlobalState 定义在 types.ts 文件 const state: GlobalState = { globalMessage: 'Initial global message' }; const store = createStore({ state, mutations, actions }); export default store;
- 在组件中使用:
<template> <div> <p>全局消息: {{ globalMessage }}</p> <button @click="updateGlobalMessage">更新全局消息</button> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { useStore } from 'vuex'; export default defineComponent({ name: 'DeepComponent', computed: { globalMessage() { const store = useStore(); return store.state.globalMessage; } }, methods: { updateGlobalMessage() { const store = useStore(); store.dispatch('updateGlobalMessage', 'New global message'); } } }); </script>
- 定义
- 安装
- 使用 provide 和 inject:
- 在祖先组件中
provide
数据,后代组件中inject
数据,并定义好数据类型。 - 示例:
- 定义提供数据的类型接口:
// 定义 provide 数据的类型 interface ProvidedData { sharedValue: string; }
- 祖先组件:
<template> <div> <slot/> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ProvidedData } from './types';// 假设接口定义在 types.ts 文件 export default defineComponent({ name: 'AncestorComponent', provide() { return { sharedValue: 'Shared value from ancestor' } as ProvidedData; } }); </script>
- 后代组件:
<template> <div> <p>注入的数据: {{ injectedValue }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ProvidedData } from './types';// 假设接口定义在 types.ts 文件 export default defineComponent({ name: 'DescendantComponent', inject: { injectedValue: { from:'sharedValue', default: '' } } as ProvidedData }); </script>
- 定义提供数据的类型接口:
- 在祖先组件中