ThomasD
ThomasD

Reputation: 2494

set property and retrieve HTML as string from Vue component

In order to separate my code and make it cleaner, I would like to use a Vue component as an HTML template, pass some parameters to the template and get the resulting HTML back as a string.

I have made a simple example that almost works, but for some reason the returned HTML is not up to date. When I hit "click me" I do get an HTML-string from the "MyDetails"-component, but it shows the value passed from the previous time, I hit the "click me"-button, instead of showing the actual value.

Main.vue

<template>
  <div>
    <p>
      <myDetails ref="myDetails"/>
    </p>
    <button @click="handleClick">click me</button>
    <p>{{message}}</p>
  </div>
</template>

<script>
import MyDetails from "/components/MyDetails.vue";

export default {
  name: "hello",
  components: {
    MyDetails
  },
  methods: {
    handleClick() {
      this.$refs.myDetails.setMessage(new Date().getTime());
      this.message = this.$refs.myDetails.$el.outerHTML;
    }
  },
  data() {
    return {
      message: ""
    };
  }
};
</script>

MyDetails.vue

<template>
  <div style="background-color:red">
    <h1>MyDetails component</h1>
    <p>{{message}}</p>
  </div>
</template>
<script>
export default {
  name: "hello",
  data() {
    return {
      message: ""
    };
  },
  methods: {
    setMessage(value) {
      this.message = value;
    }
  }
};
</script>

In the example above "MyDetails" is part of the template from the beginning. Is it possible to load it dynamically in the click-handler instead, so it doesn't show up, before I hit the "click me"-button?

Please see code here: https://codesandbox.io/s/vue-fullcalendar-example-50sv9?fontsize=14&hidenavigation=1&theme=dark

Upvotes: 0

Views: 938

Answers (1)

akuiper
akuiper

Reputation: 214927

Updating the DOM takes time, you are immediately getting the myDetails outerHTML after you are changing its data, which doesn't give time for the change to propagate. Setting a slight delay as follows will give output as expected:

handleClick() {
    this.$refs.myDetails.setMessage(new Date().getTime());
    setTimeout(() => {
        this.message = this.$refs.myDetails.$el.outerHTML;
    }, 100) 
}

For demo, see the sandbox here

Upvotes: 1

Related Questions