主要是針對(duì)vue3.2中的<script setup>語法
這次這個(gè)項(xiàng)目使用的是一個(gè) vue3.2+vite+antd vue
因?yàn)檫@個(gè)項(xiàng)目中多處使用到表格組件,所以進(jìn)行了一個(gè)基礎(chǔ)的封裝,主要是通過antd vue 中表格的slots
配置項(xiàng),通過配合插槽來進(jìn)行封裝自定義表格;
子組件的代碼
<template>
<!-- 表格組件 -->
<a-table
:dataSource="dataSource"
:columns="columns"
class="ant-table-striped mar_t10"
size="small"
:pagination="false"
:scroll="tableHeight"
:rowClassName="
(record, index) => (index % 2 === 1 ? 'table-striped' : null)
"
:row-key="(record) => `${record[rowkey]}`"
:row-selection="
isSelect
? {
selectedRowKeys: selectedRowKeys,
onChange: onRowSel,
}
: null
"
>
<template v-slot:[item]="scope" v-for="item in renderArr">
<!-- // 插槽后面-slot:[item] 如果是動(dòng)態(tài)渲染插槽需要使用這種方式
//renderArr 是父組件傳遞過來的用了插槽的名字,等下會(huì)在父組件中講清楚,通過這個(gè)數(shù)組來遍歷生成插槽 -->
<!-- //再通過這個(gè)插槽傳遞數(shù)據(jù)給父組件,做一些編輯提交的操作等等 -->
<slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
</template>
</a-table>
</template>
<script lang="ts" setup>
// 把setup放在 script 標(biāo)簽里面,相當(dāng)于 setup()語法糖, 具體可以看vue的官網(wǎng)
import { useSlots } from "vue";
// 如果要知道使用插槽的實(shí)例需要引入 useSlots
defineProps({
dataSource: {
type: Object,
required: true,
},
columns: {
type: Object,
required: true,
},
isSelect: {
type: Boolean,
required: true,
},
rowkey: {
type: String,
required: true,
},
});
// defineProps是3.2中新的語法,不需要從 vue里面引入出來
const slots = useSlots();
const emit = defineEmits(["onSelRowKeys"])
// 插槽的實(shí)例
const renderArr = Object.keys(slots);
const state = reactive({
selectedRowKeys: [] as (string | number)[],
});
const onRowSel = (selectedRowKeys: (string | number)[], selectedRows) => {
state.selectedRowKeys = selectedRowKeys;
emit("onSelRowKeys", selectedRowKeys)
};
// 此處減去的190是其他固定元素塊的總高度
const tableHeight = ref({ x: 4800, y: document.body.clientHeight - 190 });
onMounted(() => {
// 監(jiān)聽瀏覽器窗口變化
window.onresize = () => {
return (() => {
tableHeight.value.y = document.body.clientHeight - 190;
})();
};
});
// 渲染的數(shù)據(jù)
const { selectedRowKeys } = toRefs(state);
</script>
<style lang="less" scoped>
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa;
}
</style>
里面最主要的就是通過useSlots
來知道父組件在使用表格組件的時(shí)候使用了幾個(gè)插槽,通過返回的這個(gè)對(duì)象來通過Object.Keys 來遍歷渲染生成新的插槽.
父組件的使用
//rowkey是唯一值隨自己數(shù)據(jù)而修改
<template>
<MyTable :loading="loading"
:columns="columns"
:dataSource="viewList"
:isSelect="isSelect"
@onSelRowKeys="onSelRowKeys"
rowkey="xxxxxxxxxxx">
<template v-slot:bodyCell="{ scope }">
<span v-if="scope.column.key === 'action'" class="recent_linkcolor" @click="onDel(scope.record.fnid, 'nor')" >{{ $t("common.del") }}</span >
</template>
</MyTable>
</template>
<script setup>
const isSelect=ref(false)
const state=reactive({
rowKeys :[]
})
const dataSource = ref([])
const columns = [
{
title: '序號(hào)',
dataIndex: 'numbers',
key: 'numbers',
width: '6%'
},
{
title: '資源名稱',
dataIndex: 'ResourceName',
slots: { customRender: 'ResourceName' }, //slots這個(gè)是重點(diǎn),通過這個(gè)相當(dāng)于告訴表格組件我有一個(gè)具名插槽要用,名字就是customRender后面的名字, 父組件中的useSlots插槽的實(shí)例就有這個(gè)ResourceName,下面也一樣
width: '12%'
},
{
title: '資源名稱IP',
dataIndex: 'IP',
slots: { customRender: 'IP' },
width: '12%'
},
{
title: '數(shù)據(jù)庫類型',
dataIndex: 'DatabaseType',
slots: { customRender: 'DatabaseType' },
width: '12%'
},
{
title: '數(shù)據(jù)庫名',
dataIndex: 'Dbname',
slots: { customRender: 'Dbname' },
width: '12%'
},
{
title: '用戶名',
dataIndex: 'Username',
slots: { customRender: 'Username' },
width: '12%'
},
{
title: '端口',
dataIndex: 'Port',
slots: { customRender: 'Port' },
width: '12%'
},
{
title: '操作',
isSlot: true,
dataIndex: 'action',
slots: { customRender: 'action' }
}
]
const onSelRowKeys = (rowKeys: (string | number)[]) => {
state.rowKeys = rowKeys;
};
const changePage=()=>{
console.log('xxxx')
}
const onDel=()=>{
console.log('xxxx')
}
const {rowKeys }=toRefs(state)
</script>