vue组件插槽

113 阅读1分钟

匿名插槽和具名插槽

使用组件时,可以使用插槽往组件里插入一些不属于组件模板的自定义内容,插槽标签用<slot></slot>表示。
设置了 name 属性的 slot 标签叫做具名插槽,没有设置 name 属性 slot 标签叫做匿名插槽。
想要插入的内容设置了 slot 属性,值为对应具名插槽的name属性值,就会插入对应的具名插槽内,如<h2 slot="s1">具名插槽s1</h2> 。如果设置了 slot 属性,但没有对应的具名插槽,则不会被插入。
其它没有设置 slot 属性的内容会被统一插入匿名插槽,若没有设置匿名插槽,则不被插入。

// DemoOne.vue

<template>
  <div>
      <hr>
      <!-- 匿名插槽 -->
      <slot></slot>
      <h1>DemoOne</h1>
      <!-- 具名插槽s1 -->
      <slot name="s1"></slot>
  </div>
</template>

<script>
export default {
    name:'DemoOne',
    data(){
        return {
            msg:'插槽s1的值',
            str:'插槽s2的值'
        }
    }
}
</script>
// App.vue

<template>
  <div id="app">
    <h1>App</h1>
    <DemoOne>
      <h2>匿名插槽</h2>
      <h2 slot="s1">具名插槽s1</h2>
    </DemoOne>
  </div>
</template>

<script>
import DemoOne from '@/components/DemoOne.vue'

export default {
  name:'App',
  components:{
    DemoOne
  }
}
</script>

插槽传值

slot-scope
vue2.5及之前的版本使用 slot-scope 属性来接收插槽传过来的,属性值为任意名对象,传过来的值存在对象中。

v-slot
vue2.6及之后的版本使用 v-slot 取代了 slot-scope,想要插入插槽内容需用template标签包裹,具名插槽用法:使用 v-slot:插槽name值="scope" 取代name="s2",匿名插槽用法:v-slot="scope",scope 值为对象 可以接收插槽传的值。

// App.vue
<template>
  <div id="app">
    <h1>App</h1>
    <DemoOne>
      <h2 slot="s1" slot-scope="scope">插槽s1--{{scope.msgv}}</h2>
      <!-- vue2.6之后的版本 v-slot取代了 slot-scope
           想要插入插槽内容需用template标签包裹
           使用 v-slot:插槽name值="scope" 取代name="s2"
           scope 值为对象 可以接收插槽传的值  -->
      <!-- v-slot具名插槽写法 -->
      <template v-slot:s2="scope">
        <h2>插槽s2--{{scope.str}}</h2>
      </template>
      <!-- v-slot匿名插槽写法 -->
      <template v-slot="scope">
        <h2>匿名插槽--{{scope.str}}</h2>
      </template>
    </DemoOne>
    
    <!-- 点击a标签可以在控制台打印插槽传过来的对象信息 -->
    <demo-two>
      <template slot-scope="scope">
        <a href="javascript:;" @click="handler(scope.row)">查看</a>
      </template>
    </demo-two>
  </div>
</template>

<script>
import DemoOne from '@/components/DemoOne.vue'
import DemoTwo from '@/components/DemoTwo.vue'

export default {
  name:'App',
  components:{
    DemoOne,
    DemoTwo
    
  },
  methods:{
    handler(row){
      console.log(row);
    },
  }
}
</script>
// DemoOne.vue
<template>
  <div>
      <hr>
      <slot name="s1" :msgv="msg"></slot>
      <h1>DemoOne</h1>
      <slot name="s2" :str="str"></slot>
      <slot :str="str2"></slot>
  </div>
</template>

<script>
export default {
    name:'DemoOne',
    data(){
        return {
            msg:'插槽s1的值',
            str:'插槽s2的值',
            str2:'匿名插槽的值'
        }
    }
}
</script>
// DemoTwo.vue
<template>
  <div>
      <hr>
      <h1>DemoTwo</h1>
      <ul>
          <li v-for="(v,i) in list" :key="i">
              {{v.name}}--{{v.age}}
              <slot :row="v"></slot>
          </li>
      </ul>
  </div>
</template>

<script>
export default {
    name:'DemoTwo',
    data(){
        return {
            list:[{
                name:'张三',
                age:20
            },
            {
                name:'李四',
                age:30
            },{
                name:'王五',
                age:35
            }]
        }
    }
}
</script>