标签部分
<div class="search-box">
<div>
<div
style="
width: 100%;
text-align: center;
font-size: 16px;
font-weight: 700;
margin-bottom: 10px;
"
>
可用字段
</div>
<div class="one-box">
<div
v-for="(item, index) in sortleftDatas"
:key="index"
:class="{ hovered: hoverIndex === index }"
@mouseenter="onMouseEnter(index)"
@mouseleave="onMouseLeave"
style="
padding: 10px 20px;
font-size: 14px;
display: flex;
align-items: center;
"
@click="checkWords(item)"
>
<div
v-if="!item.checked"
class="check-box"
:class="{ 'check-box1': hoverIndex === index }"
></div>
<div v-if="item.checked" class="check-box2"><check-outlined /></div>
<div>{{ item.name }}</div>
</div>
</div>
</div>
<div class="box-btn">
<div>
<div style="margin-bottom: 6px">添加</div>
<a-button type="primary" @click="addRight">
<template #icon>
<CaretRightOutlined style="font-size: 22px" />
</template>
</a-button>
</div>
<div style="margin-top: 20px">
<a-button type="primary" @click="addLeft">
<template #icon>
<CaretLeftOutlined style="font-size: 22px" />
</template>
</a-button>
<div style="margin-top: 6px">移除</div>
</div>
</div>
<div>
<div
style="
width: 100%;
text-align: center;
font-size: 16px;
font-weight: 700;
margin-bottom: 10px;
"
>
选取的字段
</div>
<div class="one-box">
<div
v-for="(item, index) in sortrightDatas"
:key="index"
:class="{ hovered: hoverIndex2 === index }"
@mouseenter="onMouseEnter2(index)"
@mouseleave="onMouseLeave2"
style="
padding: 10px 20px;
font-size: 14px;
display: flex;
align-items: center;
"
@click="checkWords(item)"
>
<div
v-if="!item.checked"
class="check-box"
:class="{ 'check-box1': hoverIndex2 === index }"
></div>
<div v-if="item.checked" class="check-box2"><check-outlined /></div>
<div>{{ item.name }}</div>
</div>
</div>
</div>
<div class="box-btn">
<div>
<div style="margin-bottom: 6px">向上</div>
<a-button type="primary" @click="upNum">
<template #icon>
<CaretUpOutlined style="font-size: 22px" />
</template>
</a-button>
</div>
<div style="margin-top: 20px">
<a-button type="primary" @click="downNum">
<template #icon>
<CaretDownOutlined style="font-size: 22px" />
</template>
</a-button>
<div style="margin-top: 6px">向下</div>
</div>
</div>
</div>
css样式部分
.search-box {
display: flex;
margin: 40px 0 20px;
.one-box {
width: 340px;
height: 420px;
overflow-y: scroll;
border: 1px solid #c3c0c0ec;
display: flex;
flex-direction: column;
padding-top: 10px;
.hovered {
background-color: #f0f0f0;
cursor: pointer;
}
.check-box {
width: 20px;
height: 20px;
border: 1px solid #d4d4d4;
border-radius: 2px;
margin-right: 12px;
}
.check-box1 {
width: 20px;
height: 20px;
border: 1px solid #3a91f5;
border-radius: 2px;
margin-right: 12px;
}
.check-box2 {
width: 20px;
height: 20px;
border: 1px solid #3a91f5;
color: white;
background-color: #3a91f5;
border-radius: 2px;
margin-right: 12px;
display: flex;
justify-content: center;
align-items: center;
}
}
.box-btn {
width: 100px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
}
逻辑部分
const leftOptions = reactive({
datas: [
{ name: '字段1', checked: false, num: 0 },
{ name: '字段3', checked: false, num: 3 },
{ name: '字段2', checked: false, num: 2 },
{ name: '字段4', checked: false, num: 4 },
{ name: '字段5', checked: false, num: 5 },
{ name: '字段6', checked: false, num: 6 },
{ name: '字段7', checked: false, num: 7 },
{ name: '字段8', checked: false, num: 8 },
],
})
// 计算属性,返回按 num 排序的数据
const sortleftDatas = computed(() => {
return [...leftOptions.datas].sort((a, b) => a.num - b.num)
})
const rightOptions = reactive({
datas: [],
})
// 计算属性,返回按 num 排序的数据
const sortrightDatas = computed(() => {
return [...rightOptions.datas].sort((a, b) => a.num - b.num)
})
const hoverIndex = ref(-1) // 用于跟踪鼠标悬停的索引
const onMouseEnter = (index) => {
hoverIndex.value = index
}
const onMouseLeave = () => {
hoverIndex.value = -1
}
const hoverIndex2 = ref(-1) // 用于跟踪鼠标悬停的索引
const onMouseEnter2 = (index) => {
hoverIndex2.value = index
}
const onMouseLeave2 = () => {
hoverIndex2.value = -1
}
//选择选项
const checkWords = (item) => {
item.checked = !item.checked
}
//添加按钮
const addRight = () => {
let leftdata = leftOptions.datas
.filter((item) => item.checked == true)
.map((item) => {
return {
...item,
checked: false,
}
})
leftOptions.datas = leftOptions.datas.filter((item) => item.checked != true)
rightOptions.datas = [...rightOptions.datas]
rightOptions.datas.unshift(...leftdata)
rightOptions.datas = rightOptions.datas.map((item, index) => {
return {
...item,
num: index,
}
})
// console.log('rightOptions2', rightOptions.datas)
}
//移除按钮
const addLeft = () => {
let rightdata = rightOptions.datas
.filter((item) => item.checked == true)
.map((item) => {
return {
...item,
checked: false,
}
})
rightOptions.datas = rightOptions.datas.filter((item) => item.checked != true)
rightOptions.datas = rightOptions.datas.map((item, index) => {
return {
...item,
num: index,
}
})
leftOptions.datas = [...leftOptions.datas]
leftOptions.datas.unshift(...rightdata)
leftOptions.datas = leftOptions.datas.map((item, index) => {
return {
...item,
num: index,
}
})
// console.log('leftOptions2', leftOptions.datas)
}
//向上按钮
const upNum = () => {
for (let i = 0; i < rightOptions.datas.length; i++) {
const currentItem = rightOptions.datas[i]
if (currentItem.checked === true) {
let newIndex = i - 1
while (newIndex >= 0 && rightOptions.datas[newIndex].checked == true) {
newIndex--
}
if (newIndex < 0) {
newIndex = 0
}
rightOptions.datas.splice(newIndex, 0, rightOptions.datas.splice(i, 1)[0])
rightOptions.datas = rightOptions.datas.map((item, index) => ({
...item,
num: index,
}))
}
}
// console.log('leftOptions4', rightOptions.datas)
}
//向下按钮
const downNum = () => {
for (let i = rightOptions.datas.length - 1; i >= 0; i--) {
const currentItem = rightOptions.datas[i]
if (currentItem.checked === true) {
let newIndex = i + 1
while (
newIndex < rightOptions.datas.length &&
rightOptions.datas[newIndex].checked === true
) {
newIndex++
}
if (newIndex === rightOptions.datas.length) {
newIndex = i
}
rightOptions.datas.splice(newIndex, 0, rightOptions.datas.splice(i, 1)[0])
rightOptions.datas = rightOptions.datas.map((item, index) => ({
...item,
num: index,
}))
let j = newIndex - 1
while (j > i && rightOptions.datas[j - 1].checked === false) {
rightOptions.datas.splice(j, 0, rightOptions.datas.splice(j - 1, 1)[0])
j--
rightOptions.datas = rightOptions.datas.map((item, index) => ({
...item,
num: index,
}))
}
}
}
// console.log('leftOptions3', rightOptions.datas)
}
页面效果