index_other.vue 6.1 KB

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