TagsProvider

Let's see how to implement the TagsProvider components to better understand the renderless components.

In this lesson, we create a TagsProvider application that adds and deletes tags. Similar to the ToggleProvider component, it will contain only business logic and no markup of its own, as all the necessary properties and methods are passed via scoped slots.

Implementation

Here’s the implementation for the TagsProvider component.

Press + to interact
// components/common/TagsProvider.vue
<script>
export default {
emits: ['on-tag-added', 'on-tag-deleted'],
render() {
// Destructure and values via scoped slot
const {tags, addTag, deleteTag} = this
// this.$scopedSlots.default() in Vue 2
return this.$slots.default({
tags,
addTag,
deleteTag,
})
},
props: {
options: {
type: Array,
default: () => [],
},
trackBy: {
type: String,
},
},
data() {
return {
tags: [...this.options],
}
},
watch: {
options: {
handler(value) {
if(Array.isArray(value)) this.tags = [...value]
},
immediate: true,
},
},
methods: {
addTag(value) {
this.tags.push(value)
this.$emit('on-tag-added', {
tags: this.tags,
value
})
},
deleteTag(value) {
if(this.trackBy) {
this.tags = this.tags.filter(tag => tag[this.trackBy] !== value)
} else {
// We have no trackBy property, so we assume
// that the value passed is an index
this.tags.splice(value, 1)
}
this.$emit('on-tag-deleted', {
tags: this.tags,
value
})
},
/**
* Used via ref to extract tags
*/
getTags() {
return this.tags
},
},
}
</script>

Let’s go through what’s happening in this component because this example is a bit more complicated.

Props

We have two props, options and trackBy, as seen below.

Press + to interact
props: {
options: {
type: Array,
default: () => [],
},
trackBy: {
type: String,
},
},

The options prop is used to specify default values for the tags. When assigned to the tags property, options are cloned using the spread operator to avoid mutation via reference. A default value is used if the parent component doesn’t pass the options prop. The trackBy prop, on the other hand, is used to handle the case when the options object isn’t an array of strings, but objects. It’s used in the removeTag method to filter out the tag that’s supposed to be removed.

The watch operator

We have a watcher for the options array as ...