Do you have a good solution to the problem that the view is not updated when the object properties are changed in vue?

A problem with the change of object properties is that the change of data will cause the view not to be updated, but the view has not been updated, so I searched the Internet and saw that someone said to use Vue.set and Object.assign to solve this problem

my effect is to take the data from the state during initialization and then manually pull down and refresh the data from the background and replace the articleList data in state
the following is the data of state at initialization

articleList: [
    {
      userinfo: {image: "static/img/3.jpeg", nickname: "eee", text: "", time: ""},
      content: {href: "2222222", text: "test", create_time: "", updata_time: ""},
      pic: [{path: "static/img/0.jpg"}, {path: "static/img/0.jpg"}, {path: "static/img/0.jpg"}],
      likebar: {hot: 555, status: false, comments: 666},
      isFollow: true
    },
    {
      userinfo: {image: "static/img/3.jpeg", nickname: "eee", text: "", time: ""},
      content: {href: "", photo: "", text: "test", create_time: "", updata_time: ""},
      pic: [{path: "static/img/0.jpg"}, {path: "static/img/1.jpg"}, {path: "static/img/3.jpeg"}],
      likebar: {hot: 555, status: false, comments: 666},
      isFollow: false
    }
  ],

first I tried it with Vue.set, but the data displayed after the first drop-down refresh is not correct
mutation.js

updateList (state, data) {
    Vue.set(this.state, "articleList", data)
    console.log(this.state.articleList)
}

later, I used Object.assign to try the first drop-down refresh to update the data displayed in the view, but in the second and third drop-down refresh, if the background data changes, but the view is still the first drop-down refresh, the result is that the view can be updated the first time, but the view cannot be updated later. I don"t know if this is an Object.assign problem
object. The problem of attribute update has not been solved for two days. I don"t know if you have a good way.

mutation.js

updateList (state, data) {
    this.state.articleList = Object.assign({}, this.state.articleList, data)
    //this.state.articleList = Object.assign({}, data) //
    console.log(this.state.articleList)
  }
May.09,2022

updateList (state, data) {
    this.state.articleList = data
    // state.articleList = data
}

if you are not using modules and the index.js is:

import mutations from './mutations'
...
const store = new Vuex.Store({
  state: {
    ...    
  },
  mutations,
  actions,
  getters
})

then there should be no problem. Check to see if there is a problem with the interface data returned.


ide/mutations.html-sharpmutation-%E9%9C%80%E9%81%B5%E5%AE%88-vue-%E7%9A%84%E5%93%8D%E5%BA%94%E8%A7%84%E5%88%99" rel=" nofollow noreferrer "> https://vuex.vuejs.org/zh/gui...


this.articleList=JSON.parse (JSON.stringify ( This.articleList)


go and test the code yourself. I've already answered your question.
online preview that can climb over walls: https://codesandbox.io/s/z6mp...
can't climb over walls. Use the following code to test

store several files
state.js

.
export default {
  articleList: [
    {
      userinfo: {
        image: "static/img/3.jpeg",
        nickname: "eee",
        text: "",
        time: ""
      },
      content: {
        href: "2222222",
        text: "test",
        create_time: "",
        updata_time: ""
      },
      pic: [
        { path: "static/img/0.jpg" },
        { path: "static/img/0.jpg" },
        { path: "static/img/0.jpg" }
      ],
      likebar: { hot: 555, status: false, comments: 666 },
      isFollow: true
    }
  ]
};

mutations.js

export default {
  updateList(state, data) {
    state.articleList = data;
  }
};

getters.js

export default {
  articleList: state => state.articleList
};

actions.js

export default {
  getLists({ commit, state }) {
    //
    setTimeout(() => {
      //
      const newArticleList = [
        {
          userinfo: {
            image: "static/img/3.jpeg",
            nickname: "eee",
            text: "1",
            time: "1"
          },
          content: {
            href: "2222222",
            text: "test",
            create_time: "",
            updata_time: ""
          },
          pic: [
            { path: "static/img/0.jpg" },
            { path: "static/img/0.jpg" },
            { path: "static/img/0.jpg" }
          ],
          likebar: { hot: 555, status: false, comments: 666 },
          isFollow: true
        },
        {
          userinfo: {
            image: "static/img/3.jpeg",
            nickname: "eee",
            text: "2",
            time: "2"
          },
          content: {
            href: "2222222",
            text: "test",
            create_time: "",
            updata_time: ""
          },
          pic: [
            { path: "static/img/0.jpg" },
            { path: "static/img/0.jpg" },
            { path: "static/img/0.jpg" }
          ],
          likebar: { hot: 555, status: false, comments: 666 },
          isFollow: true
        }
      ];
      //commit
      commit("updateList", newArticleList);
    }, 2000);
  }
}

index.js

import Vue from "vue";
import Vuex from "vuex";

import getters from "./getters";
import actions from "./actions";
import mutations from "./mutations";
import state from "./state";

Vue.use(Vuex);

export default new Vuex.Store({
  getters,
  actions,
  mutations,
  state
});

Page Code

<template>
  <div>
    <div v-for="(article, index) in articleList" :key="index">
      <div>{{ article }}</div>
      <hr />
    </div>
    <button @click="onClick"></button>
  </div>
</template>

<script>
import { mapGetters, mapActions} from "vuex";
export default {
  computed: {
    ...mapGetters(["articleList"])
  },
  methods: {
    ...mapActions(["getLists"]),
    onClick() {
      this.getLists();
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
Menu