vue3.0二次封装el-table

这篇博客介绍了在Vue3中如何使用v-slot进行模板插槽的替换,特别是在子组件中动态生成表格并处理多选框、序号列和文本列。同时展示了如何通过事件总线实现子组件与父组件之间的数据传递,例如分页功能。文章还提供了详细的子组件和父组件代码示例,帮助读者理解Vue3的新特性。
摘要由CSDN通过智能技术生成

实现效果:

注意点:vue3取消slot-scope,改用v-slot,简写#。刚学vue3不久,语法不太熟悉,花了点时间。

核心代码:

 

详细代码:

//子组件
<template>
    <div>
        <el-table ref="el-from" :data="tableData" stripe style="width:100%" v-loading="loading">
            <!-- 多选框 -->
            <el-table-column v-if="configFlag.selection" type="selection" width="55" :align="align"></el-table-column>
            <!-- 序号列 -->
            <el-table-column v-if="configFlag.index" align="center" width="100" type="index" :index="1" :label="configFlag.indexName || '序号'" />
            <!-- 文本 -->
            <el-table-column v-for="item in tableTitleData" :key="item.id" :label="item.label" :prop="item.value" :sortable="item.sortable || false" :align="item.align || 'left'">
                <template #default="scope">
                    <slot v-if="item.slotname" :name="item.slotname" :soltval="scope.row" />
                    <span v-else>
                        {{ scope.row.value }}
                    </span>
                </template>
            </el-table-column>
        </el-table>
        <div class="block pageBox" v-if="pageObj.total">
            <el-pagination @current-change="handleCurrentChange" :currentPage="pageObj.page" background layout="prev, pager, next, jumper" :total="pageObj.total" :page-size="pageObj.size">
            </el-pagination>
        </div>
    </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
    props: {
        tableData: {
            type: Array,
            default: () => {
                return [{}];
            }
        },
        loading: {
            type: Boolean,
            default: true
        },
        configFlag: {
            type: Object,
            default: () => {
                return {
                    selection: false,
                    index: false
                };
            }
        },
        tableTitleData: {
            type: Array,
            default: () => {
                return [];
            }
        },
        pageObj: {
            type: Object,
            default: () =>{
                return {
                    total:0,
                    size:20,
                    page:1
                }
            }
        }
    },
    emits:['onchangepage'],
    setup(props,ctx) {
        const handleCurrentChange = (val) =>{
            ctx.emit('onchangepage',val);
        }
        return {
            handleCurrentChange
        };
    }
});
</script>

<style lang="scss" scoped>
    .pageBox{
        margin-top: 20px;
        text-align: center;
    }
</style>
//父组件

<template>
    <header class="head">
        <el-button type="primary">+ 新建</el-button>
        <div class="head-right">
            <div class="head-select">
                <el-select placeholder="请选择测试题目类型" v-model="search.type" clearable>
                    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
                </el-select>
            </div>
            <div class="head-input">
                <el-input @keyup.enter="searchTable" @clear="searchTable" clearable v-model="search.value" placeholder="请输入关键字搜索">
                    <template #append>
                        <el-button icon="el-icon-search" @click="searchTable"></el-button>
                    </template>
                </el-input>
            </div>
        </div>
    </header>
    <section>
        <ele-table :tableTitleData="tableTitleData" :tableData="tableData" :loading="loading" :pageObj="pageObj" @onchangepage="changePage" >
            <template  #typeName="scope" >
                自定义slot:
                <span>{{scope.soltval.key}}</span>
            </template>
        </ele-table>
    </section>

</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs,onMounted } from "vue";
import eleTable from '@/components/ele-table/index.vue';

export default defineComponent({
    components:{
        eleTable
    },
  setup(){
    const search = reactive({
      value:'',
      type:'',
      page:1,
      size:20,
      total:0
    })
    const loading = ref(true);
    const pageObj = ref({page:1,size:20,total:80})
    const options = reactive({
      options: [{
          value: '选项1',
          label: '黄金糕'
        }, {
          value: '选项2',
          label: '双皮奶'
        }]
    })
    const tableTitleData = ref([
            { id: 1, label: '测试', slotname: 'typeName' },
            { id: 2, label: '测试2',align:'center' }
    ])
    const tableData = ref([
      { value: 3, key: '3-1' },
      { value: 4, key: '4-1'}
    ])
    const changePage = (val) =>{
      console.log(val)
    };
    const searchTable = () => {
      console.log(111)
    };
    onMounted(()=>{
      loading.value = false;
    })
    return{
      search,
      ...toRefs(options),
      loading,
      pageObj,
      tableTitleData,
      tableData,
      searchTable,
      changePage
    }
  }
})
</script>

<style lang="scss" scoped>
@import 'index.scss';
</style>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值