我在vuex存储区中有一个带有表[t1,t2]的列表,当更新t1时,我必须更改表数组才能更新t1。
对于每个表,我使用<Table v-for="(item, index) in tables" :key="index" :data="item">
,其中它使用Table.vue。在Table.Vue中,我有:
props: {
data: {
type: Object,
default: null
}
},
但是,当t1更改时,它也将强制更新到t2,这是可以理解的,因为存储中的整个“ tables”变量都发生了变异。但是我只希望组件在道具发生实际变化时进行更新,以免t2不必要地更新。我试图研究记忆,我之前在React-projects中使用它来解决这个问题。我真的没有发现任何易于使用的东西,并且搜索“ memoization vuejs”并没有真正让我继续前进。
我如何在vuex存储中进行突变以对表进行突变:
my_mutation(state, data) {
let newList = [...state.tables];
let index = newList.findIndex(i => i.tableName === data.tableName);
if (index !== -1) {
newList[index] = data.value;
}
Vue.set(state, 'currentViews', newList);
}
如您所见,该代码当时仅在state.tables中变异1个元素,但设置整个表变量。这将导致update()函数在组件中触发(注意,不是created(),因为这仅在我获取并填充表变量时才发生)并重新释放组件。
由于在发生突变时未触发created(),因此这告诉我该组件仍然存在并且不需要重新创建。这里的目标不是在道具没有更改时触发update()并防止重新渲染该特定组件。
答案 0 :(得分:0)
您可能应该添加一些代码,因为您看到的内容似乎很奇怪...
看下面的例子(更新的例子使用Vuex ...只是为了确定)
tables
数组。 结果 =两个组件的重新渲染(符合预期)tables
数组。 结果 =完全不重新渲染currentViews
中拥有state
属性,则无需使用Vue.set
-简单的分配就足够了 更新:在updated
组件中添加了带有console.log
的{{1}}钩子,以检查日志是否与表标题中的时间变化相关-已确认
mytable
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
tables: [
['item 1', 'item 2'],
['item 1', 'item 2']
]
},
mutations: {
mutate1st(state) {
Vue.set(state.tables[0], 0, state.tables[0][0]+'+1')
},
mutateTables(state) {
Vue.set(state.tables, 1, ['item 3', 'item 4'])
},
replaceTables(state) {
state.tables = [
['item 1', 'item 2'],
['item 1', 'item 2']
]
},
newArrayCreatedFromPreviousOnes(state) {
state.tables = [...state.tables] // we are creating new array composed from existing instances
},
sameWayAsInQuestion(state) {
let newList = [...state.tables];
newList[1] = ['item 5', 'item 6'];
Vue.set(state, 'tables', newList);
}
}
})
const mytable = Vue.component('mytable', {
props: ['title', 'data'],
template: `
<div>
<div> {{ title }} ({{ now() }}) </div>
<div v-for="(item, index) in data" :key="index">{{ item }}</div>
<hr>
</div>
`,
methods: {
now() {
const date = new Date();
return date.toLocaleTimeString();
}
},
updated() {
console.log(`${this.title} updated at ${this.now()}`)
}
})
const app = new Vue({
store,
components: { mytable },
template: `
<div>
<button @click="mutate1st">Mutate 1st table data</button>
<button @click="mutateTables">Mutate tables array</button>
<button @click="replaceTables">Replace tables array</button>
<button @click="newArrayCreatedFromPreviousOnes">Just for curiosity...</button>
<button @click="sameWayAsInQuestion">Same way as in question</button>
<hr>
<mytable v-for="(table, index) in $store.state.tables" :key="index" :title="'Table ' + index" :data="table" />
</div>
`,
methods: {
...Vuex.mapMutations(['mutate1st', 'mutateTables', 'replaceTables', 'newArrayCreatedFromPreviousOnes', 'sameWayAsInQuestion'])
}
})
app.$mount("#app")
答案 1 :(得分:0)
更新:我在Table.vue中还有另一个组件,该组件依赖于存储变量,该存储变量在更改t1时发生了突变,导致其余表发生更改。每日提示:检查所有嵌套组件是否不依赖于受更改影响的某些存储变量