最近在一个项目中要对权限进行分配 后面看了一下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>