user-component.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <!-- 用户组件(单选) -->
  2. <template>
  3. <div>
  4. <el-select v-model="value" ref="select" placeholder="请选择" clearable filterable remote :remote-method="remoteMethod"
  5. @change="onChange" @focus="cancelReadOnly" @hook:mounted="cancelReadOnly" @visible-change="cancelReadOnly">
  6. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
  7. </el-option>
  8. <el-option v-if="options.length > 0" label="加载更多" style="font-style: italic; color: #8a979e" value="undefined"
  9. @click.native="handleClick()"></el-option>
  10. </el-select>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. name: 'user-component',
  16. props: {
  17. userId: {
  18. type: String,
  19. default: ''
  20. }
  21. },
  22. model: {
  23. prop: 'userId',
  24. event: 'userSelected'
  25. },
  26. watch: {
  27. // userId (value) {
  28. // console.log('userId变化:' + value)
  29. // this.value = value
  30. // // 检查缺失item
  31. // this.checkItem(value)
  32. // }
  33. userId: {
  34. immediate: true,
  35. handler(newUserId) {
  36. this.value = newUserId
  37. this.checkItem(newUserId)
  38. }
  39. }
  40. },
  41. data() {
  42. return {
  43. value: '',
  44. current: 1,
  45. size: 100,
  46. name: '',
  47. options: [],
  48. loading: false,
  49. noMore: false
  50. }
  51. },
  52. mounted() {
  53. this.init()
  54. },
  55. methods: {
  56. async init() {
  57. this.getList()
  58. },
  59. remoteMethod(query) {
  60. this.options = []
  61. this.current = 1
  62. this.name = query
  63. this.getList()
  64. },
  65. getList() {
  66. this.$http({
  67. url: this.$http.adornUrl(`/user-service/user/list`),
  68. method: 'get',
  69. params: this.$http.adornParams({
  70. 'current': this.current,
  71. 'size': this.size,
  72. 'name': this.name
  73. })
  74. }).then(({ data }) => {
  75. if (data && data.code === '200') {
  76. if (this.current > data.data.pages) {
  77. return
  78. }
  79. this.noMore = data.data.records.length >= 10
  80. data.data.records.forEach(item => {
  81. let i = this.options.findIndex(a => a.value === item.userId)
  82. if (i < 0) {
  83. this.options.push({
  84. label: item.name + ' (' + item.orgName + ')',
  85. value: item.userId,
  86. name: item.name,
  87. phone: item.mobile
  88. })
  89. }
  90. })
  91. } else {
  92. this.options = []
  93. }
  94. })
  95. },
  96. handleClick() {
  97. this.loadMore()
  98. },
  99. loadMore() {
  100. this.current++
  101. this.value = null
  102. this.getList()
  103. },
  104. onChange(item) {
  105. if (item === 'undefined') {
  106. this.value = null
  107. }
  108. this.$emit('userSelected', item)
  109. this.$emit('userSelectedItem', { userId: item, userName: this.options.find(t => t.value === item).name })
  110. },
  111. checkItem(code) {
  112. if (!code || !this.options) return
  113. let i = this.options.findIndex(item => item.value === code)
  114. if (i > -1) return
  115. // info
  116. this.$http({
  117. url: this.$http.adornUrl(`/user-service/user/info/${code}`),
  118. method: 'get'
  119. }).then(({ data }) => {
  120. if (data && data.code === '200' && data.data) {
  121. // 再次检查,防止异步重复添加
  122. if (!this.options.some(opt => opt.value === data.data.userId)) {
  123. this.options.push({
  124. label: data.data.name + ' (' + data.data.orgName + ')',
  125. value: data.data.userId
  126. })
  127. }
  128. }
  129. })
  130. },
  131. cancelReadOnly(onOff) {
  132. this.$nextTick(() => {
  133. if (!onOff) {
  134. const input = this.$refs.select.$el.querySelector('.el-input__inner')
  135. const timer = setTimeout(() => {
  136. input.removeAttribute('readonly')
  137. clearTimeout(timer)
  138. }, 200)
  139. }
  140. })
  141. }
  142. }
  143. }
  144. </script>
  145. <style scoped></style>