使用Vue3实现一个穿梭框效果的示例代码
作者:JacksonChen
效果
当选中数据,并且点击相对应的方向箭头时,选中的数据会发送到对面,并且数据会保持正确的顺序进行排列。
实现
左右两边逻辑一致,这里只对左侧的进行分析
先看一下 html 结构 方便理解
<div class="module-wrapper"> <div class="module-head"> <span>list1</span> <span>{{ currentSelectLeft }}</span> </div> <div class="module-content"> <div v-if="!listLeft.length" style="text-align: center">No data</div> <div class="module-item" v-for="(item, index) in listLeft" @click="handleTransferLeft(index)"> <input style="width: 20px; height: 20px" type="checkbox" :checked="item.checked" /> <span :style="{ color: item.checked ? '#68b2ff' : '#000', }" >{{ item.label }}</span > </div> </div> </div>
数据处理
首先初始化 10 条穿梭框数据,key 属性用于排序,label 用于展示数据,最后为数据添加 checked 属性(主要用于标记是否被选中),然后将数据赋值给左边的列表 listLeft。
function getListData() { let data = [] for (let index = 1; index <= 10; index++) { data.push({ key: index, label: 'option' + index, }) } //对data进行处理 默认我们认为没有checked属性 data.forEach((item) => { item.checked = false }) listLeft.value = data }
点击状态取反
上面我们初始化了数据,下面需要做的是当点击每一项 option 的时候让状态取反。
点击 option 时只需把相应的 index 传入,然后进行取反操作即可。
// 点击进行状态取反 function handleTransferLeft(currentIndex) { listLeft.value[currentIndex].checked = !listLeft.value[currentIndex].checked }
比例状态
我们看到了上面的已选数据和总数据的比例状态
先拿到已选数据
// 左侧checked的数据 const currentCheckedLeft = computed(() => { return listLeft.value.filter((item) => item.checked) })
将左侧选中数据的长度 比上 数据总长度即可
点击箭头进行穿梭
// 点击右箭头 function toRight() { // 对选中数据进行深拷贝 const deepCloneData = JSON.parse(JSON.stringify(currentCheckedLeft.value)) // 把刚选择的数据状态进行清除 deepCloneData.forEach((item) => { item.checked = false }) // 把选中的数据添加到右边 需要把刚选择的数据状态进行清除 listRight.value.push(...deepCloneData) // 对右边数据进行重新排序 listRight.value.sort((a, b) => a.key - b.key) // 找到未选中数据 进行重新赋值 const noCheckedLeftData = listLeft.value.filter((item) => !item.checked) listLeft.value = noCheckedLeftData }
先对选中数据清除状态,因为如果不清除状态可能会导致穿梭过的的数据仍然还是选中。
如图所示:1,2是刚穿梭过去的数据,仍保留状态
注意需要对选中数据进行深拷贝,因为下面需要用到未选中的数据,如果不进行深拷贝,那下面再去筛选未选中的数据时就会把所有的数据选中。
// 对选中数据进行深拷贝 const deepCloneData = JSON.parse(JSON.stringify(currentCheckedLeft.value)) // 把刚选择的数据状态进行清除 deepCloneData.forEach((item) => { item.checked = false })
接下来筛选出来选中数据后,将数据添加到右边的数组
// 把选中的数据添加到右边 需要把刚选择的数据状态进行清除 listRight.value.push(...deepCloneData)
然后再对右边的数组进行排序
// 对右边数据进行重新排序 listRight.value.sort((a, b) => a.key - b.key)
现在已经将数据穿梭到右侧,那怎么去除左侧已穿梭的数据呢?
筛选出来左边未选择的数据,重新赋值给左边数组即可
// 找到未选中数据 进行重新赋值 const noCheckedLeftData = listLeft.value.filter((item) => !item.checked) listLeft.value = noCheckedLeftData
这一步也是上面为什么深拷贝的原因。
如果不进行深拷贝,如图所示:
已经穿梭了过去,但是取未筛选数据时,因为上面的状态已经取反,这里都会选择到。
总结
我们需要知道如果要实现一个穿梭框效果,我们大概都需要做哪些东西呢?
那首先是对左侧的初始化数据,我们需要对数据进行加工,添加 checked 属性,方便后面进行筛选。
其次是我们找出我们选中的数据,添加到右侧,同时把左侧选中的数据进行移除。
源码
GitHub:https://github.com/chenyajun-create/transfer
以上就是使用Vue3实现一个穿梭框效果的示例代码的详细内容,更多关于Vue3实现穿梭框的资料请关注脚本之家其它相关文章!