基于element-plus UI 框架封装一个table组件
在项目目录下的components新建一个Table.vue
javascript
<template>
<section class="wrap">
<el-table
ref="table"
:data="tableData"
v-loading="loading"
style="width: 100%"
:stripe="stripe"
:border="border"
:row-key="(row) => { return row.id }"
@selection-change="handleSelectionChange"
:height="tableHeight"
>
// 复选框列 type="selection"
<el-table-column
v-if="selection"
type="selection"
width="56"
align="center"
:fixed="fixed"
>
</el-table-column>
// 序号列 type="index"
<el-table-column
v-if="index"
type="index"
width="56"
label="序号"
:fixed="fixed"
></el-table-column>
<template v-for="(item, index) in tableProps" :key="index">
<el-table-column
:prop="item.prop"
:label="item.label"
:width="item.width"
:type="item.type"
:show-overflow-tooltip="item.showOverflowTooltip"
:align="item.align"
:fixed="item.fixed"
:sortable="item.sort"
:formatter="item.formatter"
>
<template v-if="item.prop === 'operation'" #default="scope">
<el-button size="small" type="success" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
<el-button size="small" type="warning" @click="handleAdd(scope.$index, scope.row)">新增</el-button>
</template>
</el-table-column>
</template>
</el-table>
</section>
</template>
<script setup>
import { ref, watch } from 'vue'
const tableData = ref([])
const loading = ref(true)
// 监听父组件传递过来的数据
watch(() => props.data, (val) => {
tableData.value = val
loading.value = false
})
// 声明要触发的emits
const emits = defineEmits(['selectionChange','deleteItem', 'editItem', 'addItem'])
// 父组件传递过来的props
const props = defineProps({
data: {
type: Array,
default: () => [],
},
tableProps: {
type: Array,
},
tableHeight: {
type: String,
default: '500'
},
selection: Boolean,
index: Boolean,
border: Boolean,
stripe: Boolean,
})
// 定义表格的列属性
const tableProps = ref([
{
type: 'selection',
label: '',
width: '55',
align: 'center'
},
{
type: 'index',
label: 'No.',
width: '55',
align: 'center'
},
{
prop: 'name',
label: '姓名',
width: '',
showOverflowTooltip: true,
align: 'center'
},
{
prop: 'username',
label: '用户名',
width: 120,
showOverflowTooltip: true,
align: 'center'
},
{
prop: 'email',
label: '邮箱',
width: '',
showOverflowTooltip: true,
align: 'center'
},
{
prop: 'phone',
label: '联系电话',
width: '',
showOverflowTooltip: true,
align: 'center',
// 单元格格式化函数,参考element-plus formatter
formatter: (row) => {
return `+86 ${ row.phone }`;
},
},
{
prop: 'website',
label: '网址',
width: '',
showOverflowTooltip: true,
align: 'center',
},
{
prop: 'operation',
label: '操作',
align: 'center',
formatter: (row,column) => {}
}
])
const handleAdd = (row) => {
emits('addItem', row)
}
const handleEdit = (rowData) => {
emits('editItem', rowData)
}
const handleDelete = (index, rowData) => {
emits('deleteItem', index)
}
const handleSelectionChange = (row) => {
console.log('row data are: ', row[0].name)
}
</script>
在具体的父组件中使用:
javascript
<template>
<section class="container">
<section class="table-wrap">
<Table
:data="tableData"
ref="table"
border
stripe
@selectionChange="handleSelectionChange"
@editItem="handleEdit"
@addItem="handleAdd"
@deleteItem="handleDelete">
</Table>
</section>
// <span v-pre>{{ this will not be compiled }}</span>
</section>
</template>
<script setup>
import { ref, reactive, toRefs, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import Table from '@/components/Table.vue'
onMounted(() => {
queryData()
})
const table = ref(null)
const data = reactive({
/* materialForm: {
materailName: '',
materialCode: '',
snCode: '',
productCode: '',
productName: '',
result: '',
workOrder: [],
productLine: [],
},
loading: false,
lineList: [],
orderList: [],
*/
tableData: [],
})
const { materialForm, lineList, orderList, tableData, loading } = toRefs(data)
const title = ref("")
const addData = (param) => {
param.id = Math.random()
// const data = Object.assign({}, param) // 拷贝一个对象
const data = { ...param }
// const data = JSON.parse(JSON.stringify(param)) // 深拷贝
tableData.value.push(data)
}
const handleAdd = () => {
editRef.value.openDialog()
title.value = '新增'
formData.value = {}
}
const handleDelete = (index, row) => {
ElMessageBox.confirm('此操作将会删除本条数据,请确定是否继续执行?','提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
type: 'warning',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '删除成功',
})
tableData.value.splice(index, 1)
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消操作',
})
})
}
const handleSelectionChange = () => {
table.value.handleSelectionChange()
}
provide('formObj', { title, formData, addData })
const handleEdit = (rowData) => {
title.value = '编辑'
const param = {...rowData}
formData.value = param
// formData.value = Object.assign({}, rowData)
// 避免引用传递,做一次数据拷贝
// formData.value = JSON.parse(JSON.stringify(row))
editRef.value.openDialog()
}
const query = () => {
queryData()
}
const reset = (formEl) => {
if (!formEl) return
formEl.resetFields()
queryData()
}
const queryData = () => {
loading.value = true
// const param = { ...materialForm.value, ...{ name: 'zhangsan', age: 20 } }
fetch("https://jsonplaceholder.typicode.com/users").then((resposne) => resposne.json()).then((json) => {
loading.value = false
tableData.value = json
})
}
</script>