【问题标题】:Vuejs, why is this.$store.state.route.params.activityId undefined when I access it in store moduleVuejs,当我在商店模块中访问它时,为什么 this.$store.state.route.params.activityId 未定义
【发布时间】:2020-01-03 20:07:12
【问题描述】:

我需要在 store 中设置 currentId。我在组件中有它,在控制台中一切正常:

async created() {
    const activityId = await this.$store.state.route.params.activityId
    activityId: 'activityId'
    console.log("here activityId: ", activityId)
    console.log('print all params: ', this.$store.state.route.params)
    console.log("STORE: ", this.$store.state)
  },

我已将商店组织成模块,我正在处理的是 activity.js,它运行良好(我已将所有活动保存在商店中)。我现在需要设置当前的 id,然后根据它设置单个活动(这样我就可以访问它的数据)。 删除非固有代码,我所拥有的是:

import {
  activityId
} from '@/views/ActivityDetail'

const state = {
  currentActivityId: activityId
}

const mutations = {
  SET_CURRENT_ACTIVITY_ID: (state, currentActivityId) => {
    state.currentActivityId = currentActivityId
  }
}

const actions = {
  setCurrentActivityId({
    commit
  }) {
    return new Promise(resolve => {
      commit('SET_CURRENT_ACTIVITY_ID', '')
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

在模块“getters”中,我拥有的其他模块(工作正常):

activityId: state => state.activity.activityId,

还是activityId: undefined

我在路由器中有sync (store, router) 工作,还有mode: 'history',因为在此之前我尝试过:

import {router} from '@/router'
const state = {
  currentActivityId: router.currentRoute.params.activityId,
}

我没有对mode:history做任何改变,所以我不知道问题是否可以在这里找到。但是评论它并使用 currentRoute 并没有解决问题。

我的应用中安装的版本是: “Vue路由器”:“3.0.6”, "vuex": "^3.1.0", "vuex-router-sync": "^5.0.0"

还是activityId: undefined 有人可以帮忙吗? 谢谢

【问题讨论】:

  • 不清楚您的代码究竟是如何工作的。您要访问哪些属性以及在哪里访问它们?请尝试更好地组织您的问题。
  • 据我所知,要使用 Vuex 存储数据,您应该使用 this.$store.commit('relative path to exact mutation method', your data)
  • const activityId = ... 在这里使用 const 而不是 let 似乎很奇怪..
  • 您的商店看起来有state.currentActivityId。那么,activityId: state => state.currentActivityId?
  • @Wes Doyle 是的,你是对的,但它并没有解决问题..

标签: vue.js vuejs2 vuex vue-router vuex-modules


【解决方案1】:

我解决了这个问题。我实际上并没有使用 currentActivityId 来保存单个活动。 这是我所做的: 在包含所有活动的模板中,我修改了这样的按钮:

<b-button
  v-b-tooltip.hover
  title="Mostra dettagli"
  variant="info"
  class="px-3"
  @click="goToDetailActivity((data.item), selectActivity(data.item))"
>

现在被点击的activity的@click按钮触发了这两个方法:

selectActivity(activity) {
      let currentActivity = activity;
      currentActivity = this.$store.getters.currentActivity;
      return currentActivity;
    },
    goToDetailActivity(activity) {
      console.log('OBJECT activity sent from all activities to detail: ', activity)
      const activityData = {
        activity: activity
      }
      console.log('ACTIVITY DATA IN ALL: ', activityData)
      this.loading = true
      this.$store.dispatch('activity/setCurrentActivity', activityData).then(() => {
        this.$router.push({
          name: 'DettaglioAttivita',
          params: {
            activityId: activity.id
          }
        })
        this.loading = false
      }).catch((err) => {
        console.log('ERROR IN fetching activityData: ', err)
        this.loading = false
      })
    }

在 getters 模块中:

currentActivity: state => state.activity.currentActivity

在 store/activity.js 中: -状态:

currentActivity: ''

-突变:

SET_CURRENT_ACTIVITY: (state, activityData) => {
    state.currentActivity = activityData
  }

-动作:

setCurrentActivity({ commit }, activityData) {
    commit('SET_CURRENT_ACTIVITY', activityData)
  }

我需要 payolad (activityData) 来传递数据。显然重新考虑整个事情。 现在它起作用了。 但是,如果我刷新页面,我会丢失所有数据。我正在使用 vuex-persitedstate 插件处理它。但这是另一个故事。 感谢任何花时间看它的人。

【讨论】:

  • 只是告诉你,vuex-persitedstate 插件有效。
【解决方案2】:

我相信您正在尝试做的是set您商店中特定“活动”的 ID,以便您可以使用此 ID 在不同页面上显示有关此“活动”的更多信息。

要在您的商店中设置数据,您绝对应该始终使用commit(),如果您使用触发commit()action() 会更好。不要直接设置storestate(例如this.$store.state.bar = 23

以下是如何设计功能的示例:

// Template in 'activitySelecotr.vue'
...
<div
  v-for="activity in activities"
  :key="activity.id"
  class="activity"
>
  // other stuff
  <button @click="showMoreInfo(activity.id)">Show more Information</button>
</div>
...

computed: {
  activities() {
    return this.$store.state.allActivities;
  },
  ...
}

methods: {
  showMoreInfo(activityId) {
    this.$store.dispatch('activityModule/setCurrentActivityId', activityId);
  },
  ...
}

// in 'activityDetails.vue'
...
computed: {
  activityId() {
    return this.$store.state.activityModule.currentActivityId;
  },
  ...
},
created() {
  console.log("activityId: ", this.activityId);
},
...

// store/activityModule.js

const state = {
  ...
  currentActivityId: null,
};

const actions = {
  setCurrentActivityId({ commit }, activityId) {
    // do stuff, for example load activity data
    commit('SET_CURRENT_ACTIVITY_ID', activityId);
  },
  ...
};

const mutations = {
  SET_CURRENT_ACTIVITY_ID(state, activityId) {
    state.currentActivityId = activityId;
  },
  ...
};

您提供的信息很难回答为什么您的代码无法正常工作。但我可以告诉你,至少created() 函数中的代码不是有效的 JavaScript。

async created() {
  // const activityId = await this.$store.state.route.params.activityId
  // ^ why is your route stored in your store? You can do the following:
  const activityId = this.$route.params.activityId;

  activityId: 'activityId' // 'activityId' is is a const and cannot be reassigned. Also you need to reasign with '='; ':' is invalid JavaScript.
  console.log("here activityId: ", activityId)
  console.log('print all params: ', this.$store.state.route.params)
  console.log("STORE: ", this.$store.state)
},

【讨论】:

  • 感谢@MarcRo,感谢您向我推荐这些技巧,我相应地更新了代码。不幸的是,现在控制台用红色显示,activityId is read-only,我不知道它是什么意思......
  • 您很可能尝试重新分配activityId。你不能在我的代码示例中这样做,因为activityIdconst。如果您想在声明后更改其值,则需要为let。我建议您阅读这些内容!
  • 我会的!再次非常感谢。
  • forum.vuejs.org/t/… 我找到了这篇文章,即使它很旧,也与我需要的相似。而且我也更新了我的代码(最后一个答案是我的),只是试图在不使用 activityId 的情况下获取单个活动对象并将其保存到商店(我只将它用于动态路由)。我想我离得更近了,但仍然无法正常工作...@MarcRo 请看一下,谢谢!
  • 您上一个答案中的代码(最后的更新版本)是正确的,应该可以工作。
猜你喜欢
  • 2020-03-13
  • 2018-08-17
  • 2018-05-19
  • 1970-01-01
  • 2018-10-12
相关资源
最近更新 更多