Skip to content
Advertisement

Vue.js directives on html rendering

I made this pen. Simple tabs using Vue.js.

Each tab get it’s content from this object:

var tabs = [
  {
    title: "Pictures",
    content: "Pictures content"
  },
  {
    title: "Music",
    content: "Music content. Wanna see some <a @click.prevent="show = 3">Documents</a> content?"
  },
  {
    title: "Videos",
    content: "Videos content."
  },
    {
    title: "Documents",
    content: "Documents content. Wanna see some <a @click.prevent="show = 1">Music</a> content?"
  },   
];

To render each tab content:

<div v-for="(tab, index) in tabs" v-if="show == index" :key="index" v-html="tab.content"></div>

I’m stuck trying to make those click directives on ‘tab.content’ work 🙁 Am I missing something?

Thanks in advance.

Advertisement

Answer

v-html is not Vue content, it is simply innerHTML for an element. You will not be able to use Vue directives or components(!) in v-html content.

What you can do is catch and handle a native click event inside a component. The transition-group is convenient.

const tabs = [{
    title: "Pictures",
    content: "Pictures content"
  },
  {
    title: "Music",
    content: "Music content. Wanna see some <a data-show="3">Documents</a> content?"
  },
  {
    title: "Videos",
    content: "Videos content."
  },
  {
    title: "Documents",
    content: "Documents content. Wanna see some <a data-show="1">Music</a> content?"
  },
];

var vue = new Vue({
  el: "#app",
  data: {
    show: 0,
    tabs
  },
  methods: {
    navigate(event) {
      const target = event.target;

      if (target.dataset.show) {
        event.preventDefault();
        this.show = target.dataset.show;
      }
    }     
  }
});
.section {
  padding: 2em 0;
}

.fade-up-enter-active,
.fade-up-leave-active {
  transition: all 0.3s ease-in-out;
}

.fade-up-enter,
.fade-up-leave-to {
  height: 0;
  transform: translateY(30px);
  opacity: 0;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div class="container section" id="app">
  <div class="tabs">
    <ul>
      <li v-for="(tab, index) in tabs" :class="{'is-active': show == index}"><a @click.prevent="show = index">{{tab.title}}</a></li>
    </ul>
  </div>
  <div class="texts">
    <transition-group name="fade-up" target="div" appear  @click.native="navigate">
      <div v-for="(tab, index) in tabs" v-if="show == index" :key="index" v-html="tab.content"></div>
    </transition-group>
  </div>
</div>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement