Cat-Table-Select 基于Vue+Element的表格选择器

Cat-Table-Select是一个基于Vue 2.x和Element的组件,提供单选、多选、分页及自定义列等功能。用户可以通过复制仓库、安装依赖并预览Demo来体验这个表格选择器。它还包括了Api文档,详细说明了TableSelect的Attributes、Columns、Props、Events和V-Slot。

Cat-Table-Select 基于Vue+Element的表格选择器

基于 Element 的Vue 组件(Vue.js 2.x)

cat-table-select Github 地址

前言

之前自己动手做了个基于Element树选择器 cat-tree-selec ,于是就照着之前的思路又封装了个表格选择器。目前已经实现了单选,多选,分页,自定义列,可搜索等功能。

效果预览

在这里插入图片描述
在这里插入图片描述

Demo 安装

复制仓库

git clone git@github.com:scuxiatian/cat-table-select.git

安装依赖

npm install

demo预览

npm run serve

实例

单选表格

<cat-table-select 
	v-model="value" 
	:data="data" 
	:columns="columns" 
	:props="props">
</cat-table-select>
export default {  
	data () {   
		return { 
			value: '',
			columns: [
				{ key: 'name',  label: '姓名', width: 100}, 
				{ key: 'address', label: '地址'  }
			],
			props: { key: 'id', label: 'name' },
			data: [
				{ id: '1', name: '王小虎1', address: '上海市普陀区金沙江路 1518 弄' }, 
				{ id: '2', name: '王小虎2', address: '上海市普陀区金沙江路 1517 弄' },
				{ id: '3', name: '王小虎3', address: '上海市普陀区金沙江路 1519 弄' },
				{ id: '4', name: '王小虎4', address: '上海市普陀区金沙江路 1516 弄'  }
			] 
		}
	}
}

可分页

<cat-table-select 
	v-model="value" 
	:data="data" 
	:columns="columns" 
	:props="p
<template> <div> <div class="flex justify-between items-center py-4 h-14 px-5"> <PageHeader :title="pageTitle" @back="handlegoback" /> <div class="flex gap-2.5"> <el-button type="default" @click="handlegoback">返回</el-button> <el-button type="primary" @click="handleSave">保存</el-button> </div> </div> <el-form :model="customForm" :rules="customRuleSet" ref="customFormRef" label-width="120px" class="flex gap-5 pt-5 border-t tlinter-border items-center pb-5" > <el-form-item label="规则集名称" prop="ruleSetName" class="m-0"> <el-input v-model="customForm.ruleSetName" placeholder="请输入1-20位规则集名称" show-word-limit class="w-60" /> </el-form-item> <el-text type="primary" class="mx-1 text-[#409eff] self-center" style="padding-bottom: 5px" > {{ usedRulesText }} </el-text> </el-form> <div class="flex gap-0 p-5 border-t tlinter-border"> <div class="flex flex-col gap-1 w-1/4 border-r tlinter-border pr-5 h-full"> <div class="w-full h-full"> <el-input v-model="searchQuery" placeholder="输入规则编号/描述查询" class="w-full" suffix-icon="Search" clearable /> </div> <div class="flex gap-4" label-width="0"> <el-checkbox v-model="isVHDLChecked">VHDL</el-checkbox> <el-checkbox v-model="isVerilogChecked">Verilog</el-checkbox> </div> <h1 class="font-inter text-base font-medium leading-[22px] tracking-0 tlinter-text-one pb-2">规则类别</h1> <div class="flex flex-col gap-3" label-width="0"> <el-checkbox v-for="(category, index) in ruleCategories" :key="index" v-model="category.checked" :label="category.name" class="block !mb-2 w-full" > {{ category.name }} </el-checkbox> </div> </div> <div class="flex-1 w-3/4 custom-form-item"> <el-table ref="ruleTableRef" :data="ruleTable" style="width: 100%" row-key="id" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55" reserve-selection /> <el-table-column width="400" prop="ruleNo" label="规则编号" > <template #header> <div class="flex items-center gap-2"> <span>规则编号</span> <el-select v-model="headerSelectValue" :placeholder="selectPlaceholder" style="width: 120px" @change="handleHeaderSelectChange" > <el-option label="启用" value="enableAll"></el-option> <el-option label="禁用" value="disableAll"></el-option> </el-select> </div> </template> <template #default="scope"> <el-text @click="openDrawer(scope.row)" class="hover:text-primary cursor-pointer" :class="activeRowId === scope.row.id ? 'el-text--primary' : ''" > {{ scope.row.ruleNo }} </el-text> </template> </el-table-column> <el-table-column prop="description" label="描述" width="420" /> <el-table-column prop="alarmType" label="告警类型(点击标签可切换)" > <template #default="scope"> <el-tag :type="getTagType(scope.row.alarmType)" @click="toggleAlarmType(scope.row)" :class="scope.row.alarmType === '错误' ? 'tag-pink' : 'tag-yellow'" > ● {{ scope.row.alarmType }} </el-tag> </template> </el-table-column> </el-table> </div> </div> <el-drawer v-model="drawerVisible" :title="drawerTitle" size="30%" :before-close="closeDrawer" > <RuleDetails :current-row="currentRow" /> </el-drawer> </div> </template> <script setup> import { ref, computed, reactive, watch, onMounted, nextTick } from 'vue' import { useRouter, useRoute } from 'vue-router' import { Search } from '@element-plus/icons-vue' import { ElMessage } from 'element-plus' import RuleDetails from './components/ruleDetails.vue' import PageHeader from "@/components/PageHeader.vue"; const router = useRouter() const route = useRoute() const ruleTableRef = ref(null) const customFormRef = ref(null) const headerSelectValue = ref('') // 搜索关键词 const searchQuery = ref('') const isVHDLChecked = ref(true) const isVerilogChecked = ref(false) // 抽屉相关 const drawerVisible = ref(false) const currentRow = ref(null) const drawerTitle = ref('') const activeRowId = ref(null) // 表格选中数据 const selectedRows = ref([]) // 页面标题 const pageTitle = computed(() => { return route.query.ruleSetName || '自定义规则集' }) // 表单数据(规则集名称) const customForm = reactive({ ruleSetName: route.query.ruleSetName || '' }) // 表单校验规则 const customRuleSet = reactive({ ruleSetName: [ { required: true, message: '请输入规则集名称', trigger: 'blur' }, { max: 20, message: '规则集名称不能超过20个字符', trigger: 'blur' } ] }) // 规则类别(左侧筛选) const ruleCategories = ref([ { name: 'VHDL编码规则', checked: true }, { name: 'VHDL同步设计规则', checked: true }, { name: 'VHDL标头规则', checked: false }, { name: '规则类别1', checked: false }, { name: '规则类别2', checked: false }, { name: '规则类别3', checked: false }, { name: '规则类别4', checked: false }, { name: '规则类别5', checked: false }, { name: '规则类别6', checked: false }, { name: '规则类别7', checked: false } ]) // 表格原始数据 const ruleData = ref([ { id: 1, ruleNo: 'TLR-030001V', description: 'VHDL源文件应包含头注释', alarmType: '错误', category: 'VHDL编码规则', enable: true }, { id: 2, ruleNo: 'TLR-030002V', description: '同步设计应遵循时钟域交叉原则', alarmType: '告警', category: 'VHDL同步设计规则', enable: true }, { id: 3, ruleNo: 'TLR-030003V', description: '标头应包含版本、作者等信息', alarmType: '告警', category: 'VHDL标头规则', enable: false }, { id: 4, ruleNo: 'TLR-030004V', description: '模块端口声明需指定方向(IN/OUT)', alarmType: '错误', category: 'VHDL编码规则', enable: true } ]) // 过滤后的表格数据 const ruleTable = computed(() => { if (!ruleData.value || !ruleCategories.value) return [] const selectedCategoryNames = ruleCategories.value .filter(cat => cat.checked) .map(cat => cat.name) if (selectedCategoryNames.length === 0) return [] let filteredData = ruleData.value.filter(item => selectedCategoryNames.includes(item.category) ) if (searchQuery.value.trim()) { const keyword = searchQuery.value.trim().toLowerCase() filteredData = filteredData.filter(item => item.ruleNo.toLowerCase().includes(keyword) || item.description.toLowerCase().includes(keyword) ) } return filteredData }) const isAllSelectedEnabled = computed(() => { if (selectedRows.value.length === 0) return false return selectedRows.value.every(row => row.enable === true) }) const selectPlaceholder = computed(() => { return isAllSelectedEnabled.value ? '已启用' : '启用状态' }) const usedRulesText = computed(() => { const enabledCount = ruleData.value.filter(rule => rule.enable === true).length return `已启用${enabledCount}条规则` }) const getTagType = computed(() => (alarmType) => { const typeMap = { '错误': 'danger', '告警': 'warning' } return typeMap[alarmType] || 'info' }) const handleTableSelection = (tableData) => { if (!ruleTableRef.value || !tableData || tableData.length === 0) { return } tableData.forEach(row => { ruleTableRef.value.toggleRowSelection(row, false) }) tableData.forEach(row => { if (row.enable) { ruleTableRef.value.toggleRowSelection(row, true) } }) } // 表格选中事件 const handleSelectionChange = (selection) => { selectedRows.value = selection } // 下拉框操作 const handleHeaderSelectChange = (value) => { switch (value) { case 'enableAll': handleBatchEnable() break case 'disableAll': handleBatchDisable() break } headerSelectValue.value = '' } // 批量启用 const handleBatchEnable = () => { if (selectedRows.value.length === 0) { ElMessage.warning('请先选择要启用的规则') return } ruleData.value.forEach(row => { row.enable = false }) selectedRows.value.forEach(selectedRow => { const targetRow = ruleData.value.find(row => row.id === selectedRow.id) if (targetRow) targetRow.enable = true }) handleTableSelection(ruleTable.value) // ElMessage.success(`成功启用${selectedRows.value.length}条规则`) } // 批量禁用 const handleBatchDisable = () => { if (selectedRows.value.length === 0) { ElMessage.warning('请先选择要禁用的规则') return } selectedRows.value.forEach(selectedRow => { const targetRow = ruleData.value.find(row => row.id === selectedRow.id) if (targetRow) targetRow.enable = false }) handleTableSelection(ruleTable.value) // ElMessage.success(`成功禁用${selectedRows.value.length}条规则`) } // 切换告警类型 const toggleAlarmType = (row) => { const types = ['错误', '告警'] const currentIdx = types.indexOf(row.alarmType) row.alarmType = types[(currentIdx + 1) % types.length] } // 打开规则详情抽屉 const openDrawer = (row) => { currentRow.value = row drawerTitle.value = row.ruleNo activeRowId.value = row.id drawerVisible.value = true } // 关闭抽屉 const closeDrawer = () => { currentRow.value = null drawerTitle.value = '' activeRowId.value = null drawerVisible.value = false } // 保存规则集 const handleSave = async () => { const valid = await customFormRef.value.validate() if (!valid) return const savedData = { name: customForm.ruleSetName, enabledRules: ruleData.value.filter(rule => rule.enable), totalEnabled: ruleData.value.filter(rule => rule.enable).length, updateTime: new Date().toLocaleString() } console.log('保存规则集数据:', savedData) ElMessage.success('规则集保存成功') handlegoback() } // 返回上一页 const handlegoback = () => { router.push("/rules") } // 监听表格数据变化 watch( () => ruleTable.value, (newTableData) => { handleTableSelection(newTableData) }, { immediate: true, deep: true } ) // 监听选中数据变化 watch( () => selectedRows.value, (newSelected) => { if (isAllSelectedEnabled.value) { headerSelectValue.value = 'enableAll' } else { const validActions = ['enableAll', 'disableAll'] if (!validActions.includes(headerSelectValue.value)) { headerSelectValue.value = '' } } }, { deep: true } ) // 组件挂载完成后,确保表格选中状态初始化 onMounted(async () => { await nextTick() handleTableSelection(ruleTable.value) }) </script> <style scoped lang="scss"> :deep(.custom-form-item .el-form-item__content) { margin-left: 20px !important; } // 抽屉样式调整 :deep(.el-drawer__header) { margin-bottom: 0px !important; padding: 16px 24px !important; border-bottom: 1px solid #eee; } </style>分析代码,修改代码文件,1.完成VHDL和Verilog改为单选框,并且选择VHDL时,规则类别下面的多选框只显示VHDL的规则类别,选择Verilog时,只显示Verilog的规则类别。2.完成规则类别下面的多选框,点击时表格里面数据只显示当前点击的规则类别里面的编号,点击另一个时,只显示另一个规则类别的规则编号,增加模拟数据完善此功能。并且给当前点击的规则类别增加背景色,选择框显示改为为如图图标,用unocss。编写完整代码显示出来
最新发布
10-23
<think>我们有两个主要任务: 1. 将VHDL和Verilog的复选框改为单选框,并且根据选择过滤规则类别(左侧)和表格数据(右侧)。 2. 修改规则类别多选框为单选效果(每次只能选一个),并且点击某个类别时,表格只显示该类别下的规则,同时给选中的类别项添加背景色,并更改选择框图标为单选框(使用Unocss图标)。 步骤分解: 任务1:VHDL和Verilog改为单选框 - 将原来的两个复选框(el-checkbox)改为单选框(el-radio)或者使用单选框组(el-radio-group)。 - 因为只能选一种语言,所以我们用一个变量(比如`selectedLanguage`)来存储当前选中的语言('VHDL'或'Verilog')。 - 当选择VHDL时,规则类别只显示VHDL相关的类别;选择Verilog时,只显示Verilog相关的类别。 任务2:规则类别改为单选且点击时表格只显示当前类别 - 将规则类别的多选框(el-checkbox)改为单选框(例如使用el-radio或者改变交互方式,但题目要求用多选框改图标,且要求单选效果,所以我们可以使用el-checkbox但通过代码控制每次只选一个,并改变样式)。 - 要求:点击一个类别时,其他类别取消选中,并且表格只显示该类别下的规则。 - 同时,给当前选中的规则类别项添加背景色,并将复选框图标改为单选框图标(使用Unocss图标)。 由于原代码中规则类别是使用el-checkbox循环生成的,并且每个类别有一个checked属性。现在我们要改为单选,那么: - 我们需要一个变量(例如`selectedCategory`)来记录当前选中的类别名称(或索引)。 - 当点击一个类别时,将该类别的checked设为true,其他设为false。 但是,为了保持与之前的数据结构兼容,我们可以继续使用`ruleCategories`数组,但改变它的使用方式。 具体修改: 1. 将VHDL和Verilog的复选框改为单选框组: ```html <el-radio-group v-model="selectedLanguage"> <el-radio label="VHDL">VHDL</el-radio> <el-radio label="Verilog">Verilog</el-radio> </el-radio-group> ``` 并定义`selectedLanguage`,初始值设为'VHDL'。 2. 根据`selectedLanguage`来过滤规则类别(ruleCategories): 我们可以在`ruleCategories`的基础上,根据语言动态显示不同的类别数组。例如,我们可以将规则类别分为两组: - VHDL类别数组:['VHDL编码规则','VHDL同步设计规则','VHDL标头规则'] - Verilog类别数组:['Verilog编码规则','Verilog同步设计规则', ...] (需要新增模拟数据) 因此,我们需要重新组织规则类别数据,可以定义两个数组,然后根据语言选择显示其中一个。 或者,我们在原始数据中给每个类别增加一个`language`字段,然后通过计算属性来过滤出当前语言对应的类别。 3. 修改规则类别的显示为单选,并改变样式: - 我们将每个类别的`el-checkbox`改为点击事件,在点击时设置当前类别为选中,其他为未选中。 - 同时,我们给选中的类别添加一个背景色样式(例如`selected-category`),并修改前面的选择框为单选框图标(使用Unocss的图标,这里我们可以用i标签添加类名,比如`i-carbon-radio-button-checked`和`i-carbon-radio-button`)。 4. 修改表格数据的过滤(ruleTable): - 之前是通过多个选中的类别来过滤,现在改为只通过当前选中的类别(一个)来过滤。 5. 增加模拟数据以满足Verilog的显示。 由于原代码中规则数据(ruleData)只有VHDL的规则,我们需要增加Verilog的规则数据。 具体修改步骤: 步骤1:将语言选择改为单选框组,并定义selectedLanguage。 步骤2:定义规则类别时,我们重构ruleCategories,为每个类别增加language属性,然后根据selectedLanguage过滤显示的类别列表(计算属性)。 步骤3:修改规则类别的显示方式,不再使用v-model绑定checked,而是使用一个变量(selectedCategory)来记录当前选中的类别。当点击某个类别时,设置selectedCategory为该类别,并更新ruleCategories中该类别的checked为true,其他为false(实际上我们不需要在ruleCategories中维护checked,而是根据selectedCategory来判断是否选中)。 步骤4:修改ruleTable的computed属性,使其只根据selectedCategory进行过滤(同时还要考虑语言、搜索关键词等)。 步骤5:为选中的规则类别项添加背景色和单选框图标。 步骤6:增加Verilog的模拟规则数据。 考虑到代码量较大,我们将逐步修改代码。 以下是修改后的完整代码: </think>我将分析并修改代码以实现您的要求,以下是修改后的完整代码: ```vue <template> <div> <div class="flex justify-between items-center py-4 h-14 px-5"> <PageHeader :title="pageTitle" @back="handlegoback" /> <div class="flex gap-2.5"> <el-button type="default" @click="handlegoback">返回</el-button> <el-button type="primary" @click="handleSave">保存</el-button> </div> </div> <el-form :model="customForm" :rules="customRuleSet" ref="customFormRef" label-width="120px" class="flex gap-5 pt-5 border-t tlinter-border items-center pb-5" > <el-form-item label="规则集名称" prop="ruleSetName" class="m-0"> <el-input v-model="customForm.ruleSetName" placeholder="请输入1-20位规则集名称" show-word-limit class="w-60" /> </el-form-item> <el-text type="primary" class="mx-1 text-[#409eff] self-center" style="padding-bottom: 5px" > {{ usedRulesText }} </el-text> </el-form> <div class="flex gap-0 p-5 border-t tlinter-border"> <div class="flex flex-col gap-1 w-1/4 border-r tlinter-border pr-5 h-full"> <div class="w-full h-full"> <el-input v-model="searchQuery" placeholder="输入规则编号/描述查询" class="w-full" suffix-icon="Search" clearable /> </div> <!-- 修改为单选框 --> <div class="flex gap-4" label-width="0"> <el-radio-group v-model="selectedLanguage" @change="handleLanguageChange"> <el-radio label="VHDL" border size="small">VHDL</el-radio> <el-radio label="Verilog" border size="small">Verilog</el-radio> </el-radio-group> </div> <h1 class="font-inter text-base font-medium leading-[22px] tracking-0 tlinter-text-one pb-2">规则类别</h1> <div class="flex flex-col gap-3" label-width="0"> <!-- 修改为单选模式 --> <div v-for="(category, index) in filteredCategories" :key="index" class="flex items-center p-2 rounded-md cursor-pointer transition-colors duration-200" :class="{'bg-blue-50 border border-blue-200': category.name === selectedCategory}" @click="selectCategory(category)" > <div class="mr-2"> <!-- 使用单选框图标 --> <div v-if="category.name === selectedCategory" class="i-carbon-checkmark-circle-filled text-blue-500 w-5 h-5"></div> <div v-else class="i-carbon-circle-dash text-gray-400 w-5 h-5"></div> </div> <span class="text-sm">{{ category.name }}</span> </div> </div> </div> <div class="flex-1 w-3/4 custom-form-item"> <el-table ref="ruleTableRef" :data="ruleTable" style="width: 100%" row-key="id" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55" reserve-selection /> <el-table-column width="400" prop="ruleNo" label="规则编号" > <template #header> <div class="flex items-center gap-2"> <span>规则编号</span> <el-select v-model="headerSelectValue" :placeholder="selectPlaceholder" style="width: 120px" @change="handleHeaderSelectChange" > <el-option label="启用" value="enableAll"></el-option> <el-option label="禁用" value="disableAll"></el-option> </el-select> </div> </template> <template #default="scope"> <el-text @click="openDrawer(scope.row)" class="hover:text-primary cursor-pointer" :class="activeRowId === scope.row.id ? 'el-text--primary' : ''" > {{ scope.row.ruleNo }} </el-text> </template> </el-table-column> <el-table-column prop="description" label="描述" width="420" /> <el-table-column prop="alarmType" label="告警类型(点击标签可切换)" > <template #default="scope"> <el-tag :type="getTagType(scope.row.alarmType)" @click="toggleAlarmType(scope.row)" :class="scope.row.alarmType === '错误' ? 'tag-pink' : 'tag-yellow'" > ● {{ scope.row.alarmType }} </el-tag> </template> </el-table-column> </el-table> </div> </div> <el-drawer v-model="drawerVisible" :title="drawerTitle" size="30%" :before-close="closeDrawer" > <RuleDetails :current-row="currentRow" /> </el-drawer> </div> </template> <script setup> import { ref, computed, reactive, watch, onMounted, nextTick } from 'vue' import { useRouter, useRoute } from 'vue-router' import { Search } from '@element-plus/icons-vue' import { ElMessage } from 'element-plus' import RuleDetails from './components/ruleDetails.vue' import PageHeader from "@/components/PageHeader.vue"; const router = useRouter() const route = useRoute() const ruleTableRef = ref(null) const customFormRef = ref(null) const headerSelectValue = ref('') const searchQuery = ref('') // 修改:使用单选框管理语言选择 const selectedLanguage = ref('VHDL') // 修改:添加当前选中的类别 const selectedCategory = ref('') // 抽屉相关 const drawerVisible = ref(false) const currentRow = ref(null) const drawerTitle = ref('') const activeRowId = ref(null) // 表格选中数据 const selectedRows = ref([]) // 页面标题 const pageTitle = computed(() => { return route.query.ruleSetName || '自定义规则集' }) // 表单数据(规则集名称) const customForm = reactive({ ruleSetName: route.query.ruleSetName || '' }) // 表单校验规则 const customRuleSet = reactive({ ruleSetName: [ { required: true, message: '请输入规则集名称', trigger: 'blur' }, { max: 20, message: '规则集名称不能超过20个字符', trigger: 'blur' } ] }) // 规则类别(左侧筛选) - 修改:添加语言类型字段 const ruleCategories = ref([ { name: 'VHDL编码规则', language: 'VHDL' }, { name: 'VHDL同步设计规则', language: 'VHDL' }, { name: 'VHDL标头规则', language: 'VHDL' }, { name: 'Verilog编码规则', language: 'Verilog' }, { name: 'Verilog时序规则', language: 'Verilog' }, { name: 'Verilog模块结构规则', language: 'Verilog' }, { name: 'Verilog命名规则', language: 'Verilog' } ]) // 修改:根据语言过滤类别 const filteredCategories = computed(() => { return ruleCategories.value.filter( cat => cat.language === selectedLanguage.value ) }) // 表格原始数据 - 添加更多模拟数据 const ruleData = ref([ // VHDL规则 { id: 1, ruleNo: 'TLR-030001V', description: 'VHDL源文件应包含头注释', alarmType: '错误', category: 'VHDL编码规则', language: 'VHDL', enable: true }, { id: 2, ruleNo: 'TLR-030002V', description: '同步设计应遵循时钟域交叉原则', alarmType: '告警', category: 'VHDL同步设计规则', language: 'VHDL', enable: true }, { id: 3, ruleNo: 'TLR-030003V', description: '标头应包含版本、作者等信息', alarmType: '告警', category: 'VHDL标头规则', language: 'VHDL', enable: false }, { id: 4, ruleNo: 'TLR-030004V', description: '模块端口声明需指定方向(IN/OUT)', alarmType: '错误', category: 'VHDL编码规则', language: 'VHDL', enable: true }, // Verilog规则 { id: 5, ruleNo: 'TLR-040001R', description: 'Verilog模块应有端口声明列表', alarmType: '错误', category: 'Verilog编码规则', language: 'Verilog', enable: true }, { id: 6, ruleNo: 'TLR-040002R', description: '时序逻辑必须使用非阻塞赋值', alarmType: '警告', category: 'Verilog时序规则', language: 'Verilog', enable: true }, { id: 7, ruleNo: 'TLR-040003R', description: '模块应包含module-endmodule结构', alarmType: '错误', category: 'Verilog模块结构规则', language: 'Verilog', enable: true }, { id: 8, ruleNo: 'TLR-040004R', description: '变量命名应使用小写字母加下划线', alarmType: '警告', category: 'Verilog命名规则', language: 'Verilog', enable: false }, { id: 9, ruleNo: 'TLR-040005R', description: '避免使用组合逻辑产生锁存器', alarmType: '错误', category: 'Verilog时序规则', language: 'Verilog', enable: true } ]) // 过滤后的表格数据 - 修改:添加类别过滤 const ruleTable = computed(() => { let filteredData = ruleData.value.filter(item => item.language === selectedLanguage.value ) // 如果有选中的类别,则进一步过滤 if (selectedCategory.value) { filteredData = filteredData.filter(item => item.category === selectedCategory.value ) } // 搜索过滤 if (searchQuery.value.trim()) { const keyword = searchQuery.value.trim().toLowerCase() filteredData = filteredData.filter(item => item.ruleNo.toLowerCase().includes(keyword) || item.description.toLowerCase().includes(keyword) ) } return filteredData }) const isAllSelectedEnabled = computed(() => { if (selectedRows.value.length === 0) return false return selectedRows.value.every(row => row.enable === true) }) const selectPlaceholder = computed(() => { return isAllSelectedEnabled.value ? '已启用' : '启用状态' }) const usedRulesText = computed(() => { const enabledCount = ruleData.value.filter(rule => rule.enable === true).length return `已启用${enabledCount}条规则` }) const getTagType = computed(() => (alarmType) => { const typeMap = { '错误': 'danger', '告警': 'warning' } return typeMap[alarmType] || 'info' }) const handleTableSelection = (tableData) => { if (!ruleTableRef.value || !tableData || tableData.length === 0) { return } tableData.forEach(row => { ruleTableRef.value.toggleRowSelection(row, false) }) tableData.forEach(row => { if (row.enable) { ruleTableRef.value.toggleRowSelection(row, true) } }) } // 表格选中事件 const handleSelectionChange = (selection) => { selectedRows.value = selection } // 下拉框操作 const handleHeaderSelectChange = (value) => { switch (value) { case 'enableAll': handleBatchEnable() break case 'disableAll': handleBatchDisable() break } headerSelectValue.value = '' } // 批量启用 const handleBatchEnable = () => { if (selectedRows.value.length === 0) { ElMessage.warning('请先选择要启用的规则') return } ruleData.value.forEach(row => { row.enable = false }) selectedRows.value.forEach(selectedRow => { const targetRow = ruleData.value.find(row => row.id === selectedRow.id) if (targetRow) targetRow.enable = true }) handleTableSelection(ruleTable.value) } // 批量禁用 const handleBatchDisable = () => { if (selectedRows.value.length === 0) { ElMessage.warning('请先选择要禁用的规则') return } selectedRows.value.forEach(selectedRow => { const targetRow = ruleData.value.find(row => row.id === selectedRow.id) if (targetRow) targetRow.enable = false }) handleTableSelection(ruleTable.value) } // 切换告警类型 const toggleAlarmType = (row) => { const types = ['错误', '告警'] const currentIdx = types.indexOf(row.alarmType) row.alarmType = types[(currentIdx + 1) % types.length] } // 打开规则详情抽屉 const openDrawer = (row) => { currentRow.value = row drawerTitle.value = row.ruleNo activeRowId.value = row.id drawerVisible.value = true } // 关闭抽屉 const closeDrawer = () => { currentRow.value = null drawerTitle.value = '' activeRowId.value = null drawerVisible.value = false } // 保存规则集 const handleSave = async () => { const valid = await customFormRef.value.validate() if (!valid) return const savedData = { name: customForm.ruleSetName, enabledRules: ruleData.value.filter(rule => rule.enable), totalEnabled: ruleData.value.filter(rule => rule.enable).length, updateTime: new Date().toLocaleString() } console.log('保存规则集数据:', savedData) ElMessage.success('规则集保存成功') handlegoback() } // 返回上一页 const handlegoback = () => { router.push("/rules") } // 新增:选择规则类别 const selectCategory = (category) => { // 如果点击已选中的类别,则取消选择 if (selectedCategory.value === category.name) { selectedCategory.value = '' } else { selectedCategory.value = category.name } } // 新增:处理语言变更 const handleLanguageChange = () => { // 切换语言时重置选中的类别 selectedCategory.value = '' } // 监听表格数据变化 watch( () => ruleTable.value, (newTableData) => { handleTableSelection(newTableData) }, { immediate: true, deep: true } ) // 监听选中数据变化 watch( () => selectedRows.value, (newSelected) => { if (isAllSelectedEnabled.value) { headerSelectValue.value = 'enableAll' } else { const validActions = ['enableAll', 'disableAll'] if (!validActions.includes(headerSelectValue.value)) { headerSelectValue.value = '' } } }, { deep: true } ) // 组件挂载完成后,确保表格选中状态初始化 onMounted(async () => { await nextTick() handleTableSelection(ruleTable.value) }) </script> <style scoped lang="scss"> :deep(.custom-form-item .el-form-item__content) { margin-left: 20px !important; } // 抽屉样式调整 :deep(.el-drawer__header) { margin-bottom: 0px !important; padding: 16px 24px !important; border-bottom: 1px solid #eee; } // 新增样式:语言选择组 .radio-group-container { display: flex; gap: 16px; margin-bottom: 16px; } // 新增样式:类别项 .category-item { display: flex; align-items: center; padding: 8px 12px; border-radius: 6px; margin-bottom: 8px; cursor: pointer; transition: background-color 0.2s; &:hover { background-color: #f5f7fa; } &.selected { background-color: #ecf5ff; border: 1px solid #d9ecff; } .radio-icon { margin-right: 10px; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; } } </style> ``` ### 修改内容详解: 1. **VHDL/Verilog改为单选框**: - 将原来的两个复选框改为单选框组(`el-radio-group`) - 添加 `selectedLanguage` 响应式变量(默认为'VHDL') - 新增 `handleLanguageChange` 方法处理语言变更事件,切换语言时重置类别选择 2. **规则类别单选功能**: - 移除原来的多选框,改为点击选择模式 - 添加 `selectedCategory` 响应式变量存储当前选中的类别 - 新增 `selectCategory` 方法处理类别选择逻辑
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值