SelectPopup.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <u-popup class="jnpf-tree-select-popup" mode="right" v-model="showPopup" @close="close" :z-index="uZIndex"
  3. width="100%">
  4. <view class="jnpf-tree-select-body">
  5. <view class="jnpf-tree-select-title">
  6. <text class="icon-ym icon-ym-report-icon-preview-pagePre backIcon" @tap="close()"></text>
  7. <view class="title">角色选择</view>
  8. </view>
  9. <view class="jnpf-tree-select-search">
  10. <u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
  11. :show-action="false" @change="handleSearch" bg-color="#f0f2f6" shape="square">
  12. </u-search>
  13. </view>
  14. <view class="jnpf-tree-selected">
  15. <view class="jnpf-tree-selected-head">
  16. <view>{{$t('component.jnpf.common.selected')}}({{selectedList.length||0}})</view>
  17. <view v-if="multiple" class="clear-btn" @click="removeAll">
  18. {{$t('component.jnpf.common.clearAll')}}
  19. </view>
  20. </view>
  21. <view class="jnpf-tree-selected-box">
  22. <scroll-view scroll-y="true" class="select-list">
  23. <u-tag closeable @close="handleRemove(index)" v-for="(item,index) in selectedList" :key="index"
  24. :text="item.fullName" class="u-selectTag" />
  25. </scroll-view>
  26. </view>
  27. </view>
  28. <view class="jnpf-tree-selected-line"></view>
  29. <view class="jnpf-tree-selected-tabs">
  30. <view class="tab-item tab-item-active">用户角色</view>
  31. </view>
  32. <view class="jnpf-tree-select-tree">
  33. <scroll-view :scroll-y="true" style="height: 100%">
  34. <view class="jnpf-selcet-list" v-if="options.length">
  35. <view class="jnpf-selcet-cell" v-for="item in options" :key="item.id"
  36. @click.stop="handleNodeClick(item)">
  37. <view class="jnpf-selcet-cell-action">
  38. <lyCheckbox :type="multiple ? 'checkbox' : 'radio'"
  39. :checked="selectedIds.includes(item.id)" />
  40. </view>
  41. <view class="jnpf-selcet-cell-name">
  42. {{item.fullName}}
  43. </view>
  44. </view>
  45. </view>
  46. <Empty class="h-full" v-else />
  47. </scroll-view>
  48. </view>
  49. <!-- 底部按钮 -->
  50. <view class="jnpf-tree-select-actions">
  51. <u-button class="buttom-btn" @click="close()">{{$t('common.cancelText')}}</u-button>
  52. <u-button class="buttom-btn" type="primary"
  53. @click.stop="handleConfirm()">{{$t('common.okText')}}</u-button>
  54. </view>
  55. </view>
  56. </u-popup>
  57. </template>
  58. <script>
  59. import lyCheckbox from '@/components/ly-tree/components/ly-checkbox.vue';
  60. import Empty from '../Empty/index.vue'
  61. export default {
  62. components: {
  63. lyCheckbox,
  64. Empty
  65. },
  66. props: {
  67. getOptions: {
  68. type: Function,
  69. },
  70. selectedData: {
  71. type: Array,
  72. default: () => []
  73. },
  74. // 通过双向绑定控制组件的弹出与收起
  75. modelValue: {
  76. type: Boolean,
  77. default: false
  78. },
  79. // 弹出的z-index值
  80. zIndex: {
  81. type: [String, Number],
  82. default: 99999
  83. },
  84. multiple: {
  85. type: Boolean,
  86. default: false
  87. }
  88. },
  89. data() {
  90. return {
  91. moving: false,
  92. selectedList: [],
  93. selectedIds: [],
  94. keyword: '',
  95. showPopup: false,
  96. options: [],
  97. cacheData: [],
  98. };
  99. },
  100. watch: {
  101. modelValue: {
  102. handler(val) {
  103. this.showPopup = val
  104. if (val) setTimeout(() => this.init(), 10);
  105. },
  106. immediate: true
  107. },
  108. selectedList: {
  109. handler(val) {
  110. this.selectedIds = val.map((o) => o.id);
  111. },
  112. deep: true
  113. },
  114. },
  115. computed: {
  116. uZIndex() {
  117. // 如果用户有传递z-index值,优先使用
  118. return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
  119. },
  120. },
  121. methods: {
  122. init() {
  123. this.keyword = ''
  124. this.selectedList = JSON.parse(JSON.stringify(this.selectedData))
  125. if (this.getOptions) {
  126. this.getOptions().then(res => {
  127. this.options = res || []
  128. this.cacheData = res || []
  129. })
  130. } else {
  131. this.options = []
  132. this.cacheData = []
  133. }
  134. },
  135. handleNodeClick(data) {
  136. const index = this.selectedList.findIndex((o) => o.id === data.id);
  137. if (index !== -1) return this.selectedList.splice(index, 1);
  138. this.multiple ? this.selectedList.push(data) : (this.selectedList = [data]);
  139. },
  140. handleRemove(index) {
  141. this.selectedList.splice(index, 1);
  142. },
  143. removeAll() {
  144. this.selectedList = [];
  145. },
  146. handleConfirm() {
  147. this.$emit('confirm', this.selectedList, this.selectedIds);
  148. this.close();
  149. },
  150. close() {
  151. this.$emit('close');
  152. },
  153. handleSearch(val) {
  154. this.options = this.cacheData.filter((o) => o.fullName.includes(val));
  155. },
  156. }
  157. };
  158. </script>