TreeSelect組件:v-model語法糖進行父子組件傳值案例


效果:

一、組件代碼

<template>
  <!--el-select中v-model/value的值為當前被選中的el-option的value屬性值,
  為el-select設置disabled屬性,則整個選擇器不可用,
  為el-select設置clearable屬性,則可將選擇器清空。clear事件:可清空的單選模式下用戶點擊清空按鈕時觸發 -->
  <el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle" ref="treeSelect" :size="size" 
      :disabled="isDisabled" class="mySelect"> <el-input class="selectInput" :placeholder="placeholder" v-model="filterText"></el-input> <!--label為選項的標簽,為要展示的值。若不設置則默認與 value 相同,value為要提交的值--> <el-option :value="valueTitle" :label="valueTitle" class="options"> <!--data為要展示的數據,props中label指定標簽,props中children指定子樹,node-key是每個樹節點用來作為唯一標識的屬性, default-expanded-keys為默認展開的節點的 key 的數組。 filter-node-method對樹節點進行篩選時執行的方法,返回 true 表示這個節點可以顯示,返回 false 則表示這個節點會被隱藏 node-click為節點被點擊時的回調,共三個參數,依次為:傳遞給 data 屬性的數組中該節點所對應的對象、節點對應的 Node、節點組件本身。--> <el-tree id="tree-option" ref="selectTree" :accordion="accordion" :data="options" :props="props" :node-key="props.value" :default-expanded-keys="defaultExpandedKey" :filter-node-method="filterNode" @node-click="handleNodeClick"> </el-tree> </el-option> </el-select> </template> <script> export default { name: "el-tree-select", props: { /* 配置項 */ props: { type: Object, default: () => { return { value: 'id', // ID字段名 label: 'title', // 顯示名稱 children: 'children', // 子級字段名 } } }, /* 選項列表數據(樹形結構的對象數組) */ options: { type: Array, default: () => { return [] } }, /* 接收父組件傳遞v-model中傳遞過來的值 */ value: { type: String, default: () => { return null } }, /* 可清空選項 */ clearable: { type: Boolean, default: () => { return true } }, /* 自動收起 */ accordion: { type: Boolean, default: () => { return false } }, placeholder: { type: String, default: () => { return "檢索關鍵字" } }, size: { type: String, default: () => { return "small" } }, isDisabled: { type: Boolean, default: () => { return false } } }, data() { return { filterText: '', valueId: this.value, // 初始值 valueTitle: '', defaultExpandedKey: [] } }, watch: { // 當切換時會改變父組件的值,從而觸發該監聽器綁定的方法 value() { // 每次切換將value的值賦值給valueId this.valueId = this.value this.initHandle() // 每次切換時都會觸發該方法 }, filterText(val) { // val為input輸入框要輸入的值 console.log(val) this.$refs.selectTree.filter(val); } }, mounted() { this.initHandle() }, methods: { // 每次切換時都會觸發該方法 initHandle() { // 添加菜單時,value為默認值null;修改菜單時,由於有節點的值,故value值不為null if (this.valueId) { // 如果不為空, const node = this.$refs.selectTree.getNode(this.valueId) // 獲取節點 if(node){ // 通過node的data屬性獲取節點數據,再獲取節點的name的值,賦值給valueTitle this.valueTitle = node.data[this.props.label] // 修改組件要展示的值 } this.$refs.selectTree.setCurrentKey(this.valueId) // 設置當前節點為選中狀態 this.defaultExpandedKey = [this.valueId] // 設置valueId當前節點展開 } this.initScroll() }, // 初始化el-select的滾動條 initScroll() { this.$nextTick(() => { // 獲取class="el-scrollbar"下class=" el-select-dropdown__wrap"的所有元素 let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0] // 獲取class="el-scrollbar"下class="el-scrollbar__bar"的所有元素 let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar') // cssText 的本質就是設置 HTML 元素的 style 屬性值 scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;' scrollBar.forEach(ele => ele.style.width = 0) }) }, // 每次點擊一個新的菜單都會觸發這個方法,即切換時會觸發,修改父組件的值 // 每次切換,都會修改組件顯示的值,即el-select顯示的值,海修改parentId的值, handleNodeClick(node) { this.valueTitle = node[this.props.label] // 菜單名稱,如:菜單管理,修改顯示的值 this.valueId = node[this.props.value] // 菜單id,如1529450670506250249 this.$emit('getValue', this.valueId) // 將id賦值給父組件的form.parentId this.defaultExpandedKey = [] if (!node.children || !node.children.length) { // 當node為最后一級時,讓el-select組件失去焦點 this.$refs.treeSelect.blur() } }, // 清除選中 clearHandle() { this.valueTitle = '' this.valueId = 0 this.defaultExpandedKey = [] this.clearSelected() this.$emit('getValue', 0) }, /* 清空選中樣式 */ clearSelected() { // 獲取id="tree-option"下class="el-tree-node"的所有元素 let allNode = document.querySelectorAll('#tree-option .el-tree-node') // classList 屬性返回元素的類名,該屬性用於在元素中添加,移除及切換 CSS 類。classList 屬性是只讀的,但你可以使用 add() 和 remove() 方法修改它。 allNode.forEach((element) => element.classList.remove('is-current')) }, filterNode(value, data) { // value為輸入的值,data為每一個節點的值,即將每一個節點的name值拿出來判斷是否包含value // 如果返回true,則顯示節點,否則不顯示 console.log(value) if (!value) return true; return data.name.indexOf(value) !== -1; } }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .el-scrollbar .el-scrollbar__view .el-select-dropdown__item { height: auto; max-height: 274px; padding: 0; overflow: hidden; overflow-y: auto; } .el-select-dropdown__item.selected { font-weight: normal; } ul li>>>.el-tree .el-tree-node__content { height: auto; padding: 0 20px; } .el-tree-node__label { font-weight: normal; } .el-tree>>>.is-current .el-tree-node__label { color: #409EFF; font-weight: 700; } .el-tree>>>.is-current .el-tree-node__children .el-tree-node__label { color: #606266; font-weight: normal; } .selectInput { padding: 0 5px; box-sizing: border-box; } .mySelect { width: 100%; } </style>

獲取class="el-scrollbar"下class=" el-select-dropdown__wrap"的所有元素

 獲取class="el-scrollbar"下class="el-scrollbar__bar"的所有元素

二、組件的使用

1、引入

import SelectTree from "components/tree/TreeSelect"

2、注冊

components: {
            SelectTree
        },

3、使用組件

父組件代碼如下:

                <el-form-item label="上級菜單" prop="parentId" :rules="form.type!=0?rules.parentId:[]">
                    <select-tree :props="props" :options="list" v-model="form.parentId" :clearable="isClearable"
                        :accordion="isAccordion" @getValue="getValue($event)" :isDisabled="isDisabled" ref="TreeSelect">
                    </select-tree>
                </el-form-item>

由v-model語法糖可知:v-model="form.parentId"相當與:value="form.parentId" @input="form.parentId = $event.target.value",所以在子組件中偵聽value的值的變化,value值得變化就相當於parentId得值得變話。然后將當前被選中的el-option的value屬性值賦值給form.parentId,從而實現雙向綁定。

props中label指定節點標簽為節點對象的某個屬性值,children指定子樹為節點對象的某個屬性值。

其中父組件的props如下:

// 配置項
                props: {
                    value: "id",
                    label: "name",
                    children: "children",
                },

父組件傳遞到子組件的list值如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM