Vuex商店没有返回正确的价值

时间:2018-01-18 10:25:14

标签: javascript vue.js axios vuex

我不知道造成这个问题的原因。我正在向后端发送请求以获取一些数据并将其显示在前面。我从后面获取一些食谱并将其存储在数组中。使用 v-for i循环播放数组并创建 router-link 以导航到每个食谱。现在,当我点击一些食谱时,我想在屏幕右侧显示它的详细信息。单击链接时,我从数据库中获取正确的配方并将其存储在vuex状态的空对象中。有了getter,我想得到那个对象但是当我得到它时,这是完全错误的id。

VUEX MODULE

const state = {
 recipes: [],
 singleRecipe: {}
};

const mutations = {
 'RECIPES_LIST'(state, recipes) {
 state.recipes = recipes;
},
'GET_RECIPE'(state, response) {
 const recipe = response; // THIS IS THE RIGHT RESPONSE 
 state.singleRecipe =  recipe;
 }
}

const actions = {
  initRecipes: ({commit}) => {
  axios.get('http://localhost:3000/recipes')
  .then((response) => {
    commit('RECIPES_LIST', response)
  })
  .catch(err => {
    console.log(err);
  });
  },
  getRecipe: ({commit}, id) => {
   axios.get('http://localhost:3000/recipes/' + id)
  .then(response => {
    const recipe = JSON.stringify(response);
    commit('GET_RECIPE', recipe); // RIGHT RECIPE
  })
  .catch(err => console.log(err));
  },

 const getters = {
 recipes: state => {
 return state.recipes;
 },
  singleRecipe: state => {
   return state.singleRecipe;
  }
};

食谱清单组件

   <template>
  <div>
    <div class="col-md-6">
      <router-link :to="'/recipes/' + recipe.id"  v-for="recipe in 
 recipes.data">
        <div id="list"  class="panel">
          <div class="panel-body">
            <div class="pull-left">
              <h4>{{recipe.title}}</h4>
            </div>
            <div class="pull-right">
              <img class="img-responsive" :src="recipe.picture" style="width: 80px; height: 80px;">
             </div>
          </div>
        </div>
      </router-link>
    </div>
    <div class="col-md-6">
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
  export default {
    computed: {
      recipes() {
        return this.$store.getters.recipes;
      }
    }
  }
</script>

食谱详细信息

<template>
  <div class="panel" @click="getSingleRecipe">
    <div class="panel-heading">
      <!--<h1>{{recipe.data.title}}</h1>-->
    </div>
    <div class="panel-body">
      <!--<p>{{recipe.data.description}}</p>-->
      <p>Ingredients: </p>
      <ul>
        <li v-for="i in recipe.ingredients">{{i.ingredient}}</li>
      </ul>
      <router-link :to="{name: 'Update', params: {id: id}}"><button class="btn btn-primary">Update Recipe</button></router-link>
      <button class="btn btn-danger" @click="deleteRecipe">Delete Recipe</button>
    </div>
  </div>
</template>
<script>
  import { mapActions } from 'vuex';
  export default {
   data() {
     return {
    id: this.$route.params.id,
    recipe: {}
      }
    },
    watch: {
  '$route' (to, from) {
    this.id = to.params.id;
    this.getSingleRecipe();
        console.log('CHANGEEEEEE' + this.recipe); // GETS RECIPE WITH ID (example 4)
        console.log("ACTIVEEEEEEE ID" + this.id); // GETS RIGHT ID (example id: 2)
      }
    },
   ...mapActions({
      deleteTheRecipe: 'deleteRecipe',
      initRecipes: 'initRecipes',
      getRecipe: 'getRecipe'
      }),
      deleteRecipe() {
    this.deleteTheRecipe(this.id);
    this.initRecipes();
    this.$router.push('/recipes');
  },
      getSingleRecipe() {
         this.getRecipe(this.id);
         this.recipe = this.$store.getters.singleRecipe;
      }
    },
    created() {
      this.getSingleRecipe();
      console.log("CREATED ID" + this.id);
      console.log('CREATEDDDDD ' + JSON.stringify(this.recipe));
    }
  }
</script>

1 个答案:

答案 0 :(得分:0)

尝试将id属性从数据移动到计算属性中。我的猜测是,一旦组件渲染了data.id属性,就不会对route.params中的更改做出反应。

在路由更改时加载配方的另一种方法是使用路由器上的beforeEnter功能。

import store from '../store'

beforeEnter: (to, from, next) => {
    store.dispatch(getRecipe, to.params.id)
      .then(() => {
        next()
      })
  }

这样您就不必在组件中观察路由器。使用mapGetters从商店获取食谱。

computed: {
  ...mapGetters({
    recipe: 'singleRecipe'
  })
}