Vue3中各种灵活传递数据的方式小结
作者:牛马先生
前言、理解Vue 3的数据流
Vue 3 提供了多种数据传递的方式,让我们的组件之间可以尽情地交流。接下来,我们就直接一个个来看,这些方式都是怎么工作的。
一、Props:从父到子的经典路径
在 Vue 中,子组件可以通过 props
接收父组件传递过来的数据,这可是从父组件到子组件传递数据的老传统了。这就像家长给孩子零花钱一样,孩子只能使用家长给的,不能自己去拿家里的钱。
// 父组件 <template> <ChildComponent :message="greeting" /> </template> <script setup> import ChildComponent from './ChildComponent.vue'; const greeting = 'Hello!'; </script> // 子组件 <script setup> const props = defineProps({ message: String, }); console.log(message); // "Hello!" </script>
<script setup>
使用了 Composition API,它简化了 prop 的访问方式。所以我们不需要通过 props
对象来访问 prop 的值,可以直接将 prop 声明为一个变量,并在模板或逻辑中使用它。
二、Emits:子组件的呼唤
如果子组件需要某些数据时呢,总不能坐等着父组件传递吧。所以接着是Emits
,它让子组件能够向上发射信号。通过defineEmits
和$emit
,子组件可以告诉父组件:“我有事情要通知!”
// 父组件 <template> <ChildComponent @updateMessage="newGreeting = $event" /> <p>{{ newGreeting }}</p> </template> <script setup> import ChildComponent from './ChildComponent.vue'; let newGreeting = ''; </script> // 子组件 <script setup> const emit = defineEmits(['updateMessage']); const updateParent = () => { emit('updateMessage', 'Updated from child!'); }; </script>
父组件包含一个子组件实例,并监听子组件发出的 updateMessage
事件。当这个事件被触发时,父组件会更新其内部的 newGreeting
数据属性。
子组件中定义了一个方法 updateParent
,当调用这个方法时,它会触发 updateMessage
事件,并传递一个字符串作为参数给父组件。
每当触发 updateMessage
事件,父组件会接收到这个事件并更新 newGreeting
的值,从而在页面上显示更新后的消息。
这里,
$event
只是一个约定俗成的变量名,用于在事件处理器中捕获事件对象或者事件传递的数据。通常为了使代码更易于阅读和理解,我们会根据事件数据的实际内容来选择合适的变量名。
三、provide / inject:上下文中的通信
有时候组件会嵌套的比较深,如父组件中有子组件,子组件中有孙组件……当组件层级很深,或者需要跨多个组件共享数据时,provide
和 inject
就派上用场了。它们能让我们在组件树中自由传递数据,而不必层层传递props。这在处理深层次嵌套的组件时非常有用。
// 父组件 <script setup> import { provide } from 'vue'; provide('theme', 'dark'); </script> // 子孙组件 <script setup> import { inject } from 'vue'; const theme = inject('theme'); console.log(theme); // "dark" </script>
在父组件中,我们使用 provide
函数来提供一个名为 'theme'
的键以及对应的值 'dark'
。这使得 'theme'
可以被其所有子组件及其子代组件访问。
在子孙组件中,你使用 inject
函数来获取 'theme'
键的值。inject
函数会查找最近的祖先组件中提供的与 'theme'
键相匹配的值。
当 inject
被调用时,Vue 会沿着组件树向上查找,直到找到一个与注入键匹配的提供者。如果找不到匹配的提供者,inject
将返回 undefined
。为了避免这种情况,可以为 inject
提供一个默认值。
const theme = inject('theme', 'light'); // 如果没有找到提供者,则使用 'light' 作为默认值
虽然 provide / inject 避免了必须在每一层组件之间传递 props 的繁琐,但过度使用这种方法可能导致组件之间的耦合度增加,使得代码难以追踪和维护,所以建议适当使用。
四、Vuex:全局状态管理的专家
既然 provide / inject 不好过度使用,那么现在就讲到 Vuex,它是处理复杂应用中全局状态的理想选择。通过Vuex,我们可以轻松地管理跨组件的状态。
1、安装 Vuex
如果还没有安装 Vuex,就直接 npm。
npm install vuex
2、创建 Vuex Store
首先,需要创建一个 Vuex store 文件。
import { createStore } from 'vuex'; export default createStore({ state: { theme: 'light', }, mutations: { setTheme(state, theme) { state.theme = theme; }, }, actions: { changeTheme({ commit }, theme) { commit('setTheme', theme); }, }, getters: { currentTheme(state) { return state.theme; }, }, });
state
是 store 的数据容器。mutations
是提交到 store 的唯一方式,它们负责修改 state。actions
是异步操作的处理函数,可以包含任意的异步操作逻辑。getters
是 store 的计算属性,用于从 store 中获取状态的派生状态。
3、在主应用文件中使用 Vuex Store
在我们的主应用文件中 main.js 中,引入并使用 Vuex store。
import { createApp } from 'vue'; import App from './App.vue'; import store from './store'; const app = createApp(App); app.use(store); app.mount('#app');
4、在组件中使用 Vuex Store
直接使用 store 的属性和方法。
<template> <div :class="theme"> <!-- 使用 getter --> <p>The current theme is {{ currentTheme }}.</p> <!-- 使用 action --> <button @click="changeTheme('dark')">Switch to dark theme</button> </div> </template> <script setup> import { computed, onMounted } from 'vue'; import { useStore } from 'vuex'; const store = useStore(); const theme = computed(() => store.state.theme); const currentTheme = computed(() => store.getters.currentTheme); function changeTheme(newTheme) { store.dispatch('changeTheme', newTheme); } onMounted(() => { console.log('Current theme:', store.getters.currentTheme); }); </script>
theme
和currentTheme
是使用computed
创建的响应式引用,分别映射到 store 的状态和 getter。changeTheme
函数使用store.dispatch
来触发changeTheme
action,参数是新的主题值。onMounted
钩子确保在组件挂载后立即执行,用于检查并记录当前的主题。
当主题在 Vuex store 中发生变化时,由于 theme
和 currentTheme
的响应式特性,组件会自动更新 UI 以反映新的主题。changeTheme
函数提供了切换主题的功能,可以通过点击按钮来触发主题的改变。
除了 vuex ,还有一个 pinia 和它相似,这里就不介绍了。
结语
到这里,我们一同探索了Vue 3中丰富多彩的数据传递方式,从基础的Props和Emits,到进阶的Provide与Inject,以及全局状态管理的Vuex。每种方法都有其独特的应用场景,就看我们怎么选择了。
以上就是Vue3中各种灵活传递数据的方式小结的详细内容,更多关于Vue3传递数据方式的资料请关注脚本之家其它相关文章!