vue slot详解

slot(插槽),简言之就是在组件添加一个占位的空间,在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动替换组件模板中

1.单个插槽
废话先不说,举个栗子往下瞅 ↓
父组件

<template>
  <div class="first-page">
    <div class="first-content">
        我来自父组件
      <child>
          <span style="color: red;">我将替换子组件插槽</span>
      </child>
  </div>
  </div>
</template>
<script type="text/javascript">
    import child from 'src/components/common/child.vue';
 
    export default {
        name: 'parent',
        data() {
            return {    
            }
        },
        mounted(){
          //界面加载完成后执行
        },
        methods:{
         
        },
        components:{
          // 用来声明页面组件  
          child
        }
    }
</script>
<style media="screen">
 
</style>

子组件

<template>
    <div class="sidebar">
       <h1>单个插槽</h1>
       <div class="slot"><slot></slot></div>
    </div>
</template>

<script>
    export default {
        data() {
            return {  
            }
        },
        computed:{
           
        }
    }
</script>

<style scoped>
    .sidebar{
        text-align: left;
    }
</style>

预览图
在这里插入图片描述
2.具名插槽 name - string,用于命名插槽。
区别于匿名插槽,当存在多个插槽的时候,当我们向在不同的插槽插入不同的内容,我们就需要用到匿名插槽
父组件

<template>
  <div class="first-page">
    <div class="first-content">
        我来自父组件
      <child>
          <span style="color: red;">我将替换子组件插槽</span>
          <!-- 替换子组件匿名插槽 -->

          <span slot="name_slot" style="color: #11caff;">我将替换子组件slot name="name_slot"的插槽</span>
          <!-- 替换子组件slot name="name_slot"的插槽 -->
      </child>

  </div>
  </div>
</template>
<script type="text/javascript">
    import child from 'src/components/common/child.vue';
 
    export default {
        name: 'parent',
        data() {
            return {    
            }
        },
        mounted(){
          //界面加载完成后执行
        },
        methods:{
         
        },
        components:{
          // 用来声明页面组件  
          child
        }
    }
</script>
<style media="screen">
 
</style>

子组件

<template>
    <div class="sidebar">
       <h1>单个插槽</h1>
       <div class="slot"><slot></slot></div>
       <h2>具名插槽</h2>
       <div class="nameSlot"><slot name="name_slot"></slot></div>
    </div>
</template>

<script>
    export default {
        data() {
            return {  
            }
        },
        computed:{
           
        }
    }
</script>

<style scoped>
    .sidebar{
        text-align: left;
    }
</style>

预览图

在这里插入图片描述
3.作用域插槽
作用域插槽提供了更加强大的功能

父组件

<template>
  <div class="first-page">
    <div class="first-content">
        我来自父组件
      <child :arrayData="arrayData">
          <span style="color: red;">我将替换子组件插槽</span>
          <!-- 替换子组件匿名插槽 -->

          <span slot="name_slot" style="color: #11caff;">我将替换子组件slot name="name_slot"的插槽</span>
          <!-- 替换子组件slot name="name_slot"的插槽 -->

          <span slot="array_data" style="color: green;" slot-scope="arrayData">{{arrayData}}</span>
          <!-- 预览图中绿色部分就是自定义插槽 -->
      </child>

  </div>
  </div>
</template>
<script type="text/javascript">
    import child from 'src/components/common/child.vue';
 
    export default {
        name: 'parent',
        data() {
            return { 
                arrayData: [
                    {id: 'a1', name: 'aa1',des: 'des1'},
                    {id: 'a2', name: 'aa2',des: 'des2'},
                    {id: 'a3', name: 'aa3',des: 'des3'}
                ]   
            }
        },
        mounted(){
          //界面加载完成后执行
        },
        methods:{
         
        },
        components:{
          // 用来声明页面组件  
          child
        }
    }
</script>
<style media="screen">
 
</style>

子组件

<template>
    <div class="sidebar">
       <h1>单个插槽</h1>
       <div class="slot"><slot></slot></div>
       <h2>具名插槽</h2>
       <div class="nameSlot"><slot name="name_slot"></slot></div>
       <h3>作用域插槽</h3>
        <div class="city">
           <li v-for="item in arrayData" :key="item.id">
               <span>id:{{item.id}}</span><span>name:{{item.name}}</span><span>des:{{item.des}}</span>
               <div class="tableSlot"><slot name="array_data" :city="item"></slot></div>
           </li>
       </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {  
            }
        },
        computed:{
           
        },
        props:["arrayData"]
    }
</script>

<style scoped>
    .sidebar{
        text-align: left;
    }
</style>

预览图

在这里插入图片描述
小结:简单来说,前两种插槽的内容和样式皆由父组件决定,也就是说显示什么内容和怎样显示都由父组件决定;但是第三种插槽就不同了,作用域插槽的样式由父组件决定,内容却由子组件控制。简单来说:前两种插槽不能绑定数据,作用域插槽是一个带绑定数据的插槽。

此时此刻我们已经了解了插槽的简单使用,还想看,那就继续看↓

另一个demo

父组件

<template>
  <div class="first-page">
    <div class="first-content">
        我来自父组件
      <child :arrayData="arrayData">
          <span style="color: red;">我将替换子组件插槽</span>
          <!-- 替换子组件匿名插槽 -->

          <span slot="name_slot" style="color: #11caff;">我将替换子组件slot name="name_slot"的插槽</span>
          <!-- 替换子组件slot name="name_slot"的插槽 -->

          <span slot="array_data" style="color: green;" slot-scope="arrayData">{{arrayData}}</span>
          <!-- 预览图中绿色部分就是自定义插槽 -->

          <template slot-scope="a">
            <p v-text="a.item"></p>
          </template>

      </child>

  </div>
  </div>
</template>
<script type="text/javascript">
    import child from 'src/components/common/child.vue';
 
    export default {
        name: 'parent',
        data() {
            return { 
                arrayData: [
                    {id: 'a1', name: 'aa1',des: 'des1'},
                    {id: 'a2', name: 'aa2',des: 'des2'},
                    {id: 'a3', name: 'aa3',des: 'des3'}
                ]   
            }
        },
        mounted(){
          //界面加载完成后执行
          this.slotsShow()
        },
        methods:{
           slotsShow: function(){
               debugger;
           }
        },
        components:{
          // 用来声明页面组件  
          child
        }
    }
</script>
<style media="screen">
 
</style>

子组件

<template>
    <div class="sidebar">
       <h1>单个插槽</h1>
       <div class="slot"><slot></slot></div>
       <h2>具名插槽</h2>
       <div class="nameSlot"><slot name="name_slot"></slot></div>
       <h3>作用域插槽1</h3>
        <div class="city">
           <li v-for="item in arrayData" :key="item.id">
               <span>id:{{item.id}}</span><span>name:{{item.name}}</span><span>des:{{item.des}}</span>
               <div class="tableSlot"><slot name="array_data" :city="item"></slot></div>
           </li>
       </div>
        <h3>作用域插槽2</h3>
        <div>
            <ul>
            <li v-for="(item,index) in items" :key="index">
                <slot :item='item'></slot>
            </li>
            </ul>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {  
                items:['aaa1','aaa2','aaa3','aaa4']
            }
        },
        computed:{
           
        },
        props:["arrayData"]
    }
</script>

<style scoped>
    .sidebar{
        text-align: left;
    }
</style>

预览图

在这里插入图片描述
对比

作用域插槽1作用域插槽2异同点
数据来自父组件数据来自子组件差异
渲染受父组件控制渲染受父组件控制相同

当我们不需要用模板渲染出组件的时候,我们可以借助render 函数

父组件

<child></child>

子组件

<script>
    export default {
        data() {
            return {  
            }
        },
        render: function(createElement){
            var self = this;
            return createElement('div', {//一个包含模板相关属性的数据对象
                'class': {
                    foo: true,
                    bar: false
                },
                style: {
                    color: 'red',
                    fontSize: '14px'
                },
                attrs: {
                    id: 'visDom'
                },
                domProps: {
                    innerHTML: '动态渲染出组件'
                }
            })
        },
        computed:{
        },
        methods: {
        },
    }
</script>

<style scoped>
    .sidebar{
        text-align: left;
    }
</style>

更多使用后面补充…

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值