index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <template>
  2. <el-select
  3. ref="test"
  4. :size="size"
  5. :disabled="isBindPlan"
  6. :value="valueTitle"
  7. :clearable="clearable"
  8. @clear="clearHandle"
  9. :placeholder="placeholder"
  10. >
  11. <el-option :value="valueTitle" :label="valueTitle" class="options">
  12. <slot :pHandleNodeClick="handleNodeClick">
  13. <el-tree
  14. id="tree-option"
  15. ref="selectTree"
  16. :key="treeKey"
  17. :accordion="accordion"
  18. :data="options"
  19. :props="props"
  20. :node-key="props.value"
  21. :default-expand-all="true"
  22. :default-expanded-keys="defaultExpandedKey"
  23. @node-click="handleNodeClick"
  24. >
  25. </el-tree>
  26. </slot>
  27. </el-option>
  28. </el-select>
  29. </template>
  30. <script>
  31. export default {
  32. props: {
  33. // 配置项
  34. props: {
  35. type: Object,
  36. default () {
  37. return {
  38. value: 'value', // ID字段名
  39. label: 'label', // 显示名称
  40. children: 'children' // 子级字段名
  41. }
  42. }
  43. },
  44. // 选项列表数据(树形结构的对象数组)
  45. options: { type: Array, default: () => [] },
  46. // 初始值
  47. value: { type: [String, Number], default: null },
  48. // 可清空选项
  49. clearable: { type: Boolean, default: false },
  50. // 自动收起
  51. accordion: { type: Boolean, default: false },
  52. // // 可清空选项
  53. // disabled: { type: Boolean, default: false },
  54. // 多选
  55. multiple: { type: Boolean, default: false },
  56. //
  57. placeholder: {
  58. type: String,
  59. default: '请选择'
  60. },
  61. size: {
  62. type: String,
  63. default: 'mini'
  64. },
  65. dialogType: {
  66. type: String,
  67. default: ''
  68. },
  69. tableIndex: { type: Number, default: null },
  70. initStr: {
  71. type: String,
  72. default: ''
  73. },
  74. isBindPlan: {
  75. type: Boolean,
  76. default: function () {
  77. return false
  78. }
  79. },
  80. },
  81. data () {
  82. return {
  83. valueId: null,
  84. treeKey: true,
  85. valueTitle: '',
  86. defaultExpandedKey: []
  87. }
  88. },
  89. watch: {
  90. // 这个需要用深度监听,不然回显有时会失效
  91. value: {
  92. handler (val) {
  93. this.valueId = this.value
  94. this.initHandle()
  95. },
  96. deep: true,
  97. immediate: true
  98. },
  99. options:{
  100. handler (val) {
  101. this.initHandle()
  102. },
  103. deep: true,
  104. immediate: true
  105. },
  106. initStr: {
  107. handler (newVal, oldVal) {
  108. if (this.initStr) {
  109. // console.log(newVal);
  110. this.valueTitle = newVal
  111. }
  112. },
  113. immediate: true
  114. }
  115. },
  116. // mounted() {
  117. // this.valueId = this.value; // 初始值
  118. // setTimeout(() => {
  119. // this.initHandle();
  120. // },300)
  121. // },
  122. methods: {
  123. // 初始化值
  124. async initHandle () {
  125. if (this.valueId) {
  126. this.$nextTick(async () => {
  127. const tempValue = await this.$refs.selectTree.getNode(this.valueId)
  128. setTimeout(() => {
  129. if (tempValue) {
  130. this.valueTitle = tempValue.data[this.props.label] // 初始化显示
  131. this.$refs.selectTree.setCurrentKey(this.valueId) // 设置默认选中
  132. this.defaultExpandedKey = [this.valueId] // 设置默认展开
  133. }
  134. }, 300)
  135. })
  136. } else {
  137. this.valueTitle = ''
  138. }
  139. this.initScroll()
  140. },
  141. // 初始化滚动条
  142. initScroll () {
  143. this.$nextTick(() => {
  144. let scrollWrap = document.querySelectorAll(
  145. '.el-scrollbar .el-select-dropdown__wrap'
  146. )[0]
  147. let scrollBar = document.querySelectorAll(
  148. '.el-scrollbar .el-scrollbar__bar'
  149. )
  150. scrollWrap.style.cssText =
  151. 'margin: 0px; max-height: none; overflow: hidden;'
  152. scrollBar.forEach(ele => (ele.style.width = 0))
  153. })
  154. },
  155. // 切换选项
  156. handleNodeClick (node) {
  157. // 多选
  158. if (this.multiple) {
  159. this.valueTitle += `${node[this.props.label]} , `
  160. this.valueId = node[this.props.value]
  161. this.$emit('getValue', node)
  162. this.defaultExpandedKey = []
  163. return
  164. }
  165. this.valueTitle = node[this.props.label]
  166. this.valueId = node[this.props.value]
  167. this.$emit('getValue', node)
  168. this.defaultExpandedKey = []
  169. this.$refs.test.handleClose()
  170. },
  171. // 清除选中
  172. clearHandle () {
  173. this.valueTitle = ''
  174. this.valueId = null
  175. this.defaultExpandedKey = []
  176. // this.clearSelected()
  177. this.treeKey = !this.treeKey
  178. this.$emit('getValue', null)
  179. },
  180. // 清空选中样式
  181. clearSelected () {
  182. let allNode = document.querySelectorAll('#tree-option .el-tree-node')
  183. allNode.forEach(element => element.classList.remove('is-current'))
  184. }
  185. }
  186. }
  187. </script>
  188. <style scoped>
  189. .el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
  190. height: auto;
  191. max-height: 274px;
  192. padding: 0;
  193. overflow: hidden;
  194. overflow-y: auto;
  195. }
  196. .el-select-dropdown__item.selected {
  197. font-weight: normal;
  198. }
  199. ul li >>> .el-tree .el-tree-node__content {
  200. height: auto;
  201. padding: 0 20px;
  202. }
  203. .el-tree-node__label {
  204. font-weight: normal;
  205. }
  206. .el-tree >>> .is-current .el-tree-node__label {
  207. color: #157a2c;
  208. font-weight: 700;
  209. }
  210. .el-tree >>> .is-current .el-tree-node__children .el-tree-node__label {
  211. color: #606266;
  212. font-weight: normal;
  213. }
  214. </style>