为什么更新钩子中的 vuex 操作会触发无限更新的事件?



我只是不明白,list.vue我只触发一个异步更改updated钩子中state.listlist操作。items是仅依赖于state.list的计算属性。为什么这会导致无限更新的事件?

我发现,如果我将钩子中的代码移动到updated选项watch如下所示:

watch: {
'$route': function () {
this.$store.dispatch('list') 
},
},

无限的问题会消失。但是每次监视更改时$route这会触发两次updated钩子,我也不知道为什么。

简单的演示在这里。相关代码

// main.js
var Vue = require('vue')
var app = require('./App.vue')
new Vue(app).$mount('#app')
// App.vue
<template>
<div id="app">
<h1>list bug test</h1>
<router-view></router-view> 
</div>
</template>
<script>
import store from './store.js'
import router from './router.js'
export default {
store,
router,
}
</script>
// list.vue
<template>
<table>
<tbody>
<tr>
<th>title</th>
<th>actions</th>
</tr>
<tr v-for="(item, index) in items">
<td> {{item.title}} </td>
<td> submit </td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
updated: function () {
console.log('items.vue updated')
this.$store.dispatch('list') 
},
mounted: function () {
console.log('items.vue mounted')
this.$store.dispatch('list')
},
computed: {
items: function () {
return this.$store.state.list.map(e => ( {title: e.ksmc } )) 
},
},
}
</script>
// router.js
var router = new VueRouter({
routes:[
{
path:'/', 
name: 'list',
component: listView,
},
],
})
// store.js
var store = new Vuex.Store({
state: {
error: undefined,
list: JSON.parse(localStorage.getItem('list')) || [],
},
mutations: {
list: function(state, list) {
state.list = list
},
error: function(state, error) {
state.error = error
},
},
actions: {
list (ctx, kwargs) {
setTimeout(() => {
ctx.commit('list', [{ksmc:'this is a title'}])
}, 1000)
},
},
})

由于组件的数据模型发生更改(导致组件重新渲染(而更新组件的 DOM 后,将调用updated钩子。因此,您不应该在此钩子中更改组件的状态(异步与否(,否则状态更改将导致组件重新渲染,这将触发将更改状态的updated钩子......等等。

文档解释得很好:

调用此钩子时,组件的 DOM 将已更新,因此您可以在此处执行依赖于 DOM 的操作。但是,在大多数情况下,您应该避免更改钩子内部的状态。若要对状态更改做出反应,通常最好改用计算属性或观察程序。

最新更新