当前位置: 首页 > java >正文

vue3的 三种插槽 匿名插槽,具名插槽,作用域插槽

背景:

在vue3项目中,常用的三种插槽。

关于插槽的理论知识如下:

插槽是指可以在父组件内自定义模板片段,在子组件中可以将定义的模板片段插入到子组件的特定位置。常用:匿名插槽、具名插槽

作用域插槽:子组件向父组件传递数据,并在父组件定义的模板中渲染。常用:作用域插槽

匿名插槽和具名插槽:

插槽是指可以在父组件内自定义模板片段,在子组件中可以将定义的模板片段插入到子组件的特定位置。常用:匿名插槽、具名插槽

代码截图:

父组件:

子组件:

作用域插槽:

作用域插槽:子组件向父组件传递数据,并在父组件定义的模板中渲染。

代码截图:

实际代码如下:

父组件:

<div class="container"><Table :columns="columns" :current-page="currentPage" :data="tableData" :page-size="pageSize" :total="total"@update:currentPage="val => currentPage = val"><template #operation="{ row, $index }"><el-button text @click="ClickDetail(row, $index)"><template #icon><img :src="detailIcon" alt=""></template>详情</el-button><el-button text @click="ClickEdit(row, $index)"><template #icon><img :src="editIcon" alt=""></template>编辑</el-button><el-button text @click="ClickForward(row, $index)"><template #icon><img :src="forwardIcon" alt=""></template>预/决算</el-button><el-button text @click="ClickDelete(row, $index)"><template #icon><img :src="deleteIcon" alt=""></template>删除</el-button></template></Table>
</div>

子组件:

<template><div class="table-container"><el-table :data="data":style="`width: 100%; flex: 1 1 auto;opacity: ${!enableLoading || !isloading || isempty ? 1 : 0};`":height="tableBodyHeight" :header-cell-style="{ background: '#F5F9FF', color: '#333333', fontWeight: '550' }":cell-style="cellStyle" max-height="100%" :border="showBorder" empty-text=""><el-table-column type="index" label="序号" width="60" align="center" :index="indexMethod" fixed="left"v-if="showIndex" /><!-- 操作列插槽 --><el-table-column label="操作" align="center" fixed="right" v-if="$slots.operation" :width="400"><template #default="scope"><slot name="operation" :row="scope.row" :$index="scope.$index"></slot></template></el-table-column></el-table><div class="custom-pagination-wrapper"><span class="custom-pagination-total">共 {{ total }} 个</span><el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize":current-page="currentPage" @current-change="handlePageChange" class="custom-pagination" /></div></div>
</template><script setup>
import { defineProps, defineEmits, onMounted, ref, nextTick, reactive, watch, computed } from 'vue'const props = defineProps({columns: {type: Array,required: true},data: {type: Array,required: true},total: {type: Number,default: 0},pageSize: {type: Number,default: 10},currentPage: {type: Number,default: 1},// 是否默认显示序号列showIndex: {type: Boolean,default: true},// 是否默认显示表格边框showBorder: {type: Boolean,default: false},// 是否默认开启加载动画enableLoading: {type: Boolean,default: false}
});const isloading = ref(true), isempty = ref(false);
watch(() => props.data, (newValue, oldValue) => {nextTick(() => {// console.log('table');isempty.value = props.data.length == 0;isloading.value = false;})
});const emit = defineEmits(['update:currentPage', 'customCellStyle'])function handlePageChange(page) {// if (props.data && props.data.length !== 0) {//   state.tableData = props.data.slice((page - 1) * 10, 10 * page);//   emit('update:currentPage', page)// }emit('update:currentPage', page)
}// 自动序号方法,分页自增
const indexMethod = (index) => {return (props.currentPage - 1) * props.pageSize + index + 1
}// 计算表格可视区高度,减去分页区高度
const tableBodyHeight = ref('100%')// 自定义每个单元格的样式
const cellStyle = (target) => {let style = { color: '#363636' };// 子组件可自己实现自定义样式emit('customCellStyle', target, data => {style = data;});return style;
}onMounted(() => {nextTick(() => {const container = document.querySelector('.table-container')const pagination = document.querySelector('.custom-pagination-wrapper')if (container && pagination) {const containerHeight = container.clientHeightconst paginationHeight = pagination.clientHeighttableBodyHeight.value = `${containerHeight - paginationHeight}px`}// handlePageChange(props.currentPage)})
})
</script><style scoped>
.table-container {position: relative;display: flex;flex-direction: column;height: 100%;min-height: 0;.loading {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);display: flex;flex-direction: column;align-items: center;justify-content: center;z-index: 9;span {color: #3A5269;text-align: center;font-family: "Alibaba PuHuiTi";font-size: 18px;font-style: normal;line-height: 22px;/* 122.222% */font-weight: 400;/* margin-top: 10px; */margin-left: 20px;}}.isempty {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);display: flex;flex-direction: column;align-items: center;justify-content: center;z-index: 9;img {width: 140px;height: 140px;}span {color: #3A5269;text-align: center;font-family: "Alibaba PuHuiTi";font-size: 18px;font-style: normal;line-height: 22px;/* 122.222% *//* margin-top: 16px; */margin-left: 20px;}}
}.el-table {flex: 1 1 auto;min-height: 0;
}.el-table__body-wrapper {overflow-y: auto !important;
}:deep(.el-table__row) {height: 40px;
}.custom-pagination-wrapper {display: flex;align-items: center;justify-content: space-between;height: 30px;
}.custom-pagination-total {color: #86909C;font-size: 14px;margin-right: 16px;
}.custom-pagination {margin-left: auto;
}.custom-pagination .el-pager li {border-radius: 4px;min-width: 32px;height: 32px;line-height: 32px;margin: 0 2px;color: #4E5A6A;font-size: 14px;background: transparent;border: none;transition: background 0.2s, color 0.2s, border 0.2s;
}.custom-pagination .el-pager li.active {background: transparent;color: #28ABF5;border: 1px solid #28ABF5;border-radius: 4px;
}.custom-pagination .el-pager li:hover {background: #eaf4ff;color: #28ABF5;
}.custom-pagination .el-pagination__prev,
.custom-pagination .el-pagination__next {min-width: 32px;height: 32px;line-height: 32px;border-radius: 4px;color: #4E5A6A;background: transparent;border: none;margin: 0 2px;
}.custom-pagination .el-pagination__prev.is-active,
.custom-pagination .el-pagination__next.is-active {background: transparent;color: #28ABF5;border: 1px solid #28ABF5;border-radius: 4px;
}.custom-pagination .el-pagination__prev:hover,
.custom-pagination .el-pagination__next:hover {background: #eaf4ff;color: #28ABF5;
}:deep(.el-pagination.is-background .btn-next),
:deep(.el-pagination.is-background .el-pager li),
:deep(.el-pagination.is-background .btn-prev:disabled),
:deep(.el-pagination.is-background .btn-prev) {background: transparent;color: #606266;
}:deep(.el-pagination.is-background .el-pager li.is-active) {min-width: 25px;height: 25px;color: #28ABF5;border-radius: 4px;border: 1px solid #28ABF5;
}
</style>

为什么这么封装,需要了解el-table组件,点击跳转

http://www.xdnf.cn/news/20094.html

相关文章:

  • 无需Python:Shell脚本如何成为你的自动化爬虫引擎?
  • Dubbo消费者无法找到提供者问题分析和处理
  • 记录SSL部署,链路不完整问题
  • Eclipse 常用搜索功能汇总
  • 连接MCP,Lighthouse MCP Server和CNB MCP Server应用
  • 解密注意力计算的并行机制:从多头并张量操作到CUDA内核优化
  • 25年Docker镜像无法下载的四种对策
  • 【Spring Cloud Alibaba】Sentinel(一)
  • 【LeetCode数据结构】设计循环队列
  • Java 并发编程解析:死锁成因、可重入锁与解决方案
  • 人工智能机器学习——逻辑回归
  • go 初始化组件最佳实践
  • ai生成ppt工具有哪些?10款主流AI生成PPT工具盘点
  • 中州养老:角色管理的角色分页查询
  • 渗透测试与网络安全审计的关系
  • (论文速读)Navigation World Models: 让机器人像人类一样想象和规划导航路径
  • MySQL主从复制之进阶延时同步、GTID复制、半同步复制完整实验流程
  • aippt自动生成工具有哪些?一文看懂,总有一款适合你!
  • Java数据结构——栈(Stack)和队列(Queue)
  • Qt---状态机框架QState
  • 【Sharding-JDBC】​Spring/Spring Boot 集成 Sharding-JDBC,分表策略与 API、YAML 配置实践​
  • 达梦数据库-共享内存池
  • 3.3.3 钢结构工程施工
  • Kubernetes知识点(三)
  • 探究Linux系统的SSL/TLS证书机制
  • 河南萌新联赛2025第(七)场:郑州轻工业大学
  • 直接让前端请求代理到自己的本地服务器,告别CV报文到自己的API工具,解放双手
  • android View详解—自定义ViewGroup,流式布局
  • 亚洲数字能源独角兽的 “安全密码”:Parasoft为星星充电筑牢软件防线
  • MongoDB 高可用部署:Replica Set 搭建与故障转移测试