Djave
Djave

Reputation: 9349

Vue/Vuex dynamic component not changing

I have a vuex store of "nodes". Each one has a type of Accordion or Block.

{
  "1":{
    "id":1,
    "title":"Default title",
    "nodes":[],
    "type":"Block"
  },
  "2":{
    "id":2,
    "title":"Default title",
    "nodes":[],
    "type":"Accordion"
  }
}

When I use the type to create a dynamic component it works great:

<ul>
  <li v-for="(node, s) in nodes" :key="parentId + s">
    <component :is="node.type" :node="node" :parent-id="parentId"></component>
  </li>
</ul>

But when I change it, nothing happens in the view layer:

convert(state, { to, id }) {
  state.nodes[id].type = to;
  Vue.set(state.nodes[id], "type", to);
},

I even use Vue.set. How can I make this update?

It updates immediately if I then push another node into the array.


CodeSandbox:

https://codesandbox.io/s/romantic-darwin-dodr2?file=/src/App.vue

Upvotes: 0

Views: 103

Answers (1)

lightmyfire
lightmyfire

Reputation: 174

The thing is that your getter will not work, because it's not pure: Issue. But you can use deep watcher on your state instead:

<template>
  <div class="home">
    <h1>Home</h1>
    <Sections :sections="nodesArr" :parent-id="null"/>
  </div>
</template>

<script>
// @ is an alias to /src
import Sections from "@/components/Sections.vue";
import { mapState } from "vuex";

export default {
  name: "home",
  components: {
    Sections
  },
  data: () => {
    return {
      nodesArr: []
    };
  },
  computed: {
    ...mapState(["nodes", "root"])
  },
  watch: {
    root: {
      handler() {
        this.updateArr();
      },
      deep: true
    }
  },
  mounted() {
    this.updateArr();
  },
  methods: {
    updateArr() {
      this.nodesArr = this.root.map(ref => this.nodes[ref]);
    }
  }
};
</script>

Upvotes: 2

Related Questions