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

前端 未结 3 625
迷失自我
迷失自我 2021-02-02 03:05

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

My parent template


  link 1
  

        
相关标签:
3条回答
  • 2021-02-02 03:51

    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

    0 讨论(0)
  • 2021-02-02 03:52

    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>

    0 讨论(0)
  • 2021-02-02 03:54

    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>
    
    0 讨论(0)
提交回复
热议问题