- 这个组件解决的问题?
在以往的项目当中,我从未想过要对 批量/列表数据的操作按钮做什么变动,直到最近的一次开发,让我突然觉得可以将操作按钮也做成一个公共组件,在做前端开发时,更加专注于js代码逻辑。 - 如何使用?
全局(main.js中)引用操作组件 BatchOperation.vue
创建页面操作按钮 actions.js 文件 - BatchOperation.vue 全局操作按钮组件文件代码:
<template> <div> <!-- 列表顶部的批量操作按钮组件 / 表格中的操作按钮--> <el-row :gutter="10" class="mb8 mt10" type="flex"> <slot name="default"></slot> <el-col :span="1.5" v-for="action, index in visibleAction" :key="action.command" v-show="visibleAction.length > 0"> <el-button :link="inColumn" :type="getBtnType(index)" plain :disabled="action.disabled" v-hasPermi="action.permission" @click="commandAction(action.command)">{{action.name}}</el-button> </el-col> <el-col :span="1.5" v-if="moreActionsVisible"> <el-dropdown @command="commandAction" :size="inColumn ? 'default' : 'large'" style="line-height:inherit;vertical-align: bottom;"> <el-button type="primary" plain :link="inColumn"> 更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon> </el-button> <template #dropdown> <el-dropdown-menu> <div v-hasPermi="action.permission" v-for="action in moreActions" :key="action.command"> <el-dropdown-item :disabled="action.disabled" :command="action.command" > {{action.name}} </el-dropdown-item> </div> </el-dropdown-menu> </template> </el-dropdown> </el-col> <slot name="rightToolbar"></slot> </el-row> </div> </template> <script setup> import take from 'lodash/take' import takeRight from 'lodash/takeRight' import mapValues from 'lodash/mapValues' import pickBy from 'lodash/pickBy' import values from 'lodash/values' import sortBy from 'lodash/sortBy' // button type const btnType = ['primary', 'success', 'warning', 'danger', 'info', 'default'] // props const getBtnType =(index)=>{ const indx = index % btnType.length return btnType[indx] } // actions command const emits = defineEmits() // props const props = defineProps(['actions','visibleCount','inColumn']) // 明显按钮 默认显示前五个按钮; 如果是在 数据行操作只显示 1 个 const MAX = computed(()=>{ const count = props.inColumn ? 1 : 5 return props.visibleCount === undefined ? count : props.visibleCount }) // 将 key 作为 command。 hiddenInColunm 在表中隐藏 onlyInColunm 只在表格列中显示 hidden 都不显示 const operations = computed(()=>{ let actions = pickBy(props.actions, a =>(props.inColumn ? (!a.hiddenInColunm) : !a.onlyInColunm) && !a.hidden) actions = mapValues(actions,(value,key)=>{ value.command = key return value }) // 将可用功能优先排序 return sortBy(values(actions), (a)=>a.disabled) }) // 明显按钮 const visibleAction = computed(()=>{ return take(operations.value, MAX.value) }) // 更多操作下拉按钮 const moreActions = computed(()=>{ return takeRight(operations.value, operations.value.length - MAX.value) }) // 是否显示更多按钮 const moreActionsVisible = computed(()=>MAX.value == 0 || operations.value.length > visibleAction.value.length) // 点击更多操作里的按钮 const commandAction =(command)=>{ emits(command) } </script>
- actions.js 页面操作,举个例子:
// single:批量勾选 false 单条数据,true 非单条数据 // multiple:批量勾选 false 已勾选 true 未勾选 // row:单行数据。当 single 为 false 时, row 也须有值 export default function (single, multiple, row) { return { 'create': { name: "新增",// 按钮名称 permission: ['bless:product:permissionAdd'],// 权限字符 disabled: false, // 是否可点击 hiddenInColunm: true // 在表格列中隐藏 }, 'edit': { name: "修改", permission: ['bless:product:permissionEdit'], // 单行 或者 row 存在且符合( ... )中的条件时 disabled: single || ( row ? ( row.status !=0 && row.status !=3 ) : true), onlyInColunm: true // 仅在列表中显示 }, 'delete': { name: "删除", permission: ['bless:product:permissionRemove'], disabled: multiple, }, 'search': { name: "查询", permission: ['bless:product:permissionPage'], disabled: false, hidden: true // 隐藏 } } }
- 页面使用操作按钮:UI 组件:element-plus
<template> <!-- v-hasPermi 权限指令 详见 若依--自定义指令--> <div v-hasPermi="actions['search'].permission"> <!-- 批量操作 --> <BatchOperation :actions="actions" @create="handleCreate" @delete="handleDelete" > </BatchOperation> <!-- 列表 --> <el-table :data="list" row-key="productId" @selection-change="handleSelectionChange"> <!-- 勾选框 --> <el-table-column type="selection" width="55" align="center" fixed="left" /> ...(这里就是列表展示的数据) <!-- 单行操作按钮 --> <el-table-column label="操作" fixed="right" header-align="center" width="150px"> <template #default="{row}"> <BatchOperation :inColumn="true" :actions="initAction(false, false, row)" @edit="handleEdit(row)" @delete="handleDelete(row.productId)" ></BatchOperation> </template> </el-table-column> </el-table> </div> </template> <script setup name="ProductIndex"> import { getPages, remove } from '@/api/product' import initAction from './components/actions' // 勾选 const multipleSelection = ref([]) // ids // 非单个禁用 const single = computed(() => multipleSelection.value.length != 1) // 非多个禁用 const multiple = computed(() => !multipleSelection.value.length) // 当前选中 const selectedRow = computed(() => { if (multipleSelection.value.length == 1) { return list.value.find(z => z.productId == multipleSelection.value[0]) } return null }) // 批量操作按钮 const actions = computed(()=>initAction(single.value, multiple.value, selectedRow.value)) // 批量勾选触发 const handleSelectionChange = (val) => { multipleSelection.value = val.map(z => z.productId) } // 点击 ��增 const handleCreate =()=>{ router.push('/product/create') } // 点击 修改 const handleEdit =(row)=>{ const current = row || selectedRow.value router.push('/product/edit/' + current.productId) } // 批量删除 const handleDelete = (id) => { proxy.$modal.confirm('确定删除?') .then(() => { const ids = id || multipleSelection.value remove(ids).then(res => { if (res.code == 200) { proxy.$modal.msgSuccess("操作成功") getList() } else { proxy.$modal.msgError(res.msg || "请求发生错误,请稍后重试") } }) }) .catch(() => { proxy.$modal.msg("已取消") }) } // 获取列表数据 const getList = () => { proxy.$modal.loading("加载中...") // **这里 searchRef 咱们下篇随笔见!** const { dateRange, ...search } = searchRef.value.form const query = { ...pager.value, ...search } const data = dateRange ? proxy.addDateRange(query, dateRange) : query getPages(data).then(response => { list.value = response.data.rows; total.value = parseInt(response.data.total); expandRowKeys.value = [] }).finally(() => { proxy.$modal.closeLoading(); }); } </script>