Andy
Andy

Reputation: 191

How dynamically change the component with object for props in vueJS

Do you know how to change a component dynamically with object prop

App.vue

<template>
  <div id="app">
    <component :is="current['test'].target.name"> </component>
    <input type="button" value="click me" @click="change" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
import Comp from "./components/Comp.vue";

export default {
  name: "App",
  components: {
    HelloWorld,
    Comp,
  },
  data() {
    return {
      current: {},
    };
  },
  created() {
    this.current["test"] = {
      index: 0,
      target: {
        name: "Comp",
      },
    };
  },
  methods: {
    change() {
      const r =
        this.current["test"].target.name === "HelloWorld"
          ? "Comp"
          : "HelloWorld";
      this.current["test"].target = {
        name: r,
      };
      console.log(this.current["test"]);
    },
  },
};
</script>

Comp.vue

<template>
  <p>Template 2</p>
</template>

HelloWorld.vue

<template>
  <p>Template 1</p>
</template>

https://codesandbox.io/s/clever-water-dgbts?file=/src/components/HelloWorld.vue:0-42

The value of the object will change correctly but not the component.

Thank you

Upvotes: 0

Views: 533

Answers (1)

Will Blair
Will Blair

Reputation: 103

The issue here is that the property test is not defined on the object current in the data definition - you're setting the definition in the created() function. This means that Vue does not know to create the reactive getter/setter for that property.

Change your data definition to:

data() {
  return {
    current: {
      test: {
        index: 0,
        target: {
          name: "Comp"
        }
      }
    }
  };
}

It is because of the way Vue does its reactivity (requiring pre-defined properties) that I would recommend steering clear of accessing properties as dictionary items i.e. use:

current.test.target.name

instead of

current['test'].target.name

For more information on Vue reactivity see this page: link

Upvotes: 1

Related Questions