Vue组合式API中如何从计算属性获取状态值?
正确获取Vue组合式API中store异步返回的addtocalender值
我在使用Vue组合式API做状态管理时,遇到了无法获取addtocalender值的问题:通过计算属性关联store中的addtocalender状态,但在组件的config变量中访问addtocalender.value.name返回undefined。相关代码如下:
store.js
import { reactive, readonly } from 'vue'; import axios from 'axios'; const state = reactive({ addtocalender: [], }); const mutations = { updateAddtocalender: (payload) => state.addtocalender = payload, } const actions = { getAddtocalender: () => { return axios.get('http://localhost:3000/addtocalender').then((response) => { mutations.updateAddtocalender(response.data); }); }, }; export default { state: readonly(state), mutations, actions };
component.vue
<script setup> import { onMounted, ref, inject, computed, watchEffect } from "vue"; const store = inject('store'); const addtocalender = computed(() => store.state.addtocalender); store.actions.getAddtocalender(); const config ={ // 我想在此处填入addtocalender的值 name: addtocalender.value.name, startDate: addtocalender.value.startDate, }; </script>
addtocalender.json
{ "name":"Reminder to star the add-to-calendar-button repo", "description":"Check out the maybe easiest way to include add-to-calendar-buttons to your website:\n→ [url]https://github.com/jekuer/add-to-calendar-button|Click here![/url]", "startDate":"2022-08-14", "location":"World Wide Web", "label":"Simpan ke kalender!", "startTime":"10:13", "endTime":"12:57", "options":[ "Google", "Apple", "iCal", "Yahoo", "Outlook.com", "Microsoft365" ], "timeZone":"Asia/Jakarta", "trigger":"click", "iCalFileName":"Reminder-Event" }
问题原因
- 初始状态类型不匹配:store中
addtocalender初始值是数组[],但接口返回的是对象类型,初始访问.name属性自然不存在。 - 同步执行时机问题:组件setup阶段同步创建
config时,异步请求还未完成,addtocalender仍为初始值,无法拿到接口返回的数据。
解决方案
步骤1:修正store初始状态类型
将store中addtocalender的初始值改为空对象,与接口返回的类型保持一致:
// store.js const state = reactive({ addtocalender: {}, // 替换原数组[]为{} });
步骤2:让config响应式或等待请求完成后赋值
有两种可行方案:
方案一:将config定义为计算属性
利用计算属性的响应式特性,当addtocalender更新时自动同步值:
<script setup> import { inject, computed } from "vue"; const store = inject('store'); const addtocalender = computed(() => store.state.addtocalender); // 定义响应式的config const config = computed(() => ({ name: addtocalender.value.name || '', startDate: addtocalender.value.startDate || '', })); // 发起异步请求 store.actions.getAddtocalender(); </script>
方案二:等待请求完成后再赋值config
用ref定义config,在异步请求完成后更新其值:
<script setup> import { inject, computed, ref, onMounted } from "vue"; const store = inject('store'); const addtocalender = computed(() => store.state.addtocalender); const config = ref({}); onMounted(async () => { // 等待请求完成 await store.actions.getAddtocalender(); // 此时已拿到数据,赋值config config.value = { name: addtocalender.value.name, startDate: addtocalender.value.startDate, }; }); </script>
内容的提问来源于stack exchange,提问作者cahya faisal reza
相关产品推荐
相关产品推荐

