How to render a list of static content with Vue named slot?

Asked By: Anonymous

I have trouble figuring out how to get the following to work:

My parent template

<comp>
  <a href="#" slot="links>link 1</a>
  <a href="#" slot="links>link 2</a>
</comp>

and my component comp template looks like the following:

<ul class="comp">
  <li class="comp-item"><slot name="links"></slot></li>
</ul>

currently all my anchors goes to that single li tag (which is expected)
but I would like to be able to produce multiple li for every named slot I inserted like the following:

<ul class="comp">
  <li class="comp-item"><a href="#" slot="links>link 1</a></li>
  <li class="comp-item"><a href="#" slot="links>link 2</a></li>
</ul>

Is there any way to achieve what I need without using scoped slot? Because my content is pure HTML so I feel it is unnecessary to put static content inside prop in order to render them.

From what I have seen, most vue UI framework requires you to use another custom component for the list item, which I feel is over killed for the problem. Is there any other way to do this?


Solution

Answered By: Anonymous

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.

_x000D_

_x000D_

console.clear()_x000D_
_x000D_
Vue.component("comp", {_x000D_
  render(h){_x000D_
    let links = this.$slots.links.map(l => h('li', {class: "comp-item"}, [l]))_x000D_
    return h('ul', {class: 'comp'}, links)_x000D_
  }_x000D_
})_x000D_
_x000D_
new Vue({_x000D_
  el: "#app"_x000D_
})

_x000D_

https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js_x000D_
<div id="app">_x000D_
  <comp>_x000D_
    <a href="#" slot="links">link 1</a>_x000D_
    <a href="#" slot="links">link 2</a>_x000D_
  </comp>_x000D_
</div>

_x000D_

_x000D_

x000D

Or with the help of a small utility component for rendering vNodes you could do it like this with a template.

_x000D_

_x000D_

Vue.component("vnode", {_x000D_
  functional: true,_x000D_
  render(h, context){_x000D_
    return context.props.node_x000D_
  }_x000D_
})_x000D_
_x000D_
Vue.component("comp", {_x000D_
  template: `_x000D_
    <ul class="comp">_x000D_
      <li class="comp-item" v-for="link in $slots.links"><vnode :node="link" /></li>_x000D_
    </ul>_x000D_
  `_x000D_
})_x000D_
_x000D_
new Vue({_x000D_
  el: "#app"_x000D_
})

_x000D_

https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js_x000D_
<div id="app">_x000D_
  <comp>_x000D_
    <a href="#" slot="links">link 1</a>_x000D_
    <a href="#" slot="links">link 2</a>_x000D_
  </comp>_x000D_
</div>

_x000D_

_x000D_

x000D


Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen Windows 10 Lisans Office 2019 Mac Satın Al follower kaufen instagram follower kaufen porno