Dynamic Scope Slots (Vue.js)

An example demonstrating how to use the scoped slots feature of vue.js (available as of version 2.10.0) to dynamically provide a template for a field in a table.

by Steve

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<script type="x-template" id="items">
<table class="table table-striped">
	<thead>
  <tr>
  	<td v-for="field in fields">
    	{{ field }}
    </td>
  </tr>
  </thead>
	<tbody>
 	<tr v-for="item in items">
  	<template v-for="field in fields">
    	<td v-if="typeof $scopedSlots[field] !== 'undefined'">
      	a<slot :name="field" :field="field" :item="item"></slot>
      </td>
      <td v-else>
      	{{ item[field] }}
      </td>
    </template>
  </tr>
  </tbody>
</table>
</script>

<div id="app" class="container-fluid">
  <h1>Dynamic Scoped Slots (Vue.js)</h1>
  <items :fields="fields" :items="items">
    <!-- Create a template for the 'first_name' field -->
    <template slot="email" scope="props">
      <a :href="'#mailto:'+props.item.email">{{ props.item.email }}</a>
    </template>
  </items>
</div>

JavaScript

Vue.component('items', {
	template: '#items',
  props: ['fields', 'items']
})

new Vue({
  el: '#app',
  data: {
  	fields: ['first_name', 'last_name', 'email'],
    items: [
    	{
      	first_name: 'Debra',
        last_name: 'Henderson',
        email: '[email protected]',
      },
      {
      	first_name: 'Henry',
        last_name: 'Franks',
        email: '[email protected]',
      }
    ]
  }
})