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

Why vuex actions in updated hooks trigger infinite updated events?

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

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

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

infinite 问题将消失。但这会在每次 $route 变化被观察时触发 updated 两次挂钩,我也不知道为什么。

Simple demo 来了。相关代码

// 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)
    },
  },
})

updated 挂钩在组件的 DOM 由于组件数据模型的更改而更新后调用(导致重新呈现组件)。因此,您不应该在此挂钩内更改组件的状态(异步或非异步),否则状态更改将导致组件重新呈现,这将触发 updated 挂钩,从而更改状态...等等.

文档解释得很好:

The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here. However, in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead.