事件传递
-
子组件向父组件传递事件
首先在父组件中定义一个用于接收事件的方法handleContentPage
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<!-- 这是父组件 --> <template> <div id="parent"> <!-- 接收子组件的消息 --> <Navbar @update-content-page="handleContentPage"/> </div> </template>
<script> import Navbar from "@admin/views/Navbar.vue";
export default { components: { Navbar, }, methods:{ handleContentPage(page){ console.log("收到子组件传递过来的消息") } } }; </script>
|
然后在子组件中借助$emit
来调用父组件的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
<!-- 这是子组件 --> <template> <div class="navbar"> <!-- 导航栏 --> <nav> <ul> <li @click="navigateTo('Dashboard')">仪表板</li> <li @click="navigateTo('Users')">用户</li> <li @click="navigateTo('Settings')">设置</li> </ul> </nav> </div> </template> <script>
export default { methods: { navigateTo(page) { console.log("点击了菜单栏"); //向父组件发送数据 this.$emit('update-content-page', page); } }, }; </script>
|
注意: $emit
闯入的第一个参数 update-content-page
需要和父组件中使用@
进行一一对应
-
父组件向子组件传递事件
首先在子组件中定义一个供父组件调用的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<!-- 这是子组件 --> <template> <div class="content"> </div> </template> <script>
export default { methods: { //定义一个方法供父组件调用 updatePage(page) { console.log("收到来自父组件的数据"+page); } },
} } </script>
|
然后在父组件中通过对象引用的方式调取子组件的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
<!-- 这是父组件 --> <template> <div id="parent"> <button @click="handleContentPage">一键转换</button> <!-- 使用 ref 建立子组件的实例引用 方便调子组件方法 --> <Content ref="contentRef"/> </div> </template> <script>
import Content from "@admin/views/Content.vue";
export default { components: { Content, }, methods:{ handleContentPage(page){ //调取子组件的函数 this.$refs.contentRef.updatePage(page) } } }; </script>
|
-
两个不相关的组件进行事件传递
在Vue 3
中,可以使用事件总线Event Bus
来进行两个不相关的组件之间优雅地通信。
首先在一个单独的JavaScript
模块中创建事件总线:
1 2
|
import { createApp } from 'vue' export const eventBus = createApp({})
|
然后在需要发布事件的组件中导入事件总线并发送事件:
1 2 3 4 5 6 7 8 9
|
import { eventBus } from './event-bus'
export default { methods: { sendMessage() { eventBus.emit('message-sent', this.message) } } }
|
最后,在接收事件的组件中也导入事件总线并监听事件:
1 2 3 4 5 6 7 8 9
|
import { eventBus } from './event-bus'
export default { created() { eventBus.on('message-sent', message => { console.log(`Received message: ${message}`) }) } }
|
数据传递
Vue
中如果需要进行父子间数据的传递, 可以使用provide/inject来实现
在祖先组件中使用provide
来提供数据:
1 2 3 4 5 6 7 8
|
import { provide } from 'vue'
export default { setup() { const name = 'John Doe'; provide('name', name); } }
|
在后代组件中使用inject
来获取数据:
1 2 3 4 5 6 7 8
|
import { inject } from 'vue'
export default { setup() { const name = inject('name'); console.log(name); } }
|
这样,后代组件就可以通过inject
方法访问提供的数据了。
全局数据共享
如果我们需要在所有组件中共享数据, 比如用户的信息 缓存数据等等,
在Vue3
中,介绍两种方案
第一种 使用一个全局的provide/inject
具体步骤如下:
- 在根组件中提供要共享的数据
1 2 3 4 5 6 7 8 9 10 11 12
|
import { createApp, reactive } from 'vue';
const app = createApp({ setup() { const sharedState = reactive({ count: 0 }); return { sharedState, }; }, });
app.mount('#app');
|
- 在需要使用该数据的子组件中注入它
1 2 3 4 5 6 7 8 9 10
|
import { inject } from 'vue';
export default { setup() { const sharedState = inject('sharedState'); return { sharedState, }; }, };
|
- 在子组件中就可以直接使用这个共享的状态了,比如在模板中显示它的值或者修改它的值
1 2 3 4 5 6
|
<template> <div> {{ sharedState.count }} <button @click="sharedState.count++">增加</button> </div> </template>
|
这样就可以实现一个简单的全局数据共享了。需要注意的是,provide/inject
API并不是响应式的,如果需要响应式地共享数据,可以使用reactive
或者ref
等Vue3提供的响应式API来实现。
使用Vuex
在Vue 3
中,可以使用 Vuex 4
来实现全局数据共享。
首先需要安装Vuex
:
然后在 main.js 中创建一个 store 实例:
1 2 3 4 5 6 7
|
import { createApp } from 'vue' import App from './App.vue' import store from './store'
const app = createApp(App) app.use(store) app.mount('#app')
|
接着在 src 目录下创建一个 store.js 文件,用于定义 store:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
import { createStore } from 'vuex'
const store = createStore({ state() { return { count: 0 } }, mutations: { increment(state) { state.count++ } }, actions: { increment(context) { context.commit('increment') } }, getters: { doubleCount(state) { return state.count * 2 } } })
export default store
|
这里的state
定义了初始状态,mutations
定义了修改状态的方法,actions
定义了异步操作,getters
定义了从状态中派生出来的值。
在组件中使用store
的数据和方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
<template> <div> <p>Count: {{ count }}</p> <p>Double Count: {{ doubleCount }}</p> <button @click="increment">Increment</button> </div> </template>
<script> import { computed } from 'vue' import { useStore } from 'vuex'
export default { setup() { const store = useStore() const count = computed(() => store.state.count) const doubleCount = computed(() => store.getters.doubleCount)
const increment = () => { store.dispatch('increment') }
return { count, doubleCount, increment } } } </script>
|
在组件中使用 useStore
获取store
实例,在 setup
函数中使用computed
函数将 store
中的数据和方法转化为响应式的值,然后在模板中使用即可。
以上是一个简单的示例,具体使用还可以根据实际需求进行修改和扩展。