index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <view class="jnpf-tree-select">
  3. <selectBox v-model="innerValue" :disabled='disabled' :placeholder="placeholder" @openSelect="openSelect"
  4. :select-open="selectShow">
  5. </selectBox>
  6. <Tree v-if="selectShow" v-model="selectShow" :default-value="defaultValue" :options="options"
  7. :multiple="multiple" :lastLevel="lastLevel" :lastLevelKey="lastLevelKey" :lastLevelValue="lastLevelValue"
  8. :props="props" :filterable="filterable" @close="handleClose" @confirm="handleConfirm" />
  9. </view>
  10. </template>
  11. <script>
  12. import Tree from './Tree';
  13. import selectBox from '@/components/selectBox'
  14. export default {
  15. name: 'jnpf-tree-select',
  16. components: {
  17. Tree,
  18. selectBox
  19. },
  20. props: {
  21. modelValue: {
  22. default: ''
  23. },
  24. options: {
  25. type: Array,
  26. default: () => []
  27. },
  28. placeholder: {
  29. type: String,
  30. default: '请选择'
  31. },
  32. props: {
  33. type: Object,
  34. default: () => ({
  35. label: 'fullName',
  36. value: 'id',
  37. children: 'children'
  38. })
  39. },
  40. disabled: {
  41. type: Boolean,
  42. default: false
  43. },
  44. filterable: {
  45. type: Boolean,
  46. default: false
  47. },
  48. multiple: {
  49. type: Boolean,
  50. default: false
  51. },
  52. // 只能选择最后一层的数值
  53. lastLevel: {
  54. type: Boolean,
  55. default: false
  56. },
  57. // 只能选择最后一层的数值时,需要根据lastLevelKey来判断是否最后一层
  58. lastLevelKey: {
  59. type: String,
  60. default: "hasChildren"
  61. },
  62. lastLevelValue: {
  63. default: false
  64. },
  65. },
  66. data() {
  67. return {
  68. selectShow: false,
  69. innerValue: '',
  70. defaultValue: []
  71. }
  72. },
  73. watch: {
  74. options() {
  75. this.setDefault()
  76. },
  77. modelValue: {
  78. handler(val) {
  79. this.setDefault()
  80. },
  81. immediate: true
  82. }
  83. },
  84. methods: {
  85. setDefault() {
  86. if (!this.modelValue || !this.options) {
  87. this.defaultValue = []
  88. this.innerValue = ''
  89. return
  90. }
  91. const value = this.multiple ? this.modelValue : [this.modelValue]
  92. let label = ''
  93. const loop = (value, list) => {
  94. for (let i = 0; i < list.length; i++) {
  95. let item = list[i]
  96. if (value === item[this.props.value]) {
  97. label += (!label ? '' : ',') + item[this.props.label]
  98. break
  99. }
  100. if (item.children && Array.isArray(item.children) && item.children.length) {
  101. loop(value, item.children)
  102. }
  103. }
  104. }
  105. for (let i = 0; i < value.length; i++) {
  106. loop(value[i], this.options)
  107. }
  108. this.innerValue = label
  109. this.defaultValue = value
  110. },
  111. openSelect() {
  112. if (this.disabled) return
  113. this.selectShow = true
  114. },
  115. handleClose() {
  116. this.selectShow = false
  117. },
  118. handleConfirm(e) {
  119. let label = ''
  120. let value = []
  121. for (let i = 0; i < e.length; i++) {
  122. label += (!label ? '' : ',') + e[i][this.props.label]
  123. value.push(e[i][this.props.value])
  124. }
  125. this.defaultValue = value
  126. this.innerValue = label
  127. if (!this.multiple) {
  128. this.$emit('update:modelValue', value[0])
  129. this.$emit('change', value[0], e[0])
  130. } else {
  131. this.$emit('update:modelValue', value)
  132. this.$emit('change', value, e)
  133. }
  134. }
  135. }
  136. }
  137. </script>
  138. <style lang="scss" scoped>
  139. .jnpf-tree-select {
  140. width: 100%;
  141. }
  142. </style>