14

I have three templates. AddCard.vue , ImageCard.vue and VideoCard.vue

AddCard.vue has two buttons on it one is to add the Image Card and Other To Add the video Card.. I need to add components based on the button click. Here are three templates and my index.html file.

index.html

   <!doctype html>
    <html lang="en">
        <head>

        </head>
        <body>
            <div id="app">
                 <div class="container">
                    <div id="dynamic_components">
                     <!-- add components here -->
                    </div>
                    <addcard></addcard>
                </div>
            </div>
            <script src="{{ asset('js/app.js') }}"></script>
        </body>
    </html>

AddCard.vue

<template>
    <div class="buttons">
        ul class="no-margin-list">
                                <li @click="imagecard">
                                  <span class="card_icon">
                                      <img :src="'img/image.jpg'" >
                                    </span>
                                    <p>Add Image Card</p>
                                  </a>
                                </li>

                            <li @click="videocard">
                                  <span class="card_icon">
                                      <img :src="'img/video.jpg'" >
                                    </span>
                                    <p>Add Video Card</p>
                                  </a>
                              </li>
    </div>
</template>
<script>
  export default {
    computed: {

    },
    methods: {
      imagecard(val) {
        //how to add image card
      },
      videocard() {
        //how to add video card 
      }
    },

  }
</script>

ImageCard.vue

<template>
    <h1> I am a image Card </h1>
</template>
<script>

</script>

VideoCard.vue

<template>
    <h1> I am a Video Card </h1>
</template>
<script>

</script>

I need to add components dynamically one after another in the <div id="dynamic_components"> . User can add as many as cards they want.

How do I add the components dynamically. Please point me to a tutorial.

3
  • 1
    Keep data-driven in mind. for your cases, define one array as data/computed property=cards like [{'card-content':{}, 'card-type':'image'}, {'card-content':{}, 'card-type':'image'}], then in your template, <div> <!-- add components here --><template v-for="(card, index) in cards" :key="index" :is="card['card-type']"></template> </div> Commented Jun 1, 2018 at 21:02
  • @Sphinx , so each time the user clicks the button , I need to push the new array element in the computed property and v-for will take care of rendering it on the UI. Commented Jun 1, 2018 at 21:10
  • @Sphinx Please write an answer, you just provided a great answer but as a comment... Commented Jun 1, 2018 at 21:13

1 Answer 1

10

Uses v-for + dynamic component.

Vue.config.productionTip = false

Vue.component('card1', {
  template: '<div>Card:<span style="background-color:green">{{title}}</span></div>',
  props: ['title']
})

Vue.component('card2', {
  template: '<div>Card:<span style="background-color:blue">{{title}}</span></div>',
  props: ['title']
})

Vue.component('card3', {
  template: '<div>Card:<span style="background-color:yellow">{{title}}</span></div>',
  props: ['title']
})

new Vue({
  el: '#app',
  data() {
    return {
      cards: [
        {'card': {'title': 'I am one card1'}, 'card-type':'card1'},
        {'card': {'title': 'I am one card2'}, 'card-type':'card2'}
      ]
    }
  },
  computed: {
    computedNoCard1: function () {
      let availableCards = new Set(['card2', 'card3'])
      return this.cards.filter((item) => {
        return availableCards.has(item['card-type'])
      })
    }
  },
  methods: {
    addCard: function () {
      let supportedCards = ['card1', 'card2', 'card3']
      let seed = Math.floor(Math.random()*supportedCards.length)
      this.cards.push({'card': {'title': 'I am new card for ' + supportedCards[seed]}, 'card-type': supportedCards[seed]})
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<button @click="addCard()">Add Card</button>
  <table>
  <tr><th>Data Property</th><th>Computed Property</th></tr>
  <tr>
  <td>
    <div v-for="(card, index) in cards" :key="index">
      <component  :is="card['card-type']" :title="card.card.title">
      </component>
    </div>
  </td>
  <td>
    <div v-for="(card, index) in computedNoCard1" :key="index">
      <component  :is="card['card-type']" :title="card.card.title">
      </component>
    </div>
  </td>
  </tr>
  </table>
  
</div>

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

1 Comment

how do I pass the values from app.js to the template files. For example how to pass the value of message to the ImageCard.vue template file. When the user clicks the Image Card.

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.