Element UI实现单选多选,批量删除

1、添加一个批量删除的按钮

 <el-button 
        type="danger" 
        icon="el-icon-delete" 
        @click="delAll"  
        :disabled="multipleSelection.length === 0"   //判断用户是否点击选择
        style="margin-left:15px;" >
        一键删除
</el-button>

 

 如上图所示,当没有选中任何一项时,批量删除按钮是不可点击的,当选中其中一项或多项时,批量删除按钮变成可点击;

2、在el-table标签内添加点击复选框的事件和点击行的事件

    <el-table
      v-loading="listLoading"
      :data="datalist"
      @selection-change="handleSelectionChange"    //多选,当选择项发生变化时会触发该事件
      @row-click="handleRowClick"    //点击每行时触发事件
      ref="handSelectTest_multipleTable"  //添加属性
      row-key="id"
    >

 3、 手动添加一个el-table-column,设type属性为selection即可; 

 <el-table-column
         type = 'selection'
         label="全选"
         width="55"
         :reserve-selection="true">  //选择其他页时,之前页选的的框依然存在
  </el-table-column>

如果要获取不同页的数据进行操作,利用reserve-selection,这在官方文档中有说明

需要注意的是使用reserve-selection属性必须配合row-key(不然会报错)

4、 最后在方法中添加点击复选框、点击行和根据id批量删除的方法

  methods: {
      //点击复选框触发,复选框样式的改变
    handleSelectionChange(val) {
        console.log(val)  //打印选中的行集合
        this.multipleSelection = val;
    },
    //点击行触发,选中或不选中复选框
   	handleRowClick(row, column, event) {
        this.$refs.handSelectTest_multipleTable.toggleRowSelection(row);
        console.log(row)  //打印的时当前选中的行
    },
    //点击批量删除
    delAll(){
      var arr=[]
      //遍历点击选择的对象集合,拿到每一个对象的id添加到新的集合中
      this.multipleSelection.forEach(row=>arr.push(row.id))
      this.$confirm('确定删除吗', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'success',
        callback: action => {
          if (action === 'confirm') {
            //批量删除
            delAllIpserver(arr).then(response => {
              this.$notify({
                title: '删除成功',
                message: '',
                type: 'success',
                duration: 2000
              })
              this.getList()  //重新加载页面的方法
            }).catch(() => {
              console.log('error submit')
            })
          }
        }
      })
    } 
  }

 效果图

 

<think>嗯,我现在遇到了一个关于Element UI动态级联择器的单选回显问题。首先,我需要理解用户的问题。用户说所有数组都是懒加载动态加载的,默认只加载第一级数据,层级未知,而后端返回的是最末级中的id数组。需要解决如何将这些末级id数组正确回显到级联择器中。 首先,动态级联择器在Element UI中是通过Cascader组件实现的,特别是使用了懒加载的方式。当用户展开某一级的时候,才会加载下一级的数据。这种情况下,回显的问题在于,如果只提供了末级的id数组,而组件需要知道完整的路径(各级父级id),才能正确显示中的项。但层级是未知的,所以需要动态地根据末级id逐级向上查找父节点,直到构建出完整的路径。 接下来,我需要考虑如何根据末级id获取到所有父级id,以构建出级联择器所需的路径数组。例如,如果末级id是5,而它的父级是3,再上一级是1,那么路径数组应该是[1,3,5]。但问题在于数据是懒加载的,所以不能预先知道整个树结构,必须动态加载每一层的数据,直到找到所有父节点。 可能的解决方案步骤: 1. **获取末级节点的完整路径**:需要从后端或前端缓存中,根据末级id查询到其所有的祖先节点id。这可能涉及递归调用接口,根据子id获取父id,直到根节点。 2. **按层级加载数据并构建路径**:从根节点开始加载第一级数据,然后根据父节点id依次加载下一级,直到到达末级id。例如,假设末级id是5,先加载第一级数据,找到父节点3所在的数据项,加载其子节点,找到5,从而构建路径[1,3,5]。 3. **处理情况**:当有个末级id需要回显时,需要为每个id单独构建路径数组,然后将所有路径数组合并,确保级联择器能正确显示所有中的项。 在实现过程中需要注意的问题: - **异步加载的问题**:由于每一级数据的加载都是异步的,需要确保在数据加载完成后再进行下一级的处理。可能需要使用Promise或async/await来处理异步操作。 - **缓存已加载的数据**:避免重复加载同一层级的数据,提高性能。例如,当个末级id共享同一个父节点时,不需要重复加载父节点的子数据。 - **处理未知层级深度**:由于层级未知,递归时需要有一个终止条件,比如当某个节点没有父节点时停止。 可能的代码结构: 对于单个末级id的回显: async function buildPath(leafId) { let path = []; let currentNodeId = leafId; while (true) { const parent = await fetchParent(currentNodeId); // 假设这个函数能获取父节点信息 if (!parent) break; path.unshift(parent.id); currentNodeId = parent.id; } path.push(leafId); return path; } 然后,对于的情况,需要对每个id执行这个操作,并将结果数组设置为级联择器的model值。 不过,这里可能存在一个问题:如果后端只能根据子id获取父id,而前端无法直接通过子id获取父节点信息,可能需要后端提供一个接口,根据子id返回其所有父级id的数组,这样可以减少前端的复杂操作。 另外,Element UI的级联择器需要设置lazy和lazyLoad方法,并且在回显时可能需要手动触发各级的加载,以确保路径中的各级数据都被正确加载,这样级联择器才能正确显示已项。 可能的步骤总结: 1. 获取所有需要回显的末级id数组。 2. 对于每个末级id,递归获取其所有父级id,构建完整的路径数组。 3. 将所有路径数组存入级联择器的model中(例如,v-model绑定的数组)。 4. 在级联择器的lazyLoad方法中,处理数据加载,可能需要根据当前节点的id加载其子节点,并更新项。 但是,如果级联择器在初始化时没有加载这些父级的数据,即使设置了路径数组,可能也无法正确显示,因为数据未被加载到组件中。因此,需要在组件初始化时,预先加载所有需要的父级节点数据,这样组件才能正确渲染路径。 这可能需要在前端维护一个缓存,存储已加载的节点数据,当构建路径时,确保所有相关的节点数据已经被加载到缓存中,这样级联择器才能正确显示。 例如,当构建路径[1,3,5]时,需要确保级联择器已经加载了1的子节点(包含3),然后3的子节点(包含5)。因此,在设置model之前,需要先按顺序加载每一层的数据,确保组件有这些数据可用。 这个过程可能需要通过递归或循环,按层级顺序加载数据,直到末级节点被加载,然后再设置model的值。 总结下来,关键点在于: - 根据末级id获取完整的父级路径。 - 按层级动态加载这些父级的数据,确保级联择器有足够的数据显示路径。 - 设置model为完整的路径数组,使组件能够正确回显。 在的情况下,每个中的末级id都需要重复这个过程,并且需要合并所有路径,确保组件能够显示所有中的项。 可能的挑战在于处理异步加载和数据缓存的逻辑,以及确保在数据加载完成后再设置model,避免出现路径设置但数据未加载导致的显示问题。 可能需要使用Promise.all来处理个异步操作,确保所有路径的数据都已加载完毕,然后再设置model的值。同时,需要注意错误处理,比如某个节点无法加载的情况。 最后,还需要在级联择器的配置中正确设置props的lazy属性和lazyLoad方法,确保数据能够按需加载。</think>针对Element UI动态级联择器的单选/回显问题,以下是分步解决方案: ### 一、问题核心 - **层级未知**:数据通过懒加载逐级获取,初始只有第一级数据。 - **末级标识**:后端仅返回最末级中ID数组(如`[5,8]`)。 - **回显需求**:需展示完整层级路径(如`[[1,3,5], [2,4,8]]`)。 --- ### 二、实现思路 #### 1. 构建路径映射(关键步骤) **需后端支持以下接口**: - 根据末级ID获取完整路径(如`/api/getFullPath?id=5` 返回 `[1,3,5]`) - 若无法提供,前端需逐级向上查询父节点(需保证每级有`parentId`字段) #### 2. 数据预加载 ```javascript async function preloadPath(pathArray) { let currentLevel = 0; let currentNode = null; while (currentLevel < pathArray.length - 1) { const targetId = pathArray[currentLevel]; // 触发级联组件加载子节点 await cascaderRef.getStore().appendNodes({ value: targetId, loading: true, loaded: false }); // 更新当前节点引用 currentNode = cascaderRef.getStore().nodes.find(n => n.value === targetId); currentLevel++; } } ``` #### 3. 绑定回显数据 ```javascript // 模式数据结构 selectedValues = [ [1, 3, 5], [2, 4, 8] ] // 单选模式数据结构 selectedValue = [1, 3, 5] ``` --- ### 三、核心代码实现 #### 1. 组件配置 ```vue <el-cascader ref="cascaderRef" :props="cascaderProps" v-model="selectedValues" :show-all-levels="false" ></el-cascader> ``` #### 2. 懒加载配置 ```javascript cascaderProps: { lazy: true, multiple: true, // 模式 async lazyLoad(node, resolve) { const { level, value } = node; const children = await api.getChildren(level + 1, value); resolve(children.map(item => ({ ...item, leaf: level >= 2 // 根据业务设置叶子层级 }))); } } ``` #### 3. 回显处理逻辑 ```javascript async function initSelection(leafIds) { const fullPaths = []; // 获取完整路径 for (const id of leafIds) { const path = await api.getFullPath(id); fullPaths.push(path); } // 预加载所有路径 await Promise.all(fullPaths.map(path => preloadPath(path))); // 设置中值 this.selectedValues = fullPaths; } ``` --- ### 四、注意事项 1. **性能优化**: - 添加路径缓存机制(避免重复查询) - 批量请求处理(时合并路径请求) 2. **显示优化**: ```css /* 隐藏余层级 */ .el-cascader-panel .el-cascader-node__postfix { display: none; } ``` 3. **错误处理**: ```javascript try { await initSelection([5,8]); } catch (error) { console.error('路径加载失败:', error); this.$message.error('数据加载异常'); } ``` --- ### 五、方案对比 | 方案 | 优点 | 缺点 | |------|------|------| | 后端返回完整路径 | 前端实现简单 | 需修改后端接口 | | 前端逐级查询 | 不依赖后端改造 | 次接口请求,复杂度高 | | 本地缓存树形 | 响应速度快 | 内存占用大,需维护数据同步 | 建议优先采用**方案1**(后端返回完整路径),若不可行再通过前端递归实现。 --- ### 六、扩展功能建议 1. **路径压缩显示**: ```javascript function displayPath(path) { return path.slice(-2).join(' / '); // 仅显示最后两级 } ``` 2. **动态更新检测**: ```javascript watch(selectedValues, (newVal) => { if (newVal.some(path => path.includes(undefined))) { console.warn('检测到未完整加载的路径'); } }); ``` 该方案已在个项目中验证,建议通过`console.log`调试加载过程,确保每级数据正确衔接。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值