欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 【ElementPlus】在Vue3中实现表格组件封装

【ElementPlus】在Vue3中实现表格组件封装

2025/1/24 1:48:04 来源:https://blog.csdn.net/qq_40476712/article/details/145278573  浏览:    关键词:【ElementPlus】在Vue3中实现表格组件封装

预览

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2a954e6b844947f8a7a3e7f30d39421e.pn

搜索筛选组件

<template><div><el-formref="formView":model="formData"label-width="auto"label-position="right":label-col-style="{ 'min-width': '100px' }":inline="true"><el-form-item :prop="column.prop" :label="column.label" v-for="column in columns" :key="column.prop"><slot :name="column.prop" :query="formData"><el-input v-model="formData[column.prop]" :placeholder="`请输入${column.label}`" clearable /></slot></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="onSubmit">查询</el-button><el-button icon="Refresh" @click="onReset">重置</el-button></el-form-item><div class="mb15"><slot name="handleMenu" /></div></el-form></div>
</template>
<script setup>
import { ref, toRaw, watch, onMounted } from "vue"const props = defineProps(["columns"])
const emit = defineEmits(["change", "submit", "reset"])
const formView = ref(null)
let formData = ref()
let isReset = false
watch(() => formData,(data) => {if (isReset) {isReset = falsereturn}emit("change", toRaw(data.value))},{ deep: true, immediate: true }
)onMounted(() => {formData.value = columnsToFormData()
})
function onSubmit() {emit("submit", toRaw(formData.value))
}function onReset() {isReset = trueformData.value = columnsToFormData()emit("reset", toRaw(formData.value))
}function columnsToFormData() {return Object.fromEntries([].concat(...props.columns.map((item) => {if (item.items) {return item.items.map((iItem) => [iItem.prop, item?.defaultValue || null])}return [[item.prop, item?.defaultValue || null]]})))
}
</script>

表格组件

<template><div><!-- 筛选条件相关 --><query-header :columns="queryColumns" @change="onQueryParamsChange" @submit="onSubmit" @reset="onReset"><template v-for="item in queryColumns" :key="item.prop" v-slot:[item.prop]="{ query }"><slot :name="`${item.prop}Query`" :query="query" /></template><template #handleMenu><slot name="handleMenu" /></template></query-header><!-- 表格 --><el-table ref="tableView" :data="list" :loading="loading" @selection-change="onSelectionChange"><!-- 表格选择 --><el-table-column type="selection" width="55" v-if="props.selection" /><!-- 展开行内容 --><el-table-column type="expand" v-if="expand"><template #default="{ row }"><slot name="expand" :row="row" /></template></el-table-column><!-- 表格列 --><el-table-columnv-for="column in tableColumnsList":key="column.prop":align="column.align ? column.align : 'center'":label="column.label":prop="column.prop":width="column.width":sortable="column.sortable"show-overflow-tooltip><template #default="scope"><slot :name="column.prop" :row="scope.row">{{ scope.row[column.prop] }}</slot></template></el-table-column><!-- 操作菜单 --><slot name="tableMenu" /></el-table></div><!-- 分页 --><el-paginationv-model:current-page="queryForm.page_no"v-model:page-size="queryForm.page_size":page-sizes="[1, 10, 20, 50, 100]"background:background="background"layout="total, sizes, prev, pager, next, jumper":total="total"@size-change="onPageSizeChange"@current-change="onPageChange"class="mt20 flex"style="justify-content: flex-end"/>
</template>
<script setup>
import request from "@/utils/request"
import QueryHeader from "./QueryHeader.vue"
import { ref, reactive, onMounted, watch } from "vue"/* 父组件传递参数apiUrl: { type: String, required: true },   // 请求地址tableColumns: { type: Array, required: true }, // 表格列selection: { type: Boolean, default: false }, // 是否可多选rowKey: { type: String, default: '' }, // 行数据的 Key,用来优化 Table 的渲染;expand: { type: Boolean, default: false }, // 是否可展开*/
const props = defineProps(["apiUrl", "tableColumns", "expandable", "selection", "rowKey", "expand"])const tableView = ref(null)
const queryColumns = ref([])
const tableColumnsList = ref([])watch(() => props.tableColumns,(newVal, oldVal) => {queryColumns.value = newVal.filter((item) => {return item.search})tableColumnsList.value = newVal.filter((item) => {return !item.hide})}
)onMounted(() => {queryColumns.value = props.tableColumns.filter((item) => {return item.search})tableColumnsList.value = props.tableColumns.filter((item) => {return !item.hide})getList()
})/* 获取列表数据 */
const loading = ref(false)
const total = ref(0)
const list = ref([])
const queryForm = reactive({page_no: 1,page_size: 10,
})
function getList() {loading.value = truelet params = JSON.parse(JSON.stringify(queryForm))request.get({url: props.apiUrl,params,}).then((res) => {list.value = res.liststotal.value = res.countloading.value = false})
}
/*  */
/* 表格分页页数切换 */
function onPageChange(num) {queryForm.page_no = numgetList()
}
/* 表格每页数量切换 */
function onPageSizeChange(num) {queryForm.page_size = numqueryForm.page_no = 1getList()
}/* 重置查询 */
function queryList(dataList) {/* dataList除query-header 外查询参数 */if (dataList && dataList.length > 0) {for (let item of dataList) {queryForm[item.key] = item.value}}queryForm.page_no = 1getList()
}
/* 表格选择 */
const emit = defineEmits(["select"])
function onSelectionChange(value) {emit("select", value)
}
/* 查询条件-点击查询按钮 */
function onSubmit() {queryList()
}
/* 查询条件-参数变化 */
function onQueryParamsChange(value) {Object.assign(queryForm, value)
}
/*  查询条件-清空参数 */
function onReset(value) {Object.assign(queryForm, value)queryList()
}
/* 暴露到父组件方法 */
defineExpose({queryList,
})
</script>

页面引用

<template><div class="app-container home"><query-table ref="tableViewRef" apiUrl="/adviser/lists" :table-columns="tableColumns" :selection="true"><!-- 筛选条件自定义 --><template #create_timeQuery="{ query }"><el-date-pickerv-model="query.create_time"type="daterange"value-format="YYYY-MM-DD"range-separator="-"start-placeholder="开始日期"end-placeholder="结束日期"@change="onTimeChange"/></template><template #is_disableQuery="{ query }"><el-select v-model="query.is_disable" clearable><el-option label="是" :value="1"></el-option><el-option label="否" :value="0"></el-option></el-select></template><template #handleMenu><el-row><el-col :span="12"><el-space><el-button type="primary" icon="Plus" @click="clickAdd('')" v-perms="['adviser/add']">添加</el-button><el-button>批量导入</el-button><el-button>批量导出</el-button></el-space></el-col></el-row></template><!-- table自定义列 --><template #is_disable="{ row }"><el-switch v-model="row.is_disable" :active-value="1" :inactive-value="0"></el-switch></template><template #tableMenu><el-table-column label="操作" align="center" width="200"><template #default="{ row }"><router-link :to="`./info?id=${row.id}`"><el-button type="primary" link>详情</el-button></router-link><!-- <el-button v-perms="['adviser/edit']" type="primary" link @click="clickAdd(row.id)">编辑</el-button><el-button v-perms="['adviser/delete']" type="danger" link @click="handleDelete(row.id)">删除</el-button> --></template></el-table-column></template></query-table></div>
</template><script setup name="Index">
import QueryTable from "@/components/QueryTable/index.vue"const tableColumns = [{ label: "顾问名称", prop: "name", search: true },{ label: "手机号", prop: "mobile", search: true },{ label: "微信号", prop: "user_id" },{ label: "关联用户数", prop: "adviser_id", width: 150 },{ label: "当前面试", prop: "commission", sortable: true },{ label: "预约单", prop: "w_commission", sortable: true },{ label: "服务单", prop: "wz_commission", sortable: true },{ label: "创建时间", prop: "create_time", width: 160, search: true },{ label: "是否启用", prop: "is_disable", search: true },
]
</script><style scoped lang="scss"></style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com