Vue3 + Element Plus Transfer 穿梭框自定義分組的示例詳解
1. 使用render-content自定義渲染
<template>
<el-transfer
v-model="selectedData"
:data="groupedData"
:render-content="renderFunc"
:titles="['可選數(shù)據(jù)', '已選數(shù)據(jù)']"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedData = ref([]);
// 分組數(shù)據(jù)格式
const groupedData = ref([
{
key: 'group1',
label: '第一組',
disabled: false,
children: [
{ key: '1', label: '選項(xiàng)1' },
{ key: '2', label: '選項(xiàng)2' }
]
},
{
key: 'group2',
label: '第二組',
disabled: false,
children: [
{ key: '3', label: '選項(xiàng)3' },
{ key: '4', label: '選項(xiàng)4' }
]
}
]);
// 扁平化數(shù)據(jù)供Transfer使用
const flatData = computed(() => {
return groupedData.value.flatMap(group =>
group.children.map(item => ({
key: item.key,
label: item.label,
disabled: item.disabled
}))
);
});
// 自定義渲染函數(shù)
const renderFunc = (h, option) => {
// 這里可以自定義渲染邏輯
return h('div', option.label);
};
</script>2. 完全自定義左右面板
如果需要更復(fù)雜的分組效果,可以完全自定義左右面板:
<template>
<div class="custom-transfer">
<div class="transfer-panel">
<div class="panel-header">可選數(shù)據(jù)</div>
<div class="panel-body">
<div v-for="group in leftGroups" :key="group.key" class="group">
<div class="group-title">{{ group.label }}</div>
<div class="group-items">
<el-checkbox
v-for="item in group.children"
:key="item.key"
v-model="item.checked"
:label="item.label"
@change="handleLeftChange(item)"
/>
</div>
</div>
</div>
</div>
<div class="transfer-buttons">
<el-button @click="moveToRight">→</el-button>
<el-button @click="moveToLeft">←</el-button>
</div>
<div class="transfer-panel">
<div class="panel-header">已選數(shù)據(jù)</div>
<div class="panel-body">
<div v-for="group in rightGroups" :key="group.key" class="group">
<div class="group-title">{{ group.label }}</div>
<div class="group-items">
<el-checkbox
v-for="item in group.children"
:key="item.key"
v-model="item.checked"
:label="item.label"
@change="handleRightChange(item)"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
// 原始分組數(shù)據(jù)
const rawData = ref([
{
key: 'group1',
label: '第一組',
children: [
{ key: '1', label: '選項(xiàng)1', checked: false },
{ key: '2', label: '選項(xiàng)2', checked: false }
]
},
{
key: 'group2',
label: '第二組',
children: [
{ key: '3', label: '選項(xiàng)3', checked: false },
{ key: '4', label: '選項(xiàng)4', checked: false }
]
}
]);
// 計(jì)算左側(cè)分組數(shù)據(jù)
const leftGroups = computed(() => {
return rawData.value.map(group => ({
...group,
children: group.children.filter(item => !selectedData.value.includes(item.key))
}));
});
// 計(jì)算右側(cè)分組數(shù)據(jù)
const rightGroups = computed(() => {
const selectedKeys = selectedData.value;
return rawData.value
.map(group => ({
...group,
children: group.children.filter(item => selectedKeys.includes(item.key))
}))
.filter(group => group.children.length > 0);
});
// 移動(dòng)選中項(xiàng)到右側(cè)
const moveToRight = () => {
rawData.value.forEach(group => {
group.children.forEach(item => {
if (item.checked && !selectedData.value.includes(item.key)) {
selectedData.value.push(item.key);
item.checked = false;
}
});
});
};
// 移動(dòng)選中項(xiàng)到左側(cè)
const moveToLeft = () => {
rawData.value.forEach(group => {
group.children.forEach(item => {
if (item.checked && selectedData.value.includes(item.key)) {
const index = selectedData.value.indexOf(item.key);
selectedData.value.splice(index, 1);
item.checked = false;
}
});
});
};
</script>
<style scoped>
.custom-transfer {
display: flex;
align-items: center;
}
.transfer-panel {
width: 250px;
border: 1px solid #ebeef5;
border-radius: 4px;
}
.panel-header {
padding: 10px;
background: #f5f7fa;
border-bottom: 1px solid #ebeef5;
}
.panel-body {
padding: 10px;
height: 300px;
overflow: auto;
}
.group {
margin-bottom: 15px;
}
.group-title {
font-weight: bold;
margin-bottom: 5px;
}
.transfer-buttons {
margin: 0 10px;
}
</style>3. 使用插槽自定義內(nèi)容
Element Plus 的 Transfer 組件提供了插槽來自定義內(nèi)容:
<el-transfer v-model="value" :data="data">
<template #left-footer>
<el-button size="small">操作</el-button>
</template>
<template #right-footer>
<el-button size="small">操作</el-button>
</template>
</el-transfer>4. 結(jié)合 Tree 組件實(shí)現(xiàn)樹形分組
如果需要樹形分組,可以結(jié)合 Tree 組件來實(shí)現(xiàn):
<template>
<div class="tree-transfer">
<div class="left-panel">
<el-tree
:data="treeData"
show-checkbox
node-key="id"
ref="leftTree"
@check-change="handleCheckChange"
/>
</div>
<div class="transfer-buttons">
<el-button @click="moveToRight">→</el-button>
<el-button @click="moveToLeft">←</el-button>
</div>
<div class="right-panel">
<el-tree
:data="selectedTreeData"
show-checkbox
node-key="id"
ref="rightTree"
/>
</div>
</div>
</template>到此這篇關(guān)于Vue3 + Element Plus Transfer 穿梭框自定義分組的文章就介紹到這了,更多相關(guān)Vue3 Element Plus Transfer 穿梭框內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+el-table點(diǎn)擊表頭實(shí)現(xiàn)改變其當(dāng)前樣式
這篇文章主要介紹了vue+el-table點(diǎn)擊表頭實(shí)現(xiàn)改變其當(dāng)前樣式問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue引入Stylus知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給各位整理的是一篇關(guān)于Vue引入Stylus知識(shí)點(diǎn)總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。2020-01-01
Vue3使用sessionStorage保存會(huì)話數(shù)據(jù)的實(shí)現(xiàn)方式
在前端開發(fā)中,我們常常需要在用戶會(huì)話期間保存一些數(shù)據(jù),這些數(shù)據(jù)在頁面刷新或?qū)Ш綍r(shí)依然需要存在,sessionStorage 是一種非常方便的方式來實(shí)現(xiàn)這一點(diǎn),在這篇文章中,我們將探討如何在Vue3應(yīng)用中使用sessionStorage來保存會(huì)話數(shù)據(jù),需要的朋友可以參考下2025-01-01
vue實(shí)現(xiàn)滑動(dòng)和滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)滑動(dòng)和滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue element 多圖片組合預(yù)覽的實(shí)現(xiàn)
本文主要介紹了vue element多圖片預(yù)覽實(shí)現(xiàn)的相關(guān)資料,最近的項(xiàng)目中有圖片預(yù)覽的場(chǎng)景,本文就來介紹一下如何使用,感興趣的可以了解一下2023-08-08
Vue實(shí)現(xiàn)dom元素拖拽并限制移動(dòng)范圍的操作代碼
這篇文章主要介紹了Vue實(shí)現(xiàn)dom元素拖拽并限制移動(dòng)范圍的操作代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-12-12

