Transfer 穿梭框 实现权限分配

作者描述了在项目中遇到ElementTransfer组件不适合的情况,因此创建了一个自定义的权限管理组件,用户可以方便地添加和移除权限。组件包含左右两个部分,分别展示可分配和已分配的权限,通过Vue和TypeScript实现交互功能。
摘要由CSDN通过智能技术生成

最近在一个项目中要对权限进行分配 后面看了一下Element里Transfer 穿梭框比较合适 后来到项目中使用发现 不太合适 它这个组件需要把勾选的数据 传到右边的框里面再次点击确定键才可以实现权限增加 或许有办法实现但是我觉得改起来太麻烦了

然后就模仿Element Transfer 穿梭框 自己写了一个组件 左边是没有的权限 右边是所享的权限 点击增加 或移除按钮就会对权限进行操作

模板代码 

<template>
  <div class="-container">
    <div class="box">
      <ul id="left">
        <div class="title">
          <input id="all" ref="all" :checked="checkbox" name="1" type="checkbox" @click="addAll" />
          所有权限
          <span style="position: absolute; right: 10px">{{ yesListId.length }}/{{ left.length }}</span>
        </div>
        <el-scrollbar height="350px">
          <li v-for="item in left" :key="item.id">
            <input :checked="checkboxItem" name="1" type="checkbox" :value="item.id" @change="iptChange" />
            <div class="text">{{ item.name }}</div>
          </li>
          <div v-if="left.length == 0">权限都挂载您身上啦</div>
        </el-scrollbar>
      </ul>
      <div class="button">
        <el-button type="primary" @click="add">添加</el-button>
        <el-button type="primary" @click="del">移除</el-button>
      </div>
      <ul id="right">
        <div class="title">
          <input ref="all" :checked="del_checkbox" name="1" type="checkbox" @click="delAll" />
          所享权限
          <span style="position: absolute; right: 10px">{{ delListId.length }}/{{ right.length }}</span>
        </div>
        <el-scrollbar height="350px">
          <li v-for="item in right" :key="item.id">
            <input :checked="del_checkboxItem" name="1" type="checkbox" :value="item.id" @change="delChange" />
            <div class="text">{{ item.name }}</div>
          </li>
          <div v-if="right.length == 0">您没有任何权限</div>
        </el-scrollbar>
      </ul>
    </div>
  </div>
</template>

 

js代码

<script lang="ts" setup>
defineOptions({
  name: 'Demo',
})
const checkbox = ref<boolean>(false)
const checkboxItem = ref<boolean>(false)
const del_checkbox = ref<boolean>(false)
const del_checkboxItem = ref<boolean>(false)
const emit = defineEmits(['left-change', 'right-change'])
// 获取父组件传递的值
const props = defineProps({
  letfList: {
    type: Array,
  },
  rightList: {
    type: Array,
  },
})
const left = ref<any>([])
const right = ref<any>([])
onMounted(() => {
  // 页面初始化在组件内使用
  left.value = props.letfList
  right.value = props.rightList
})

const yesListId = ref<any>([])
// 增加权限监听
const iptChange = (e: any) => {
  // 首先判断要增加的权限数组里面有没有
  if (yesListId.value.includes(Number(e.target.value))) {
    // 删除操作 在数组里面有id且权限id长度为1的时候删除掉
    if (yesListId.value.length == 1) {
      yesListId.value.shift()
    }
    // console.log(yesListId.value.findIndex((item: any) => item == Number(e.target.value)))
    // 删除操作 拿到用户移除的权限id
    if (yesListId.value.findIndex((item: any) => item == Number(e.target.value)) + 1) {
      const index = yesListId.value.findIndex((item: any) => item == Number(e.target.value))
      console.log(index, 'index')
      // 删除掉指定元素 这里指权限id
      yesListId.value.splice(index, 1)
    }
  } else {
    // 没有就push进去权限id
    yesListId.value.push(Number(e.target.value))
  }
  // 全选操作 如果全选之后 用户勾选掉权限 则取消全选按钮高亮
  if (yesListId.value.length - 1 < left.value.length) {
    checkbox.value = false
  }
  if (yesListId.value.length == left.value.length) {
    checkbox.value = true
  }
}
const add = () => {
  // 向父组件传递要增加的权限id 这里是一个数组
  emit('left-change', yesListId.value)
  yesListId.value = []
}
// 删除逻辑
const delListId = ref<any>([])
// 删除操作 与新增操作同理
const delChange = (e: any) => {
  if (delListId.value.includes(Number(e.target.value))) {
    if (delListId.value.length == 1) {
      console.log(1111111111111)

      delListId.value.shift()
    }
    if (delListId.value.findIndex((item: any) => item == Number(e.target.value)) + 1) {
      const index = delListId.value.findIndex((item: any) => item == Number(e.target.value))
      console.log(index)
      delListId.value.splice(index, 1)
    }
  } else {
    console.log('push')
    delListId.value.push(Number(e.target.value))
  }
  if (delListId.value.length - 1 < right.value.length) {
    del_checkbox.value = false
  }
  if (delListId.value.length == right.value.length) {
    del_checkbox.value = true
  }
  // console.log(delListId.value)
}
const del = () => {
  emit('right-change', delListId.value)
  delListId.value = []
  console.log(right.value)
}
// 全选
const addAll = () => {
  checkbox.value = !checkbox.value
  if (checkbox.value) {
    checkboxItem.value = true
    yesListId.value = left.value.map((item: any) => item.id)
  } else {
    checkboxItem.value = false
    yesListId.value = []
  }
}
const delAll = () => {
  del_checkbox.value = !del_checkbox.value
  if (del_checkbox.value) {
    del_checkboxItem.value = true
    delListId.value = right.value.map((item: any) => item.id)
  } else {
    del_checkboxItem.value = false
    delListId.value = []
  }
}
onUnmounted(() => {
  console.log('组件关闭')
  ;(left.value = []), (right.value = [])
})
</script>

 css


<style lang="scss" scoped>
.box {
  display: flex;
  align-items: center;
  justify-content: center;
  li {
    display: flex;
    align-items: center;
    padding: 5px 3px;

    input {
      margin-right: 5px;
      cursor: pointer;
    }
    input:hover {
      border: 1px solid #4e88f3;
    }
    .text {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      list-style: none;
      cursor: pointer;
    }
    .text:hover {
      color: #4e88f3;
    }
  }
  ul {
    position: relative;
    width: 200px;
    min-height: 400px;
    padding: 35px 10px 10px 10px;
    // background-color: pink;
    border: 1px solid #ebeef5;
    border-radius: 5px;
    .title {
      position: absolute;
      top: 0;
      width: 100%;
      height: 30px;
      padding: 0 13px;
      margin-left: -10px;
      font-size: 16px;
      line-height: 30px;
      background-color: #f5f7fa;
    }
  }
  .button {
    margin: 0 20px;
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值