Use a template in vue component passed as a prop

Viewed 1319

I'm a total newbie, so please bear with me if I'm still grasping with the coding fundamentals.

I want to use a template that is defined in the prop. The template is inside the DOM. The reason I want to do it this way is that I want to reuse the component logic (specifically the pagination), but may want to change how the way the template displays the data in different pages. So I wanted to seaparate the template from the script file.

This is the HTML File:

<div id="store-list">
  <paginated-list :list-data="stores" use-template="#displayList"></paginated-list>
</div>

<script type="text/template" id="display-list">
  <div>
    <div v-for="p in paginatedData">
      {{p.BusinessName}} 
    </div>
  </div>
</script>

This is the .js file:

Vue.component('paginated-list', {
  data() {
    return {
      pageNumber: 0
    }
  },
  props: {
    listData: {
      type: Array,
      required: true
    },
    useTemplate: {
      type: String,
      required: false
    },
    size: {
      type: Number,
      required: false,
      default: 10
    }
  },
  computed: {
    pageCount() {
      let l = this.listData.length,
        s = this.size;
      return Math.floor(l / s);
    },
    paginatedData() {
      const start = this.pageNumber * this.size,
        end = start + this.size;
      return this.listData
        .slice(start, end);
    }
  },
  //template: document.querySelector('#display-list').innerHTML // this works
  template: document.querySelector(useTemplate).innerHTML // this does not
});

var sl = new Vue({
  el: '#store-list',
  data: {
    stores: [{
      "BusinessName": "Shop Number 1"
    }, {
      "BusinessName": "Shop Number 2"
    }, {
      "BusinessName": "Shop Number 3"
    }]
  }
});
var shoppingList = new Vue({
  el: '#shopping-list',
  data: {
    header: 'shopping list app',
    newItem: '',
    items: [
      '1',
      '2',
      '3',
    ]
  }
})

Any help is greatly appreciated. Thank you.

1 Answers

You can use the inline-template attribute to override the component's template at render time. For example

<paginated-list :list-data="stores" inline-template>
  <div>
    <div v-for="p in paginatedData">
      {{p.BusinessName}} 
    </div>
  </div>
</paginated-list>

See https://v2.vuejs.org/v2/guide/components-edge-cases.html#Inline-Templates

Your component can still have a default template but this will override it if set.

Related