1. 程式人生 > >基於element-ui的多選下拉框和tag標簽的二次封裝

基於element-ui的多選下拉框和tag標簽的二次封裝

line ron click opacity ext width 顯示 模塊 scss

前言:

今年這大半年我主要負責公司的後臺教務管理的開發,這個管理系統目前主要是給公司的內部人員去配置公司的核心項目(例如:熊貓小課)的所有數據,例如課程的配置、課程期數的配置、課程版本的配置、活動的配置、課程安排表、管理員的權限配置、物流的管理、退款管理、學員咨詢管理等功能。因為一開始這個教務系統的原型設計就是基於element-ui 1.4.13的版本設計的,前端一開始為了和設計稿給的原型保持一致,項目中也是基於element-ui 1.4.13在開發,現在這個版本官方已經停止維護了,我們曾經嘗試過去升級element-ui到最新版本,但是發現升級後的版本和舊版本的樣式有些模塊改動太大,微調的成本太高,最終放棄了升級。所以後續基於後臺管理element-ui部分的總結,我都是基於的element-ui 1.4.13的總結。

需要實現的效果:

選中時就顯示復選框,不選中時不顯示復選框

技術分享圖片

element-ui中提供的多選ui組件:

技術分享圖片

不符合我們的需求,所以我們需要想辦法自己封裝,但如何做呢?

element-ui中提供的其他組件:

我們可不可以將element-ui中提供的tag組件、復選框組件和普通的下拉框組件組合呢?因為這三個組合起來正是我們想要的效果。

技術分享圖片

select組件中我們可以自定義下拉框中的數據展示的樣式:

技術分享圖片

技術分享圖片

如何組合呢?

 1 <el-select class="dropdown-list" v-model="selectedValue"
placeholder="請選擇"> 2 <el-option 3 v-for="item in options" 4 :key="item.plan_id" 5 :class="{active: isActive(item)}" 6 :label="item.plan_name" 7 :value="item.plan_id"> 8 <el-checkbox 9 v-if="isActive(item)" 10 :label
="item.plan_name" 11 :disabled="isActive(item)" 12 :checked="isActive(item)" 13 @change="valueChange(item)"> 14 </el-checkbox> 15 <div v-else v-text="item.plan_name" @click="selectItem(item)"></div> 16 </el-option> 17 </el-select>

明白可以怎麽做就發現很簡單了,就是重寫el-option組件,將下拉框中默認的樣式用自定義的樣式覆蓋掉,el-option組件中下拉框的樣式是定義在一個slot的插槽中的,我們在slot中定義我們自己的ui布局。

這個組件我們只需要從外部拿兩個變量值:下拉框的選項、和被選擇的選項值。



<template>
<div class="dropdown-wrap">
<el-select class="dropdown-list" v-model="selectedValue" placeholder="選擇開學課程期數">
<el-option
v-for="item in options"
:key="item.plan_id"
:class="{active: isActive(item)}"
:label="item.plan_name"
:value="item.plan_id">
<el-checkbox
v-if="isActive(item)"
:label="item.plan_name"
:disabled="isActive(item)"
:checked="isActive(item)"
@change="valueChange(item)">
</el-checkbox>
<div v-else v-text="item.plan_name" @click="selectItem(item)"></div>
</el-option>
</el-select>
</div>
</template>

<script> export default { props: { options: Array, selected: Array },
mounted() { this.selectedItems = this.selected; },
watch: { selected: { handler(val) { this.selectedItems = val; }, deep: true },
methods: { //選中 selectItem(item) { // debugger let newArr = JSON.parse(JSON.stringify(this.selectedItems)); let newItem = JSON.parse(JSON.stringify(item)); newItem.type = "primary"; newItem.name = item.plan_name; newItem.plan_id = item.plan_id; newItem.version_id = item.version_id; newArr.push(newItem); this.selectedItems = newArr; this.$emit("valueChange",JSON.parse(JSON.stringify(newItem)), newArr); },
//取消選擇 valueChange(item) { this.$emit(‘del‘, item) },
isActive(data) { // debugger return this.selectedItems.some(item => item.plan_id === data.plan_id); }, } }; </script>
<style lang="scss" scoped> .active { display: block; }
.cpt-dropdown-list { display: inline-block;
.dropdown-link { color: #409eff; cursor: pointer; } }
.dropdown-list { .el-select-dropdown { display: none !important; } }
.el-dropdown-menu.cpt-dropdown-list-wrap { min-width: 188.09px; left: 345px !important; } </style> <style lang="scss"> // .dropdown-list { .el-select-dropdown__item.selected { background-color: rgba(color: #409eff, opacity: 0.1); color: #48576a; }
.el-select-dropdown__item.selected.hover { // background-color: rgba(color: #409eff, opacity: 0.1); color: #48576a; } // } </style>
 

總結:寫完之後就發現還是很簡單的,記得當時寫的時候都沒有思路,仔細想想,質疑一下element-ui的選擇框的下拉可以自定義樣式嗎,然後去仔細看官方文檔,發現確實可以做到,思路就打開了。先想應該怎麽做,先假設,再去驗證,這樣才能快速得到結果。

基於element-ui的多選下拉框和tag標簽的二次封裝