Vue 仿Transfer 穿梭框功能实现人员选择,左侧备选列表,右侧已选列表,带搜索带备注项
Vue 仿Transfer 穿梭框功能实现人员选择,左侧备选列表,右侧已选列表,带搜索带备注项
·
老规矩,先上效果图
设计出来的东西,非说element组件库穿梭框就有 , 扯犊子, 人名下面的手机号怎么加md…
还得靠自己实现 , 真操蛋啊…
- 左右侧数据带搜索,前端本地实现搜索功能
- 后台接口对接,代码中还未对接
- 如有帮助到您,还望一键三连
代码
<template>
<el-drawer
class="associated-member"
title="关联成员"
:visible.sync="drawer"
:direction="direction"
:append-to-body="modalToBody"
:modal-append-to-body="modalToBody"
:size="685"
>
<el-col :span="12" class="section-left">
<div class="header">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
>
全选
</el-checkbox>
</div>
<el-input
class="search"
size="mini"
placeholder="请输入姓名搜索"
suffix-icon="el-icon-search"
v-model="searchTextLeft"
clearable
@input="getSearch"
/>
<el-checkbox-group
class="checkbox-group"
v-model="checkedRoles"
@change="handleCheckedCitiesChange"
>
<el-checkbox
v-for="(role, index) in leftData"
:label="role.id"
:key="role.id"
>
{{ role.name }}
<p class="mt-10">{{ role.phone }}</p>
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col :span="12" class="section-right">
<div class="header">管理员</div>
<el-input
class="search"
size="mini"
placeholder="请输入姓名搜索"
suffix-icon="el-icon-search"
v-model="searchTextRight"
clearable
@input="getSearch"
/>
<div class="checked-group">
<el-col
class="li"
v-for="(role, index) in selectedRoles"
:key="role.name + role.id"
>
{{ role.name }}
<p class="mt-10">{{ role.phone }}</p>
<zn-icon :iconName="'icon-close'" @click="delRole(role, index)" />
</el-col>
</div>
</el-col>
<div class="drawer-footer">
<el-button class="el-cancel" @click="drawer = false">取消</el-button>
<el-button type="primary" @click="save">确定</el-button>
</div>
</el-drawer>
</template>
<script>
export default {
name: 'AssociatedMember',
props: {
modalToBody: {
type: Boolean,
default: () => true,
},
},
data() {
return {
drawer: false,
direction: 'rtl',
checkAll: false,
checkedRoles: [1, 3],
roles: [
{ name: '上海', id: 1, phone: '18989898998' },
{ name: '广州', id: 2, phone: '18989898998' },
{ name: '北京', id: 3, phone: '18989898998' },
{ name: '深圳', id: 4, phone: '18989898998' },
{ name: '石家庄', id: 5, phone: '18989898998' },
{ name: '唐山', id: 6, phone: '18989898998' },
{ name: '秦皇岛', id: 7, phone: '18989898998' },
{ name: '邯郸', id: 8, phone: '18989898998' },
{ name: '邢台', id: 9, phone: '18989898998' },
{ name: '保定', id: 10, phone: '18989898998' },
{ name: '张家口', id: 11, phone: '18989898998' },
{ name: '承德', id: 12, phone: '18989898998' },
{ name: '沧州', id: 13, phone: '18989898998' },
{ name: '廊坊', id: 14, phone: '18989898998' },
],
isIndeterminate: true,
searchTextLeft: '',
searchTextRight: '',
}
},
computed: {
// 右侧已选数据
selectedRoles() {
let arr = []
if (this.checkedRoles.length > 0) {
arr = this.roles.filter((item) => this.checkedRoles.includes(item.id))
if (this.searchTextRight) {
return this.compare(
arr.filter((i) => i.name.includes(this.searchTextRight))
)
} else {
return this.compare(arr) //根据人名排序
}
}
},
leftData() {
if (this.searchTextLeft) {
return this.roles.filter((i) => i.name.includes(this.searchTextLeft))
} else {
return this.roles
}
},
},
methods: {
showEdit(row) {
this.drawer = true
},
// 处理搜索
getSearch() {
if (this.searchTextLeft) {
return this.leftData
}
if (this.searchTextRight) {
return this.selectedRoles
}
},
handleCheckAllChange(val) {
this.checkedRoles = val
? this.roles.map((i) => {
return i.id
})
: [] //深拷贝解决全选之后单个删除右侧数据会触发左侧数据源的删除
this.isIndeterminate = false
},
handleCheckedCitiesChange(value) {
let checkedCount = value.length
this.checkAll = checkedCount === this.roles.length
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.roles.length
},
// 删除某一个
delRole(role, index) {
let idx = this.checkedRoles.findIndex((itm) => itm == role.id)
if (idx != -1) {
this.checkedRoles.splice(idx, 1)
}
},
// 提交
save() {
console.log('this.selectedRoles', this.selectedRoles)
},
},
}
</script>
<style lang="scss" scoped>
.associated-member {
position: relative;
.el-select {
width: 100%;
}
.el-drawer__body {
padding: 16px 24px;
.section-left,
.section-right {
height: calc(100% - 68px);
overflow: hidden;
border: 1px solid $base-line-2;
border-collapse: collapse;
.header {
height: $base-input-height;
padding-left: 16px;
line-height: $base-input-height;
background: $base-fill-2;
}
.search {
width: 100%;
padding: 8px 12px;
border-radius: 2px;
.el-input__inner {
background: $base-fill-3;
}
::v-deep .el-input__suffix {
margin-right: 10px !important;
top: 2px;
color: $base-fill-6;
}
}
::v-deep.checkbox-group {
height: calc(100% - 84px);
overflow-y: auto;
.el-checkbox {
width: 100%;
height: 62px;
padding: 7px 16px 0 16px;
margin-right: 0;
// padding: 10px 0;
.el-checkbox__input {
margin-top: 3px;
vertical-align: top;
}
p {
color: $base-text-3;
}
&:hover {
background: $base-fill-2;
}
}
}
}
.section-left {
border-top-left-radius: $base-border-radius-4;
border-bottom-left-radius: $base-border-radius-4;
}
.section-right {
border-left: none;
border-top-right-radius: $base-border-radius-4;
border-bottom-right-radius: $base-border-radius-4;
.checked-group {
height: calc(100% - 84px);
overflow-y: auto;
.li {
height: 62px;
padding: 7px 16px 0 16px;
position: relative;
p {
line-height: 21px;
color: $base-text-3;
}
.zn-icon {
position: absolute;
right: 28px;
top: 23px;
color: $base-fill-5;
}
&:hover {
background: $base-fill-2;
}
}
}
}
}
// drawer footer
.drawer-footer {
justify-content: flex-end;
background: #fff;
position: absolute;
left: 0;
bottom: 0;
right: 0;
padding: 16px 24px;
box-shadow: 0px -4px 10px 0px #0000001a;
.el-button {
padding: 0;
min-width: 83px;
line-height: 36px;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
border: none;
}
.el-cancel {
background: $base-fill-3;
}
}
}
</style>
补充方法
补充样式
scss变量
$base-line-2:#E5E6EB;
$base-input-height: 40px;
$base-fill-3:#F2F3F5;
$base-fill-6:#4E5969;
$base-border-radius-4:4px;
$base-border-radius-6:6px;
滚动条样式
@mixin base-scrollbar {
&::-webkit-scrollbar {
width: 4px;
height: 4px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba($base-menu-background, 0.1);
border: 3px solid transparent;
border-radius: 7px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: rgba($base-menu-background, 0.2);
}
}
更多推荐
已为社区贡献25条内容
所有评论(0)