问题描述
当我想从 onMounted 函数内的道具获取一些日期时遇到一些问题。
主店模块:
import { createStore } from 'vuex'
import { categories } from './modules/categories'
export default createStore({
state: {
},mutations: {
},actions: {
},modules: {
categories
}
})
每次更改路线时,我都会调用 getCategory 操作。
categories.js vuex 模块
export const categories = {
namespaced: true,state: {
allCategories: []
},getters: {
getAllCategories (state) {
return state.allCategories
},},mutations: {
UPDATE_ALL_CATEGORIES (state,newValue) {
state.allCategories = newValue
},actions: {
async getCategories ({ commit,rootGetters }) {
const accesstoken = rootGetters['auth/getAccesstoken']
fetch('http://localhost:8080/api2/getCategories.PHP',{
method: 'post',headers: { 'Content-type': 'application/x-www-form-urlencoded' },withCredentials: true,body: JSON.stringify({
token: accesstoken
})
}).then(res=>res.json()).then((response) => {
if (response.status != '200') {
commit('UPDATE_ALL_CATEGORIES',response)
}
}).catch((error) => {
console.log('Looks like there was a problem: \n',error);
});
},modules: {
}
}
Categories.vue
<template>
<div class="page-container">
<div>
<div class="items-title">
<h3>List of categories</h3>
<span>({{ allCategories.length }})</span>
</div>
<div class="items-container">
<div class="item" v-for="(category,index) in allCategories" :key="index">
<span class="item-cell size-xs">{{ index + 1 }}.</span>
<span class="item-cell size-l">{{ category.name }}</span>
</div>
</div>
</div>
<custom-select
:options="allCategories"
/>
</div>
</template>
<script>
import CustomSelect from '../components/Input/CustomSelect'
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
components: {
CustomSelect
},setup() {
const store = useStore()
const allCategories = computed(() => store.getters['categories/getAllCategories'])
return {
allCategories
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/scss/variables.scss';
</style>
在分类组件中,我导入了 CustomSelect 组件。当我想在 onMounted 函数中控制台日志道具时,道具未定义。有谁知道什么是问题?
CustomSelect.vue
<template>
<div class="custom-select-container" @click="openSelect">
<div class="selected-item">
<span class="selected-items-text">{{ selectedItem.name }}</span>
<span class="icon-arrow1_b selected-items-icon" :class="{ active: showOptions }" />
</div>
<transition name="fade">
<ul v-show="options.length && showOptions" class="custom-select-options">
<li v-for="(option,index) in options" :key="index" class="custom-select-item" @click="changeSelected(option)">{{ option.name }}</li>
</ul>
</transition>
</div>
</template>
<script>
import { ref,onBeforeUpdate,onMounted } from 'vue'
export default {
props: ['options'],setup(props) {
let showOptions = ref(false)
let selectedItem = ref({})
onBeforeUpdate(() => {
if (Object.keys(selectedItem.value).length === 0) {
selectedItem.value = props.options[0]
}
})
onMounted(() => {
console.log(props.options[0])
})
const openSelect = () => {
showOptions.value = !showOptions.value
}
const changeSelected = (item) => {
selectedItem.value = item
}
// console.log(JSON.parse(JSON.stringify(props.options)))
return {
openSelect,showOptions,changeSelected,selectedItem
}
}
}
</script>
解决方法
getCategories
动作中的这整个部分真的很奇怪:
.then(res=>res.json()).then((response) => {
if (response.status != '200') {
commit('UPDATE_ALL_CATEGORIES',response)
}
})
-
res.json()
仅返回 body parsed as JSON,因此您无法对其进行response.status
检查。如果您想查看状态,请在调用res.json()
之前进行
- 状态检查全错了。它应该使用相等的
===
并且response.status
是一个数字 (unsigned short) 而不是一个字符串...
因此修复您的代码,将一些 console.log
放入操作和更改中,然后再次检查...
更新
-
在 Vue 3 中执行
包装数据Proxy
时得到console.log
是绝对正常的。为了检测数据的变化,Vue 用 Proxy -
在 props 中获取
undefined
您传递给 options
的道具 CustomSelect.vue
来自 allCategories
计算,它是存储中的 getAllCategories
吸气剂。 Getter 返回 state.allCategories
,它最初是一个空数组。唯一分配 state.allCategories
的地方是在 getCategories
操作中,该操作从未在您发布的代码中执行。即使它是在您未发布的某些代码中执行的,它也是一个异步调用……这意味着需要一些时间来完成并将值分配给 state.allCategories
。这意味着几乎总是当您访问任何组件的 state.allCategories
中的 onMounted
时,它将是一个空数组(因为 fetch
调用未完成)。所以 options[0]
当 options
为空数组时会给你 undefined