vue 入门:组件通讯
跨组件通讯图
Props(父 → 子)
本质:父组件通过属性向子组件传递数据。
特点:单向数据流,子组件不能直接修改 props。
示例:
<!-- 父组件 -->
<Child :title="parentTitle" />
<!-- 子组件 -->
<script>
export default {
props: ['title'] // 接收父组件数据
}
</script>
$emit
+ v-on(子 → 父)
本质:子组件通过事件向父组件传递数据。
示例:
<!-- 子组件 -->
<button @click="$emit('update', newValue)">提交</button>
<!-- 父组件 -->
<Child @update="handleUpdate" />
provide / inject(依赖注入)
本质:祖先组件提供数据,后代组件注入使用。
特点:适合深层嵌套,但数据流向不透明。
示例:
// 祖先组件
export default {
provide() {
return { theme: 'dark' }; // 提供数据
}
}
// 后代组件
export default {
inject: ['theme'] // 注入数据
}
任意组件通信(全局状态)
Vuex 是 Vue 官方提供的状态管理库,适用于复杂应用的全局状态管理。它通过一个全局的 store 来管理应用的状态,允许跨组件共享和修改数据。
API官网
核心概念:
- state:存储数据。
- mutations:同步修改数据。
- actions:异步操作。
- getters:计算属性。
安装
npm install vuex@3 --save
创建 Store
// store.js
import { createStore } from 'vuex';
export default createStore({
state: {
globalMessage: 'Hello from Vuex'
},
mutations: {
updateMessage(state, newMessage) {
state.globalMessage = newMessage;
}
},
actions: {
updateMessage({ commit }, newMessage) {
commit('updateMessage', newMessage);
}
},
getters: {
globalMessage: (state) => state.globalMessage
}
});
在主应用中引入 Store:
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
createApp(App).use(store).mount('#app');
在组件中使用:
// 组件中
this.$store.dispatch('updateMessage', 'New Message');
console.log(this.$store.getters.globalMessage);
Pinia 是 Vue 3 推荐的状态管理库,是 Vuex 的替代品,提供了更好的类型支持和更简
安装
npm install pinia
创建 Store
// store.js
import { defineStore } from 'pinia';
export const useMessageStore = defineStore('message', {
state: () => ({
message: 'Hello from Pinia'
}),
actions: {
updateMessage(newMessage) {
this.message = newMessage;
}
}
});
在主应用中引入 Store:
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';
const app = createApp(App);
app.use(createPinia());
app.mount('#app');
在组件中使用:
// 组件中
import { useMessageStore } from './store';
const store = useMessageStore();
store.updateMessage('New Message');
console.log(store.message);