【问题标题】:Vue component's view doesn't re-render after state change in vuex?Vuex中状态更改后Vue组件的视图不会重新渲染?
【发布时间】:2020-02-10 11:14:17
【问题描述】:

最近我学习了 vue 和它的 redux 对应物 vuex。但是由于某种原因,vuex 中的状态更改不会触发对 vue 组件中视图的响应式更新。

export const store = new Vuex.Store({
    state: {
        user: {
            id: -1,
            books: []
        }
    },
    mutations: {
        ADD_BOOK(state, book) {
            state.user.books.push(book);
        }
    },
    actions: {
        addBook(context, book) {
            context.commit('ADD_BOOK', book);
        }
    },
    getters: {
        books: state => {return state.user.books}
    }
})

在我的 vue 组件中:

<template>
    <div>
        ...
        <div>
            <ul>
                <li v-for="book in books">
                    {{ book.name }}
                </li>
            </ul>
        </div>
        <div>
            <form @submit.prevent="onSubmit()">
                <div class="form-group">
                    <input type="text" v-model="name" placeholder="Enter book name">
                    <input type="text" v-model="isbn" placeholder="Enter book isbn">
                </div>
                <button type="submit">Submit</button>
            </form>
        </div>
        ...
    </div>
</template>

<script>
module.exports = {
    data () {
        return {
            isbn: ''
            name: ''
            testArr:[]
        }
    },
    methods: {
        onSubmit: function() {
            let book = {isbn: this.isbn, name: this.name};
            this.$store.dispatch('addBook', book);
            // If I do `this.testArr.push(book);` it has expected behavior.
        }
    },
    computed: {
        books () {
            return this.$store.getters.user.books;
        }
    }
}

我正在通过computed 访问 vuex 商店的书籍,在我提交表单数据后,从 vuejs 开发人员工具扩展中,我看到了 vuex 的变化以及组件的计算属性。但我没有看到提交后视图得到更新。知道我在这里缺少什么吗?

【问题讨论】:

  • 当我运行您的代码时,它似乎对我来说一切正常。我唯一需要解决的是data 中的属性之间缺少逗号。

标签: javascript vue.js


【解决方案1】:

问题出在computed 属性中。应该是:

computed: {
 books () {
   return this.$store.getters.books;
 }       
}

为方便起见,您可以使用vuex mapGetters:

import { mapGetters } from 'vuex'

export default {
  //..
  computed: {
    ...mapGetters(['books'])
  }
}

【讨论】:

  • 对不起。原来我使用的是this.$store.getters.books。我在帖子中复制了错误的内容。
  • 发生了一些奇怪的事情。当我提交后按退格键时,会显示数据。
  • 点击提交时数据应该会显示出来。您能否在 codepen 或 codesanbox 上创建一个示例来重现该问题以帮助您?
【解决方案2】:

要做到这一点,你需要观看

请注意这个例子:

methods: {
...
},
computed: {
    books () {
        return this.$store.getters.books;
    }      
},
watch: {
    books(newVal, oldVal) {
        console.log('change books value and this new value is:' + newVal + ' and old value is ' + oldVal)
    }
}

现在您可以重新渲染组件

<template>
    <div :key="parentKey">{{books}}</div>
</template>
data() {
    return {
        parentKey: 'first'
    }
}

只需要在手表上更改parentKey

watch: {
    books(newVal, oldVal) {
        this.parentKey = Math.random()
    }
}

【讨论】:

    猜你喜欢
    • 2019-07-30
    • 2019-06-29
    • 2021-10-28
    • 2019-06-08
    • 2019-06-17
    • 1970-01-01
    • 2021-05-19
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多