【问题标题】:Nuxtjs Page components are not updated even if the vuex store is updated即使更新了 vuex 存储,Nuxtjs 页面组件也不会更新
【发布时间】:2018-03-25 05:07:32
【问题描述】:

我正在将 nuxtjs 用于服务器端渲染项目。我有一个 REST API,我想从那里更新 Vuex 商店并显示页面。 In the nuxtjs documentation for using Vuex store, it mentions using fetch api of the pages。所以我正在尝试获取 API 的文章列表并呈现页面。

Vuex 商店:

const createStore = () => {
  return new Vuex.Store({
    state: {
      article_list: []
    },
    mutations: {
      updateArticleList (state, payload) {
        state.article_list = payload
        console.log('article list length', state.article_list.length)
      }
    },
    actions: {
      mutateArticleList ({commit}, payload) {
        api.get_articles()
          .then((data) => {
            commit('updateArticleList', data)
          })
      }
    }
  })
}

在 pages/index.vue:

<template>
  <div>
    <button @click="update">Update</button>
    <p v-for="article in articles" :key="article.id">Article</p>
  </div>
</template>

<script>
  export default {
    fetch ({store}) {
      store.dispatch('mutateArticleList')
    },
    computed: {
      articles () {
        return this.$store.state.article_list
      }
    },
    methods: {
      update () {
        this.$store.dispatch('mutateArticleList')
      }
    }
  }
</script>

在控制台我可以看到商店的 article_list 已经更新了

console.log('article list length', state.article_list.length) // 16

但是在 index.vue 页面上,没有文章。即使在索引created 方法的控制台上,article_list 也是 0

console.log('index created length', this.$store.state.article_list.length) // 0

我在这里缺少什么?请你帮助我好吗。

【问题讨论】:

    标签: vue.js vuex nuxt.js


    【解决方案1】:

    由于 vex 存储是响应式的,因此您可以通过在计算属性中返回存储的状态来检索它。见getting vuex state into components

    你正在做的是:

    <tag-contents v-for="article in $store.state.article_list" :key="article.id"></tag-contents>
    

    改为这样做:

    <template>
      ...
        <tag-contents v-for="article in articles" :key="article.id"></tag-contents>
      ...
    </template>
    
    <script>
    export default  {
        ...
        fetch ({store, params}) {
            api.get_articles()
                .then((data) => {
                    store.dispatch('mutateArticleList', data)
                })
        },
        created () {
            console.log('index created length', this.$store.state.article_list.length)
        },
        computed:{
            articles(){
                return this.$store.state.article_list;
            }
        }
    }
    </script>
    

    每当 store 的状态更新时,计算的属性 articles 就会重新评估并促使 DOM 更新

    还有一点要提:

    由于操作用于异步任务,您可以将 RESTapi 获取逻辑移动到 mutateArticleList 操作中,并通过将从 ajax 调用收到的数据作为负载传递给突变来提交突变以更新状态。

    所以现在你的代码应该是:

    商店

    const createStore = () => {
      return new Vuex.Store({
        state: {
          article_list: []
        },
        mutations: {
          updateArticleList (state, payload) {
            state.article_list = payload
            console.log('article list length', state.article_list.length)
          }
        },
        actions: {
          mutateArticleList ({commit}, payload) {
              api.get_articles()
                .then((data) => {
                    commit('updateArticleList', data);
                })
          }
        }
      })
    }
    

    index.vue

    <template>
      ...
        <tag-contents v-for="article in articles" :key="article.id"></tag-contents>
      ...
    </template>
    
    <script>
    export default  {
        ...
        fetch () {
            this.$store.dispatch('mutateArticleList', data)
        },
    
        computed:{
            articles(){
                return this.$store.state.article_list;
            }
        }
    }
    </script>
    

    【讨论】:

    • 嗨!我已经用您的代码更新了我的问题,并稍作修改。但是,页面仍然没有更新。在终端中,我可以看到总文章,但在浏览器中,文章长度为 0。我添加了一个额外的按钮来更新/调度从 api 获取项目的操作。当我单击按钮以获取项目时,页面会更新。如何获取api结果然后显示页面。
    • @Robin 尝试在 created() 钩子中调用更新方法并删除所有获取的东西
    猜你喜欢
    • 2019-09-01
    • 2017-12-29
    • 2021-06-21
    • 2018-06-14
    • 2016-04-11
    • 1970-01-01
    • 2021-07-26
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多