Search code examples
javascriptvue.jsvuejs2vue-component

Vuejs v-bind v-for not populating into component template


with html

  <div id="app">
    <gallery v-bind:links="['link1.jpg', 'link2.jpg']" />
  </div>

and component definition:

    Vue.component('gallery', {
      template: `
        <div v-if="!isReady">
        not ready
        </div>
        <div v-else>
          <image-grp v-for="src in links">
            <img v-bind:src="src">
          </image-grp>
        </div>
      `,
      data() {
        return {
          links: [],
          isReady: false
        }
      },
      mounted() {
        this.links = this.$el.getAttribute('links').split(',')
        this.isReady = true
        console.log(this.links);
      }
    });

I've managed to produce this html:

<div links="link1.jpg,link2.jpg">
  <div class="image">
    <img src="">
  </div>
  <div class="image">
    <img src="">
  </div>
</div>

The images are not showing up because of the empty src. The src should be filled in during the loop on src in links. The array links must be filled properly, cause the html shows the same number of image-grp elements as are in the links array.

I have tried a variety of ways to populate/bind/mustache the src into the dynamic <img src=""> elements. Any guidance would be appreciated.


Solution

  • I don't see any problems with your code. It works.

    But you should better make links to props, like this:

    props: ['links']
    

    Then, the other commented out lines are not needed.

    Playground

    Vue.component('gallery', {
      props: ['links'],
      template: `
        <div v-if="!isReady">
        not ready
        </div>
        <div v-else>
          <image-grp v-for="src in links">
            <img v-bind:src="src">
          </image-grp>
        </div>
      `,
      data() {
        return {
          //links: [],
          isReady: false
        }
      },
      mounted() {
        //this.links = this.$el.getAttribute('links').split(',');
        this.isReady = true;
      }
    });
    
    const app = new Vue({
        el: '#app'
    })
    img {
      width: 100px;
      height: 100px;
      margin: 4px;
    }
    <div id="app">
       <gallery v-bind:links="['https://i.sstatic.net/NxnaT.jpg?s=256&g=1', 'https://www.gravatar.com/avatar/50309120892edf29dcb2188bdabe3b08?s=256&d=identicon&r=PG']"></gallery>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>