treeSelect.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <template>
  2. <el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle">
  3. <el-input
  4. class="selectInput"
  5. :placeholder="placeholder"
  6. v-model="filterText">
  7. </el-input>
  8. <el-option :value="valueTitle" :label="valueTitle" class="options">
  9. <el-tree id="tree-option"
  10. ref="selectTree"
  11. :accordion="accordion"
  12. :data="options"
  13. :props="props"
  14. :node-key="props.value"
  15. :default-expanded-keys="defaultExpandedKey"
  16. :filter-node-method="filterNode"
  17. @node-click="handleNodeClick">
  18. </el-tree>
  19. </el-option>
  20. </el-select>
  21. </template>
  22. <script>
  23. export default {
  24. name: "el-tree-select",
  25. props:{
  26. /* 配置项 */
  27. props:{
  28. type: Object,
  29. default:()=>{
  30. return {
  31. value:'id', // ID字段名
  32. label: 'title', // 显示名称
  33. children: 'children' // 子级字段名
  34. }
  35. }
  36. },
  37. /* 选项列表数据(树形结构的对象数组) */
  38. options:{
  39. type: Array,
  40. default: ()=>{ return [] }
  41. },
  42. /* 初始值 */
  43. value:{
  44. type: Number,
  45. default: ()=>{ return null }
  46. },
  47. /* 可清空选项 */
  48. clearable:{
  49. type:Boolean,
  50. default:()=>{ return true }
  51. },
  52. /* 自动收起 */
  53. accordion:{
  54. type:Boolean,
  55. default:()=>{ return false }
  56. },
  57. placeholder:{
  58. type:String,
  59. default:()=>{return "检索关键字"}
  60. }
  61. },
  62. data() {
  63. return {
  64. filterText: '',
  65. valueId:this.value, // 初始值
  66. valueTitle:'',
  67. defaultExpandedKey:[]
  68. }
  69. },
  70. mounted(){
  71. this.initHandle()
  72. },
  73. methods: {
  74. // 初始化值
  75. initHandle(){
  76. if(this.valueId){
  77. this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.props.label] // 初始化显示
  78. this.$refs.selectTree.setCurrentKey(this.valueId) // 设置默认选中
  79. this.defaultExpandedKey = [this.valueId] // 设置默认展开
  80. }
  81. this.initScroll()
  82. },
  83. // 初始化滚动条
  84. initScroll(){
  85. this.$nextTick(()=>{
  86. let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]
  87. let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')
  88. scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
  89. scrollBar.forEach(ele => ele.style.width = 0)
  90. })
  91. },
  92. // 切换选项
  93. handleNodeClick(node){
  94. this.valueTitle = node[this.props.label]
  95. this.valueId = node[this.props.value]
  96. this.$emit('getValue',this.valueId)
  97. this.defaultExpandedKey = []
  98. },
  99. // 清除选中
  100. clearHandle(){
  101. this.valueTitle = ''
  102. this.valueId = null
  103. this.defaultExpandedKey = []
  104. this.clearSelected()
  105. this.$emit('getValue',null)
  106. },
  107. /* 清空选中样式 */
  108. clearSelected(){
  109. let allNode = document.querySelectorAll('#tree-option .el-tree-node')
  110. allNode.forEach((element)=>element.classList.remove('is-current'))
  111. },
  112. filterNode(value, data) {
  113. if (!value) return true;
  114. return data.name.indexOf(value) !== -1;
  115. }
  116. },
  117. watch: {
  118. value(){
  119. this.valueId = this.value
  120. this.initHandle()
  121. },
  122. filterText(val) {
  123. this.$refs.selectTree.filter(val);
  124. }
  125. },
  126. };
  127. </script>
  128. <!-- Add "scoped" attribute to limit CSS to this component only -->
  129. <style scoped>
  130. .el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
  131. height: auto;
  132. max-height: 274px;
  133. padding: 0;
  134. overflow: hidden;
  135. overflow-y: auto;
  136. }
  137. .el-select-dropdown__item.selected{
  138. font-weight: normal;
  139. }
  140. ul li >>>.el-tree .el-tree-node__content{
  141. height:auto;
  142. padding: 0 20px;
  143. }
  144. .el-tree-node__label{
  145. font-weight: normal;
  146. }
  147. .el-tree >>>.is-current .el-tree-node__label{
  148. color: #409EFF;
  149. font-weight: 700;
  150. }
  151. .el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{
  152. color:#606266;
  153. font-weight: normal;
  154. }
  155. .selectInput{
  156. padding: 0 5px;
  157. box-sizing: border-box;
  158. }
  159. /* 开发禁用 */
  160. /* .el-tree-node:focus>.el-tree-node__content{
  161. background-color:transparent;
  162. background-color: #f5f7fa;
  163. color: #c0c4cc;
  164. cursor: not-allowed;
  165. }
  166. .el-tree-node__content:hover{
  167. background-color: #f5f7fa;
  168. } */
  169. </style>