Vue中使用Transfer实现表格穿梭框(可搜索)

Vue中使用Transfer实现表格穿梭框(可搜索)

需求:使用Transfer实现带分页并可搜索的穿梭框。给不同用户分配不同的应用服务。

前端

1.注册组件(main.js)

import {  Transfer, Table, Switch } from 'ant-design-vue'
Vue.use(Transfer)
Vue.use(Table)
Vue.use(Switch)

2.Transfer中使用 Table 组件自定义渲染列表

这里用的是eladmin-ui中的el-dialog,以点击按钮的方式弹出穿梭框

2.1 自定义渲染列表
<el-dialog v-if="transferVisible" append-to-body :close-on-click-modal="false" :visible.sync="transferVisible" width="1000px" @before-close="transferClose">
  <div>
    <a-transfer
      :data-source="mockData"
      :target-keys="targetKeys"
      :show-search="true"
      :filter-option="(inputValue, item) => item.title.indexOf(inputValue) !== -1"
      :show-select-all="false"
      @change="onChange"
    >
      <template
        slot="children"
        slot-scope="{
          props: { direction, filteredItems, selectedKeys, disabled: listDisabled },
          on: { itemSelectAll, itemSelect },
        }"
      >
        <a-table
          :row-selection="
            getRowSelection({ disabled: listDisabled, selectedKeys, itemSelectAll, itemSelect })
          "
          :columns="direction === 'left' ? leftColumns : rightColumns"
          :data-source="filteredItems"
          size="small"
          :style="{ pointerEvents: listDisabled ? 'none' : null }"
          :custom-row="
            ({ key, disabled: itemDisabled }) => ({
              on: {
                click: () => {
                  if (itemDisabled || listDisabled) return;
                  itemSelect(key, !selectedKeys.includes(key));
                },
              },
            })
          "
        />
      </template>
    </a-transfer>
  </div>
  <div slot="footer">
    <el-button type="text" @click="transferClose">取消</el-button>
    <el-button type="primary" @click="transferSub">提交</el-button>
  </div>
</el-dialog>
2.2 定义变量
const mockData = []
const originTargetKeys = []
const leftTableColumns = [
  {
    dataIndex: 'title',
    title: '应用名称'
  },
  {
    dataIndex: 'description',
    title: '服务名称'
  }
]
const rightTableColumns = [
  {
    dataIndex: 'title',
    title: '应用名称'
  }
]
data(){
	return {
      transferVisible: false,
      mockData,
      targetKeys: originTargetKeys,
      disabled: false,
      showSearch: false,
      leftColumns: leftTableColumns,
      rightColumns: rightTableColumns,
}
2.3 回调函数
onChange(nextTargetKeys) {
  this.targetKeys = nextTargetKeys
},
getRowSelection({ disabled, selectedKeys, itemSelectAll, itemSelect }) {
  return {
    getCheckboxProps: item => ({ props: { disabled: disabled || item.disabled }}),
    onSelectAll(selected, selectedRows) {
      const treeSelectedKeys = selectedRows
        .filter(item => !item.disabled)
        .map(({ key }) => key)
      const diffKeys = selected
        ? difference(treeSelectedKeys, selectedKeys)
        : difference(selectedKeys, treeSelectedKeys)
      itemSelectAll(diffKeys, selected)
    },
    onSelect({ key }, selected) {
      itemSelect(key, selected)
    },
    selectedRowKeys: selectedKeys
  }
}

3.加载渲染数据

3.1 渲染mockData(左边数据)

这里页面加载就获取全部数据并渲染mockData

created() {
	this.initAppData()
},
methods: {
   initAppData() {
     getAppAll().then(res => {
       if (res.data && res.data.length > 0) {
         this.mockData = res.data.map(item => {
           return {
             key: item.appid,
             title: item.appName || '暂无',
             description: item.serviceName || '暂无',
             disabled: false
           }
         })
       }
     }).catch(() => { })
   }
}

这里getAppAll()的后台接口就不贴出来了,就是简单地获取List。

3.2 加载用户数据(右边数据)

queryListByUserId:根据不同的用户Id获取对应的应用List<Id>;后台实现见下面后端代码。

// 分配App
allot(rowData) {
 this.transferVisible = true
 this.userId = rowData.id
 queryListByUserId({ userId: rowData.id }).then(response => {
   mockData.filter(item => response.indexOf(item.key) > 0).map(item => item.key)
   this.targetKeys = response
 }).catch(() => { })
},
// 关闭穿梭框
transferClose() {
 this.transferVisible = false
}

后端

1.关联表

建立用户和应用的关联表
在这里插入图片描述

2.查询关联数据

自己实现对应的查询逻辑,这里只贴Service代码

/**
 * 根据用户ID查询App信息
 * @param userId
 * @return
 */
List<String> queryListByUserId(String userId);

3.提交绑定

前端提交按钮事件:

transferSub() {
 addUserApps({ userId: this.userId.toString(), appIds: this.targetKeys }).then(res => {
   this.$notify({
     title: '提交成功',
     type: 'success',
     duration: 2500
   })
   this.transferVisible = false
 }).catch((err) => {
   this.$notify({
     title: '提交失败' + err,
     type: 'error',
     duration: 2500
   })
 })
}

后端提交逻辑(因本人比较懒,采用的是先删除再添加的懒人方法)

public Result addUserApps(@RequestBody UsersAppsVo usersAppsVo){
   // 先删除
   usersAppsService.delAppsByUserId(usersAppsVo.getUserId());
   // 再插入
   usersAppsService.addUserApps(usersAppsVo.getAppIds(),usersAppsVo.getUserId());
   return  Result.ok();
}

效果图:
在这里插入图片描述

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
可以使用Element Plus的Transfer组件结合Table组件来实现镶嵌表格穿梭组件。具体步骤如下: 1. 引入Transfer和Table组件 ```javascript import { Transfer, TableColumn } from 'element-plus'; ``` 2. 定义需要穿梭的数据和列配置 ```javascript // 穿梭左侧表格数据 const tableData = [ { id: 1, name: 'John Brown', age: 18, address: 'New York No.1 Lake Park' }, { id: 2, name: 'Jim Green', age: 24, address: 'London No.1 Lake Park' }, { id: 3, name: 'Joe Black', age: 30, address: 'Sydney No.1 Lake Park' }, { id: 4, name: 'Jon Snow', age: 26, address: 'Winterfell No.1 Castle' } ]; // 穿梭左侧表格列配置 const tableColumns = [ { label: '姓名', prop: 'name' }, { label: '年龄', prop: 'age' }, { label: '地址', prop: 'address' } ]; ``` 3. 在模板使用Transfer和Table组件 ```html <el-transfer v-model="selectedData" :data="tableData" :titles="['可选数据', '已选数据']" > <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="年龄" prop="age"></el-table-column> <el-table-column label="地址" prop="address"></el-table-column> </el-transfer> ``` 4. 完整示例代码 ```html <template> <div> <el-transfer v-model="selectedData" :data="tableData" :titles="['可选数据', '已选数据']" > <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="年龄" prop="age"></el-table-column> <el-table-column label="地址" prop="address"></el-table-column> </el-transfer> </div> </template> <script> import { Transfer, TableColumn } from 'element-plus'; export default { components: { Transfer, TableColumn }, data() { return { tableData: [ { id: 1, name: 'John Brown', age: 18, address: 'New York No.1 Lake Park' }, { id: 2, name: 'Jim Green', age: 24, address: 'London No.1 Lake Park' }, { id: 3, name: 'Joe Black', age: 30, address: 'Sydney No.1 Lake Park' }, { id: 4, name: 'Jon Snow', age: 26, address: 'Winterfell No.1 Castle' } ], selectedData: [] }; } }; </script> ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值