0

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.

2
  • it's working for me. What is the issue? Commented Dec 26, 2017 at 14:14
  • @samayo The issue was the "@click" inside the content. Was not working as expected. Luckily, a very good explanation was given here Commented Dec 26, 2017 at 15:19

1 Answer 1

2

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>

Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant, @Roy J :) Your explanation was very clear. I'll read more about native events on components(!).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.