计算值更改时组件不重新渲染

Posted

技术标签:

【中文标题】计算值更改时组件不重新渲染【英文标题】:Component not rerendering when Computed Value changes 【发布时间】:2019-09-15 08:05:25 【问题描述】:

当计算值发生变化时,我的PreviewExerciseItem 不会重新呈现。计算的值是我的 vuex 存储中的 getter。

我没有改变我的 vuex 状态,我设置了一个新的对象。这是我的突变:

selectedWorkout: (state, workout) => 
  state.selectedWorkout = ...workout;

吸气剂:selectedWorkout: (state) => state.selectedWorkout,

这是我的组件。当我的 selectedWorkout 更改但 h1 about 正在正确更新时,PreviewExerciseItem 组件不会重新呈现

<template>
    <div v-if="selectedWorkout">
        <h1 v-if="selectedWorkout">selectedWorkout.exercises[1].progression</h1>
        <PreviewExerciseItem v-for="(exercise, index) in selectedWorkout.exercises" :key="exercise.presetKey" 
            :exercise="exercise" :index="index" :selected="selectedExercise === index"
            v-on:click.native="selectedExercise = index"/>

    </div>
</template>

<script>

import db from '@/api/db'
import  mapGetters, mapActions, mapState  from "vuex";
import PreviewExerciseItem from "@/components/PreviewExerciseItem.vue"


export default 
    components: 
        PreviewExerciseItem
    ,
    async asyncData( store, params ) 
        await store.dispatch('selectedRoutine', params.id);
        return  routineId: params.id 
    ,
    computed: 
        ...mapGetters(['user', 'selectedRoutine', 'selectedWorkout']),
    ,
    watch: 
        user: async function (user) 
            const status = await db.fetchRoutineStatus(user.uid, this.routineId);
            this.$store.dispatch('selectedWorkout', status);
            console.log('Workout1', this.selectedWorkout) // Logs correctly updated Object
        ,
        selectedWorkout: function (selectedWorkout) 
            this.workout = ...selectedWorkout;
            console.log('Workout2', this.selectedWorkout) // Also updated object
            this.$forceUpdate();    // Not doing anything
        
    ,

</script>

编辑:问题可能与我的突变有关。当我使用state.selectedWorkout = JSON.parse(JSON.stringify(workout)); 而不是state.selectedWorkout = ...workout; 时,它可以工作。我以为state.selectedWorkout = ...workout; 会分配一个新对象,但似乎没有。我不太喜欢 JSON 解决方案,有没有更好的方法来分配新的 Objet?我还尝试了state.selectedWorkout = Object.assign(, workout),它也不起作用。

【问题讨论】:

Object.assign 和 ... 不起作用,因为它仅在第一级中断引用,如果您在其中嵌套了对象或数组,则不会中断对它们的引用。所以我猜你已经嵌套了一个对象/数组。 Deepclone 解决了这个问题,因为它破坏了每个嵌套级别的引用 【参考方案1】:

您需要使用此表单JSON.parse(JSON.stringify(workout)); 来深度克隆workout 对象。

Deep Clone

【讨论】:

以上是关于计算值更改时组件不重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

如何在其他组件的状态更改时重新渲染 DOM

React 组件不会在值更改时重新渲染并显示 CSS 更改

属性更改时如何重新渲染反应组件

Mobx 仅在计算值更改时重新渲染项目

在道具更改时重新渲染功能组件

Vue 计算属性已更新,但组件未重新渲染