Vue element實(shí)現(xiàn)樹(shù)形穿梭框

需求

由于element中的穿梭框不能實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)數(shù)據(jù)的使用,所以利用Tree進(jìn)行重新封裝.

效果如圖:

代碼實(shí)現(xiàn)

1.結(jié)構(gòu)

<template>
  <div class="transferTreeBox">
    <!-- 左側(cè)待選內(nèi)容 -->
    <div class="SelectBox">
      <div
        class="boxTitle"
        @click="clickAllSelect"
      >
        全選 &gt;
      </div>
      <div class="boxCenter">
        <el-tree
          ref="beforeTree"
          :data="cascaderData"
          :props="defaultProps"
          show-checkbox
          :filter-node-method="beforeFilterNode"
          :accordion="true"
          node-key="nodeCode"
        />
      </div>
    </div>

    <!-- 中間穿梭按鈕 -->
    <div class="transferBtn">
      <div
        class="pickBtn"
        @click="towardsRight"
      >
        &gt;&gt;
      </div>
      <div
        class="pickBtn"
        @click="towardsLeft"
      >
        &lt;&lt;
      </div>
    </div>

    <!-- 右側(cè)已選內(nèi)容 -->
    <div class="SelectBox">
      <div
        class="boxTitle"
        @click="clickCancelAllSelect"
      >
        &lt; 取消全選
      </div>

      <div class="boxCenter">
        <el-tree
          ref="afterTree"
          :data="cascaderData"
          :props="defaultProps"
          show-checkbox
          :filter-node-method="afterFilterNode"
          node-key="nodeCode"
        />
      </div>
    </div>
  </div>
</template>

2.邏輯

<script>
export default {
    props: ["cascaderData"], // 班級(jí)的樹(shù)形結(jié)構(gòu)數(shù)據(jù)
    data () {
        return {
            defaultProps: {
                children: "children",
                label: "label"
            },
            beforeKeyarr: [],
            afterKeyarr: []
        };
    },
    mounted () {
        // 打開(kāi)彈窗清空右側(cè)樹(shù)形框
        this.$refs.afterTree.filter();
    },
    methods: {
        // 將組件的默認(rèn)選中清除
        keyClear(str){
            // 首先獲取node
            let node = this.$refs[str].getNode(this.cascaderData[0].nodeCode).parent;

            this.clearClickRecursion(node.childNodes);
        },
        // 清除樹(shù)形默認(rèn)選中的層級(jí)遞歸
        clearClickRecursion(data){
            data.forEach(val => {
                val.checked = false;
                if (val.childNodes && val.childNodes.length>0){
                    this.clearClickRecursion(val.childNodes);
                }
            });
        },
        // 點(diǎn)擊向右穿梭
        towardsRight(){
            let currentBeforeKeyarr = this.$refs.beforeTree.getCheckedNodes(true);
            
            // ES6語(yǔ)法.清除數(shù)組內(nèi)相同的對(duì)象
            let arr = this.beforeKeyarr.filter(item => !currentBeforeKeyarr.some(ele => ele.value === item.value));

            this.beforeKeyarr = arr;

            this.beforeKeyarr = [...this.beforeKeyarr,...currentBeforeKeyarr];

            this.shuttle();
        },
        // 點(diǎn)擊向左穿梭
        towardsLeft(){
            this.afterKeyarr = this.$refs.afterTree.getCheckedNodes(true);

            let arr = this.beforeKeyarr.filter(item => !this.afterKeyarr.some(ele => ele.value === item.value));

            this.beforeKeyarr = arr;

            this.shuttle();
        },
        // 穿梭
        async shuttle(){
            let str = "";

            this.beforeKeyarr.forEach(item => {
                if (str) {
                    str = `${str},${item.value}`;
                } else {
                    str = item.value;
                }
            });

            this.keyClear("beforeTree");
            this.keyClear("afterTree");

            await this.$refs.beforeTree.setCheckedKeys([]);
            await this.$refs.afterTree.setCheckedKeys([]);

            this.$refs.beforeTree.filter(str);
            this.$refs.afterTree.filter(str);

            this.$emit("getcascaderlist",this.beforeKeyarr);
        },
        // 過(guò)濾
        beforeFilterNode(value, data) {
            if (!value) {
                return true;
            }

            return value.indexOf(data.value) < 0;
        },
        afterFilterNode(value, data){
            if (!value) {
                return false;
            }

            return value.indexOf(data.value) !== -1;
        },
        // 點(diǎn)擊全選
        clickAllSelect(){
            this.$refs.beforeTree.setCheckedNodes(this.cascaderData);

            this.towardsRight();
        },
        // 點(diǎn)擊取消全選
        clickCancelAllSelect(){
            this.$refs.afterTree.setCheckedNodes(this.cascaderData);

            this.towardsLeft();
        }
    }
};
</script>

3.樣式

<style lang="scss" scoped>
.transferTreeBox{
    display: flex;
    width: 590px;
    justify-content: space-around;

    .SelectBox{
        border: 1px solid #ccc;
        height: 270px;
        width: 200px;
        color: #fff;
        position: relative;

        .boxTitle{
            background: #a0cfff;
            height: 30px;
            line-height: 30px;
            text-align: center;
            border-bottom: 1px solid #ccc;
            cursor: pointer;
        }

        .boxCenter{
            height: 100%;
            width: 100%;
            max-height: 239px;
            overflow-y: scroll;
        }
    }

    .transferBtn{
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;

        .pickBtn{
            height: 30px;
            width: 50px;
            background: #a0cfff;
            color: #fff;
            font-weight: 700;
            font-size: 20px;
            border-radius: 5px;
            margin-top: 10px;
            text-align: center;
            line-height: 30px;
            cursor: pointer;
        }
    }
}
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市都哭,隨后出現(xiàn)的幾起案子冕杠,更是在濱河造成了極大的恐慌攘蔽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件补胚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鸳吸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)速勇,“玉大人晌砾,你說(shuō)我怎么就攤上這事》炒牛” “怎么了养匈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)都伪。 經(jīng)常有香客問(wèn)我呕乎,道長(zhǎng),這世上最難降的妖魔是什么陨晶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任猬仁,我火速辦了婚禮,結(jié)果婚禮上珍逸,老公的妹妹穿的比我還像新娘逐虚。我一直安慰自己,他們只是感情好谆膳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布叭爱。 她就那樣靜靜地躺著,像睡著了一般漱病。 火紅的嫁衣襯著肌膚如雪买雾。 梳的紋絲不亂的頭發(fā)上把曼,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音漓穿,去河邊找鬼嗤军。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晃危,可吹牛的內(nèi)容都是我干的叙赚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼僚饭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼震叮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鳍鸵,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苇瓣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后偿乖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體击罪,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年贪薪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了媳禁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡古掏,死狀恐怖损话,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情槽唾,我是刑警寧澤丧枪,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站庞萍,受9級(jí)特大地震影響拧烦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钝计,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一恋博、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧私恬,春花似錦债沮、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至荣德,卻和暖如春闷煤,著一層夾襖步出監(jiān)牢的瞬間童芹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工鲤拿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留假褪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓近顷,卻偏偏與公主長(zhǎng)得像生音,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子幕庐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348