【问题标题】:Vuejs 3 props are undefined inside onMountedVuejs 3 道具在 onMounted 中未定义
【发布时间】:2021-07-07 22:20:59
【问题描述】:

当我想从 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>

【问题讨论】:

    标签: vue.js vuejs3 vue-props


    【解决方案1】:

    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. 状态检查全错。它应该使用相等的===response.status 是一个数字(unsigned short)而不是一个字符串...

    所以修复你的代码,将一些 console.log 放入一个动作和突变中,然后再次检查......

    更新

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

    2. 在道具中获取undefined

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

    【讨论】:

    • 但我认为问题不存在。如果我在 onBeforeUpdate 中进行控制台登录,我将获得数据。如果我在 onMounted 函数内部执行,我将不会获取数据。作为回应,我有状态,这就是我检查这个的原因。
    • 我不明白你为什么一直在谈论onMounted。您发布的代码中的任何地方都没有onMounted...
    • 对不起,我添加了错误的代码。我现在更新了,你可以看到onMounted。我正在尝试在 onMounted 中执行 console.log(props.options),结果得到了 Proxy {}。
    • 那么Mounted上就不可能获取数据了?
    猜你喜欢
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2021-07-16
    • 2019-10-05
    • 1970-01-01
    • 2019-02-19
    • 2017-03-12
    相关资源
    最近更新 更多