Skip to content

Instantly share code, notes, and snippets.

@elpete
Created September 6, 2017 14:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elpete/7068308c5a1bf4f1a0f44f8d0259a9a2 to your computer and use it in GitHub Desktop.
Save elpete/7068308c5a1bf4f1a0f44f8d0259a9a2 to your computer and use it in GitHub Desktop.
Nested scoped slots in Vue templates
<template>
<manage-lists v-model="items">
<template scope="{ item: user }">
{{ user.firstName }} {{ user.lastName }}
</template>
</manage-lists>
</template>
<script>
export default {
components: {
ManageLists
},
data() {
return {
items: [
{ firstName: "John", lastName: "Doe" },
{ firstName: "Renae", lastName: "McGillicuddy" }
]
};
}
}
</script>
<template>
<div>
<token-list :value="items" @input="forwardInput">
<template scope="props">
<slot v-bind="props"></slot>
</template>
</token-list>
<form class="form" @submit.prevent="handleAdd">
<input type="text" placeholder="New Item" v-model="newItem" ref="newItem" />
<button type="submit">Add Item</button>
</form>
</div>
</template>
<script>
import TokenList from "./TokenList";
export default {
props: {
value: {
type: Array,
default() {
return [];
}
}
},
components: {
TokenList
},
methods: {
handleAdd() {
this.$emit( "input", this.value.concat( this.newItem ) );
this.newItem = "";
this.$refs.newItem.focus();
},
forwardInput( payload ) {
this.$emit( "input", payload );
}
}
}
</script>
<template>
<div class="token-list clearfix">
<div v-for="( item, index ) in value" class="token-item">
<slot :item="item" :index="index">
<span>{{ item }}</span>
<button type="button" @click="remove( index )">&times;</button>
</slot>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
required: true
}
}
methods: {
remove( index ) {
this.$emit( "input", [
...this.value.slice( 0, index ),
...this.value.slice( index + 1 )
] );
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment