【Vue】插槽-slot

📝个人主页:五敷有你

🔥系列专栏:Vue

⛺️稳中求进,晒太阳

插槽

作用:让组件内部一些 结构 支持 自定义

插槽的分类:

  • 默认插槽。
  • 具名插槽。

基础语法

组件内需要定制的结构部分,改用占位

html 复制代码
<template>
    <div class="main">
        <h2>确认吗</h2>
        <slot></slot>
        <div class="bottom">
            <button>确认</button><button>取消</button>
        </div>
    </div>
</template>

使用组件时,标签内部,传入结构替换slot

html 复制代码
<BaseA>我是插槽练习</BaseA>

插槽的默认值

通过插槽完成内容的定制,传什么显示什么,但是不传,则是空白

插槽的后备内容:封装组件时,可以为预留的插槽提供后备内容(默认内容)

  • 语法:在slot标签内,放置内容,作为默认显示内容
  • 效果:
    • 外部使用组件不传东西,则slot会显示后备内容
    • 外部使用组件传东西了,则slot整体会被替换掉

具名插槽(一个组件有多处结构需要外部传入标签,进行定制)

语法:

多个slot使用name属性区分名字

简写:v-slot:插槽名 简化---- #插槽名

html 复制代码
    <div class="main">
        <h2>
            <slot name="head"></slot>
        </h2>
        <slot name="body">我是默认值</slot>
        <div class="bottom">
            <slot name="foot"></slot>
        </div>
    </div>

template配置v-slot:名字 来分发对应标签

html 复制代码
   <BaseA>
      <template v-slot:head>
        我是标题
      </template>
    <template v-slot:body>
      <p>我是身体</p>
    </template>
    <template v-slot:foot>
      <button>确认</button><button>取消</button>
    </template>
    </BaseA>

作用域插槽

作用域插槽:定义slot插槽的同时,是可以传值的,给插槽上 可以绑定数据, 将来 使用组件时可以用

场景:封装表格组件

基本使用步骤:

  1. 给slot标签,以添加属性的方式传值。
html 复制代码
<slot :id="item.id" msg="测试文本"></slot>
  1. 所有添加属性,都会收集到一个对象中
html 复制代码
{id:3,msg:"测试文本"}
  1. 在template中,通过 #插槽名='obj'接收,默认插槽名为 default
html 复制代码
<MyTable :list="list">
    <template #default="obj">
        <button @click="del(obj.id)">删除</button>
    </template>
   </MyTable> 

商品列表(实战):

App.vue

html 复制代码
<template>
  <div id="app">
    <MyTable :list="list">
      <template #thead>
          
            <td>编号</td>
          <td>图片</td>
          <td>名称</td>
          <td>标签</td>
       
      </template>
      <template #tbody="{item,index}" >
            <td>{{ index+1 }}</td>
            <td>{{ item.img }}</td>
            <td>{{ item.name }}</td>
            <td><MyEle v-model="item.sign"></MyEle></td>
      </template>
    </MyTable>
  </div>
</template>

<script>

import MyEle from "./components/MyEle.vue"
import MyTable from "./components/MyTable.vue"
export default {
  data(){
    return{
      list:[
      {id:101,img:'001',name:"紫砂壶",sign:"茶具"},
      {id:102,img:'001',name:"皮鞋",sign:"男鞋"},
      {id:103,img:'001',name:"棉衣",sign:"衣服"},
      {id:104,img:'001',name:"毛衣",sign:"衣服"},
      {id:105,img:'001',name:"帽子",sign:"衣服"}
  ]
    }
 
  },

components:{
 MyEle,
 MyTable
},
methods:{
  
},


//局部注册指令
directives:{
  //指令名:指令配置项
    color:{
      inserted(el,binding){
        el.style.color=binding.value
      },
      update(el,binding){
        el.style.color=binding.value
      }
    }
},

}



</script>

<style scoped>
#app {
  
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;

  margin-top: 60px;
  display: flex;
  justify-content: space-around;
}

</style>

MyTable.vue

html 复制代码
<template>
<div class="main">
    <table border="1">
        <thead>
            <tr>
                <!-- <td>编号</td>
                <td>图片</td>
                <td>名称</td>
                <td>标签</td> -->
                <slot name="thead">

                </slot>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(item,index) in list" :key="item.id">
                <slot name="tbody" :item="item" :index="index" ></slot>
            </tr>
              
        </tbody>
    </table>
</div>
</template>
<script>

export default {
    props:{
        "list":Array,
        

    }
}
</script>
<style scoped>

</style>

Mytag.vue

html 复制代码
<template>
<div class="main">
    <div class="ele" v-if="isShow" @click="isShow=false">
       {{ value }}
    </div>
    <div v-else>
        <input type="text" :value="value" v-focus @keyup.enter='update'>
    </div>
</div>
    
    
</template>
<script>

export default {
    props:{
       
        "value":String
    },
    data(){
        return {
           
            isShow:true,
        }
    },
    directives:{
        focus:{
            inserted(el){
                el.focus()
            }
        }
    },
    methods:{
        update(e){
            
            this.$emit("input",e.target.value)
            this.isShow=true
        }
    }
}
</script>
<style scoped>
.ele{
    text-align: center;
    color:rgb(50, 49, 49);
    font-size: 15px;
}
input{
    padding: 3px 4px;
    color:gray;
    font-size: 13px;
}
</style>
相关推荐
阿猫的故乡几秒前
Vue模板引用和组件暴露:ref拿DOM、defineExpose调方法,案例多到眼花
前端·javascript·vue.js
薛定谔的猫-菜鸟程序员5 分钟前
从Electron到Tauri,Rust+Vue(Tauri) 实现超高性能桌面日志应用开发,以及开发避坑指南
vue.js·rust·electron
you458012 小时前
学成在线--day02 CMS前端开发(含Vue基础知识得回顾)
前端·javascript·vue.js
xiaofeichaichai12 小时前
虚拟 DOM
前端·javascript·vue.js
初一初十12 小时前
vue3实现的纯前端护肤品商城网站
前端·javascript·vue.js·前端框架
初一初十14 小时前
vue3茶叶商城网站vue网页vuejs前端
前端·javascript·vue.js·vscode·前端框架
小亮学前端15 小时前
在1Panel中部署Nuxt项目
前端·vue.js
用户8417948145615 小时前
vxe-table 虚拟滚动下自定义行高:支持每行独立高度与自适应
vue.js
如果超人不会飞16 小时前
TinyVue 组件库实战指南:从安装到上手一篇就够了
vue.js
开飞机的舒克_16 小时前
vue3+router动态权限路由
前端·vue.js