微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vuejs 3 道具在 onMounted 内未定义 更新

如何解决Vuejs 3 道具在 onMounted 内未定义 更新

当我想从 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)
        }
      })
  1. res.json() 仅返回 body parsed as JSON,因此您无法对其进行 response.status 检查。如果您想查看状态,请在调用 res.json()
  2. 之前进行
  3. 状态检查全错了。它应该使用相等的 === 并且 response.status 是一个数字 (unsigned short) 而不是一个字符串...

因此修复您的代码,将一些 console.log 放入操作和更改中,然后再次检查...

更新

  1. 在 Vue 3 中执行 Proxy 时得到 console.log 是绝对正常的。为了检测数据的变化,Vue 用 Proxy

    包装数据
  2. 在 props 中获取 undefined

您传递给 options 的道具 CustomSelect.vue 来自 allCategories 计算,它是存储中的 getAllCategories 吸气剂。 Getter 返回 state.allCategories,它最初是一个空数组。唯一分配 state.allCategories 的地方是在 getCategories 操作中,该操作从未在您发布的代码中执行。即使它是在您未发布的某些代码中执行的,它也是一个异步调用……这意味着需要一些时间来完成并将值分配给 state.allCategories。这意味着几乎总是当您访问任何组件的 state.allCategories 中的 onMounted 时,它将是一个空数组(因为 fetch 调用未完成)。所以 options[0]options 为空数组时会给你 undefined

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。