index.vue 5.9 KB

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