How to render a list of static content with Vue named slot?
This is easily accomplished with a render function.
Vue.component("comp", { render(h){ let links = this.$slots.links.map(l => h('li', {class: "comp-item"}, [l])) return h('ul', {class: 'comp'}, links) }})
Here is a working example.
console.clear()Vue.component("comp", { render(h){ let links = this.$slots.links.map(l => h('li', {class: "comp-item"}, [l])) return h('ul', {class: 'comp'}, links) }})new Vue({ el: "#app"})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><div id="app"> <comp> <a href="#" slot="links">link 1</a> <a href="#" slot="links">link 2</a> </comp></div>
Or with the help of a small utility component for rendering vNodes you could do it like this with a template.
Vue.component("vnode", { functional: true, render(h, context){ return context.props.node }})Vue.component("comp", { template: ` <ul class="comp"> <li class="comp-item" v-for="link in $slots.links"><vnode :node="link" /></li> </ul> `})new Vue({ el: "#app"})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><div id="app"> <comp> <a href="#" slot="links">link 1</a> <a href="#" slot="links">link 2</a> </comp></div>
You can make use of scoped slots instead of slots
Your comp
component receives a prop links
which is an array of links(since static initialized as a custom option). Iterate over the links
and pass link
as data to the slot just like passing props to a component
Vue.component("comp", { template: ` <ul class="comp"> <li class="comp-item" v-for="link in links"> <slot v-bind="link"></slot> </li> </ul> `, props: ["links"]})new Vue({ el: "#app", // custom static option , accessed using vm.$options.links links: [ {text: "link1"}, {text: "link2"}, {text: "lin3"} ]})
In the parent where the comp
component is used make use of a <template>
element with a special attribute slot-scope
, indicating that it is a template for a scoped slot.
The value of slot-scope
will be used as the name of a temporary variable that holds the props object passed from the child:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><div id="app"> <comp :links="$options.links"> <template slot-scope="link"> <a href="#">{{link.text}}</a> </template> </comp></div>
Here is the working fiddle
If you don't like to put your data in array, and render list with v-for
You can put all of them in the component, no slot:
<ul class="comp"> <li class="comp-item"><a href="#">link 1</a></li> <li class="comp-item"><a href="#">link 2</a></li></ul>
or with slot:
<comp> <ul class="comp" slot="links"> <li class="comp-item"><a href="#">link 1</a></li> <li class="comp-item"><a href="#">link 2</a></li> </ul></comp>