element 樹狀下拉框

<!--

? ? /**

? ? * 樹形下拉選擇組件傀顾,下拉框展示樹形結(jié)構(gòu),提供選擇某節(jié)點(diǎn)功能薄货,方便其他模塊調(diào)用

? ? * @author sxy https://bysjb.cn

? ? * @date 2020-12-02

? ? */

-->

<template>

? <div>

? ? <div v-show="isShowSelect" class="mask" @click="isShowSelect = !isShowSelect" />

? ? <el-popover

? ? ? v-model="isShowSelect"

? ? ? placement="bottom-start"

? ? ? :width="width"

? ? ? trigger="manual"

? ? ? style="padding: 12px 0;"

? ? ? @hide="popoverHide"

? ? >

? ? ? <el-tree

? ? ? ? ref="tree"

? ? ? ? class="common-tree"

? ? ? ? :style="style"

? ? ? ? :data="data"

? ? ? ? :props="defaultProps"

? ? ? ? :show-checkbox="multiple"

? ? ? ? :node-key="nodeKey"

? ? ? ? :check-strictly="checkStrictly"

? ? ? ? default-expand-all

? ? ? ? :expand-on-click-node="false"

? ? ? ? :check-on-click-node="multiple"

? ? ? ? :highlight-current="true"

? ? ? ? @node-click="handleNodeClick"

? ? ? ? @check-change="handleCheckChange"

? ? ? />

? ? ? <el-select

? ? ? ? slot="reference"

? ? ? ? ref="select"

? ? ? ? v-model="selectedData"

? ? ? ? :style="selectStyle"

? ? ? ? :size="size"

? ? ? ? :multiple="multiple"

? ? ? ? :clearable="clearable"

? ? ? ? :collapse-tags="collapseTags"

? ? ? ? class="tree-select"

? ? ? ? @click.native="isShowSelect = !isShowSelect"

? ? ? ? @remove-tag="removeSelectedNodes"

? ? ? ? @clear="removeSelectedNode"

? ? ? ? @change="changeSelectedNodes"

? ? ? >

? ? ? ? <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />

? ? ? </el-select>

? ? </el-popover>

? </div>

</template>

<script>

export default {

? props: {

? ? // 樹結(jié)構(gòu)數(shù)據(jù)

? ? data: {

? ? ? type: Array,

? ? ? default() {

? ? ? ? return []

? ? ? }

? ? },

? ? defaultProps: {

? ? ? type: Object,

? ? ? default() {

? ? ? ? return {

? ? ? ? ? children: 'children',

? ? ? ? ? label: 'name'

? ? ? ? }

? ? ? }

? ? },

? ? // 配置是否可多選

? ? multiple: {

? ? ? type: Boolean,

? ? ? default() {

? ? ? ? return false

? ? ? }

? ? },

? ? // 配置是否可清空選擇

? ? clearable: {

? ? ? type: Boolean,

? ? ? default() {

? ? ? ? return false

? ? ? }

? ? },

? ? // 配置多選時(shí)是否將選中值按文字的形式展示

? ? collapseTags: {

? ? ? type: Boolean,

? ? ? default() {

? ? ? ? return false

? ? ? }

? ? },

? ? nodeKey: {

? ? ? type: String,

? ? ? default() {

? ? ? ? return 'id'

? ? ? }

? ? },

? ? // 顯示復(fù)選框情況下翁都,是否嚴(yán)格遵循父子不互相關(guān)聯(lián)

? ? checkStrictly: {

? ? ? type: Boolean,

? ? ? default() {

? ? ? ? return false

? ? ? }

? ? },

? ? // 默認(rèn)選中的節(jié)點(diǎn)key數(shù)組

? ? checkedKeys: {

? ? ? type: Array,

? ? ? default() {

? ? ? ? return []

? ? ? }

? ? },

? ? size: {

? ? ? type: String,

? ? ? default() {

? ? ? ? return 'medium'

? ? ? }

? ? },

? ? width: {

? ? ? type: Number,

? ? ? default() {

? ? ? ? return 250

? ? ? }

? ? },

? ? height: {

? ? ? type: Number,

? ? ? default() {

? ? ? ? return 300

? ? ? }

? ? }

? },

? data() {

? ? return {

? ? ? isShowSelect: false, // 是否顯示樹狀選擇器

? ? ? options: [],

? ? ? selectedData: [], // 選中的節(jié)點(diǎn)

? ? ? style: 'width:' + (this.width - 24) + 'px;' + 'height:' + this.height + 'px;',

? ? ? selectStyle: 'width:' + (this.width + 24) + 'px;',

? ? ? checkedIds: [],

? ? ? checkedData: []

? ? }

? },

? watch: {

? ? isShowSelect(val) {

? ? ? // 隱藏select自帶的下拉框

? ? ? this.$refs.select.blur()

? ? },

? ? checkedKeys(val) {

? ? ? console.log('checkedKeys', val)

? ? ? if (!val) return

? ? ? this.checkedKeys = val

? ? ? this.initCheckedData()

? ? }

? },

? mounted() {

? ? this.initCheckedData()

? },

? methods: {

? ? // 單選時(shí)點(diǎn)擊tree節(jié)點(diǎn),設(shè)置select選項(xiàng)

? ? setSelectOption(node) {

? ? ? const tmpMap = {}

? ? ? tmpMap.value = node.key

? ? ? tmpMap.label = node.label

? ? ? this.options = []

? ? ? this.options.push(tmpMap)

? ? ? this.selectedData = node.key

? ? },

? ? // 單選菲驴,選中傳進(jìn)來的節(jié)點(diǎn)

? ? checkSelectedNode(checkedKeys) {

? ? ? var item = checkedKeys[0]

? ? ? this.$refs.tree.setCurrentKey(item)

? ? ? var node = this.$refs.tree.getNode(item)

? ? ? this.setSelectOption(node)

? ? },

? ? // 多選荐吵,勾選上傳進(jìn)來的節(jié)點(diǎn)

? ? checkSelectedNodes(checkedKeys) {

? ? ? // this.$refs.tree.setCheckedKeys(checkedKeys)

? ? ? // 優(yōu)化select回顯顯示 有個(gè)延遲的效果

? ? ? const that = this

? ? ? setTimeout(function() {

? ? ? ? that.$refs.tree.setCheckedKeys(checkedKeys)

? ? ? }, 10)

? ? ? // console.log('checkSelectedNodes', checkedKeys, this.selectedData)

? ? },

? ? // 單選,清空選中

? ? clearSelectedNode() {

? ? ? this.selectedData = []

? ? ? this.$refs.tree.setCurrentKey(null)

? ? },

? ? // 多選赊瞬,清空所有勾選

? ? clearSelectedNodes() {

? ? ? var checkedKeys = this.$refs.tree.getCheckedKeys() // 所有被選中的節(jié)點(diǎn)的 key 所組成的數(shù)組數(shù)據(jù)

? ? ? for (let i = 0; i < checkedKeys.length; i++) {

? ? ? ? this.$refs.tree.setChecked(checkedKeys[i], false)

? ? ? }

? ? },

? ? initCheckedData() {

? ? ? if (this.multiple) {

? ? ? ? // 多選

? ? ? ? // console.log(this.checkedKeys.length)

? ? ? ? if (this.checkedKeys.length > 0) {

? ? ? ? ? this.checkSelectedNodes(this.checkedKeys)

? ? ? ? } else {

? ? ? ? ? this.clearSelectedNodes()

? ? ? ? }

? ? ? } else {

? ? ? ? // 單選

? ? ? ? if (this.checkedKeys.length > 0) {

? ? ? ? ? this.checkSelectedNode(this.checkedKeys)

? ? ? ? } else {

? ? ? ? ? this.clearSelectedNode()

? ? ? ? }

? ? ? }

? ? },

? ? popoverHide() {

? ? ? if (this.multiple) {

? ? ? ? this.checkedIds = this.$refs.tree.getCheckedKeys() // 所有被選中的節(jié)點(diǎn)的 key 所組成的數(shù)組數(shù)據(jù)

? ? ? ? this.checkedData = this.$refs.tree.getCheckedNodes() // 所有被選中的節(jié)點(diǎn)所組成的數(shù)組數(shù)據(jù)

? ? ? } else {

? ? ? ? this.checkedIds = this.$refs.tree.getCurrentKey()

? ? ? ? this.checkedData = this.$refs.tree.getCurrentNode()

? ? ? }

? ? ? this.$emit('popoverHide', this.checkedIds, this.checkedData)

? ? },

? ? // 單選先煎,節(jié)點(diǎn)被點(diǎn)擊時(shí)的回調(diào),返回被點(diǎn)擊的節(jié)點(diǎn)數(shù)據(jù)

? ? handleNodeClick(data, node) {

? ? ? if (!this.multiple) {

? ? ? ? this.setSelectOption(node)

? ? ? ? this.isShowSelect = !this.isShowSelect

? ? ? ? this.$emit('change', this.selectedData)

? ? ? }

? ? },

? ? // 多選,節(jié)點(diǎn)勾選狀態(tài)發(fā)生變化時(shí)的回調(diào)

? ? handleCheckChange() {

? ? ? var checkedKeys = this.$refs.tree.getCheckedKeys() // 所有被選中的節(jié)點(diǎn)的 key 所組成的數(shù)組數(shù)據(jù)

? ? ? // console.log('handleCheckChange', checkedKeys)

? ? ? this.options = checkedKeys.map((item) => {

? ? ? ? var node = this.$refs.tree.getNode(item) // 所有被選中的節(jié)點(diǎn)對(duì)應(yīng)的node

? ? ? ? const tmpMap = {}

? ? ? ? tmpMap.value = node.key

? ? ? ? tmpMap.label = node.label

? ? ? ? return tmpMap

? ? ? })

? ? ? this.selectedData = this.options.map((item) => {

? ? ? ? return item.value

? ? ? })

? ? ? this.$emit('change', this.selectedData)

? ? },

? ? // 多選,刪除任一select選項(xiàng)的回調(diào)

? ? removeSelectedNodes(val) {

? ? ? this.$refs.tree.setChecked(val, false)

? ? ? var node = this.$refs.tree.getNode(val)

? ? ? if (!this.checkStrictly && node.childNodes.length > 0) {

? ? ? ? this.treeToList(node).map(item => {

? ? ? ? ? if (item.childNodes.length <= 0) {

? ? ? ? ? ? this.$refs.tree.setChecked(item, false)

? ? ? ? ? }

? ? ? ? })

? ? ? ? this.handleCheckChange()

? ? ? }

? ? ? this.$emit('change', this.selectedData)

? ? },

? ? treeToList(tree) {

? ? ? var queen = []

? ? ? var out = []

? ? ? queen = queen.concat(tree)

? ? ? while (queen.length) {

? ? ? ? var first = queen.shift()

? ? ? ? if (first.childNodes) {

? ? ? ? ? queen = queen.concat(first.childNodes)

? ? ? ? }

? ? ? ? out.push(first)

? ? ? }

? ? ? return out

? ? },

? ? // 單選,清空select輸入框的回調(diào)

? ? removeSelectedNode() {

? ? ? this.clearSelectedNode()

? ? ? this.$emit('change', this.selectedData)

? ? },

? ? // 選中的select選項(xiàng)改變的回調(diào)

? ? changeSelectedNodes(selectedData) {

? ? ? // 多選,清空select輸入框時(shí)巧涧,清除樹勾選

? ? ? if (this.multiple && selectedData.length <= 0) {

? ? ? ? this.clearSelectedNodes()

? ? ? }

? ? ? this.$emit('change', this.selectedData)

? ? }

? }

}

</script>

<style scoped>

? .mask {

? ? width: 100%;

? ? height: 100%;

? ? position: fixed;

? ? top: 0;

? ? left: 0;

? ? opacity: 0;

? ? z-index: 11;

? }

? .common-tree {

? ? overflow: auto;

? }

? .tree-select {

? ? z-index: 111;

? }

</style>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薯蝎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谤绳,更是在濱河造成了極大的恐慌占锯,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缩筛,死亡現(xiàn)場(chǎng)離奇詭異消略,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瞎抛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門艺演,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桐臊,你說我怎么就攤上這事胎撤。” “怎么了断凶?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵伤提,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我认烁,道長(zhǎng)肿男,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任却嗡,我火速辦了婚禮次伶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稽穆。我一直安慰自己,他們只是感情好赶撰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布舌镶。 她就那樣靜靜地躺著柱彻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪餐胀。 梳的紋絲不亂的頭發(fā)上哟楷,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音否灾,去河邊找鬼卖擅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛墨技,可吹牛的內(nèi)容都是我干的惩阶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扣汪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼断楷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起崭别,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤冬筒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后茅主,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舞痰,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年诀姚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了响牛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡学搜,死狀恐怖娃善,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瑞佩,我是刑警寧澤聚磺,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站炬丸,受9級(jí)特大地震影響瘫寝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稠炬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一焕阿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧首启,春花似錦暮屡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)准夷。三九已至,卻和暖如春莺掠,著一層夾襖步出監(jiān)牢的瞬間衫嵌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工彻秆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楔绞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓唇兑,卻偏偏與公主長(zhǎng)得像酒朵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子幔亥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容