一,el-table表格
<template>
<el-table
:data="tableData"
:border="border"
:stripe="stripe"
v-bind="$attrs"
@selection-change="handleSelectionChange"
>
<!-- 动态列渲染 -->
<template v-for="column in columns" :key="column.prop">
<el-table-column
v-bind="column"
:prop="column.prop"
:label="column.label"
>
<!-- 支持自定义列内容 -->
<template v-if="column.slotName" #default="scope">
<slot :name="column.slotName" :row="scope.row"></slot>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script setup>
defineProps({
tableData: {
type: Array,
required: true,
default: () => []
},
columns: {
type: Array,
required: true,
default: () => []
},
border: {
type: Boolean,
default: false
},
stripe: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['selection-change']);
const handleSelectionChange = (val) => {
emit('selection-change', val);
};
</script>
使用
<template>
<BaseTable
:table-data="userList"
:columns="columns"
stripe
@selection-change="handleSelect"
>
<!-- 自定义操作列 -->
<template #action="scope">
<el-button @click="editUser(scope.row)">编辑</el-button>
</template>
</BaseTable>
</template>
<script setup>
const columns = [
{ prop: 'name', label: '姓名' },
{ prop: 'age', label: '年龄' },
{ prop: 'address', label: '地址' },
{
prop: 'action',
label: '操作',
slotName: 'action' // 对应模板中的slot名称
}
];
const userList = [
{ name: '张三', age: 25, address: '北京' },
{ name: '李四', age: 30, address: '上海' }
];
const handleSelect = (selection) => {
console.log('选中行:', selection);
};
const editUser = (row) => {
console.log('编辑用户:', row);
};
</script>
二,el-drawer封装
<template>
<el-drawer
v-model="visible"
:title="title"
:size="size"
:direction="direction"
v-bind="$attrs"
@close="handleClose"
>
<!-- 内容插槽 -->
<slot></slot>
<!-- 底部操作按钮插槽 -->
<template #footer>
<slot name="footer">
<div class="drawer-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</div>
</slot>
</template>
</el-drawer>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
title: {
type: String,
default: '抽屉标题'
},
size: {
type: [String, Number],
default: '30%'
},
direction: {
type: String,
default: 'rtl',
validator: (val) => ['ltr', 'rtl', 'ttb', 'btt'].includes(val)
}
});
const emit = defineEmits(['update:modelValue', 'confirm', 'cancel', 'close']);
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
});
const handleConfirm = () => {
emit('confirm');
visible.value = false;
};
const handleCancel = () => {
emit('cancel');
visible.value = false;
};
const handleClose = () => {
emit('close');
};
</script>
<style scoped>
.drawer-footer {
text-align: right;
}
</style>
使用
<template>
<BaseDrawer
v-model="drawerVisible"
title="用户信息"
@confirm="handleConfirm"
>
<!-- 自定义内容 -->
<el-form :model="form">
<el-form-item label="用户名">
<el-input v-model="form.name" />
</el-form-item>
</el-form>
<!-- 自定义底部 -->
<template #footer>
<el-button @click="drawerVisible = false">关闭</el-button>
<el-button type="danger" @click="handleDelete">删除</el-button>
<el-button type="primary" @click="handleSave">保存</el-button>
</template>
</BaseDrawer>
</template>
<script setup>
const drawerVisible = ref(false);
const form = reactive({
name: ''
});
const handleConfirm = () => {
console.log('默认确认操作');
};
const handleSave = () => {
console.log('保存数据', form);
drawerVisible.value = false;
};
const handleDelete = () => {
console.log('删除操作');
};
</script>
三,el-dialog封装
<template>
<el-dialog
v-model="visible"
:title="title"
:width="width"
:top="top"
:fullscreen="fullscreen"
v-bind="$attrs"
@close="handleClose"
>
<!-- 内容插槽 -->
<slot></slot>
<!-- 底部操作按钮插槽 -->
<template #footer>
<slot name="footer">
<div class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</div>
</slot>
</template>
</el-dialog>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
title: {
type: String,
default: '对话框标题'
},
width: {
type: [String, Number],
default: '50%'
},
top: {
type: String,
default: '15vh'
},
fullscreen: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:modelValue', 'confirm', 'cancel', 'close']);
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
});
const handleConfirm = () => {
emit('confirm');
visible.value = false;
};
const handleCancel = () => {
emit('cancel');
visible.value = false;
};
const handleClose = () => {
emit('close');
};
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>
使用
<template>
<BaseDialog
v-model="dialogVisible"
title="编辑用户"
width="600px"
@confirm="handleConfirm"
>
<!-- 自定义内容 -->
<el-form :model="form">
<el-form-item label="用户名">
<el-input v-model="form.name" />
</el-form-item>
</el-form>
<!-- 自定义底部 -->
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="danger" @click="handleDelete">删除</el-button>
<el-button type="primary" @click="handleSave">保存</el-button>
</template>
</BaseDialog>
</template>
<script setup>
const dialogVisible = ref(false);
const form = reactive({
name: ''
});
const handleConfirm = () => {
console.log('默认确认操作');
};
const handleSave = () => {
console.log('保存数据', form);
dialogVisible.value = false;
};
const handleDelete = () => {
console.log('删除操作');
};
</script>