fa-selectpages.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <view class="selectpage">
  3. <view class="" v-if="checkeType == 'selectpage'">
  4. <u-input type="select" :select-open="show" v-model="page_lable" :placeholder="'请选择' + title" @click="show = true"></u-input>
  5. </view>
  6. <view class="" v-if="checkeType == 'selectpages'">
  7. <view class="select-pages u-flex u-flex-wrap" @click="show = true">
  8. <view class="u-m-r-10" v-for="(tag, tak) in pagesLable" :key="tak">
  9. <u-tag :text="tag[showField]" :bg-color="lightColor" :border-color="faBorderColor" :color="theme.bgColor" type="success" />
  10. </view>
  11. <view class="u-light-color" v-text="'请选择' + title" v-if="!pagesLable.length"></view>
  12. </view>
  13. </view>
  14. <u-popup v-model="show" :popup="false" @close="close" mode="bottom" height="700">
  15. <view class="u-flex u-flex-column">
  16. <view class="fa-column u-p-l-30 u-p-r-30 u-p-t-20 u-p-b-20 u-border-bottom">
  17. <u-search placeholder="搜索" v-model="q_word" :show-action="false"></u-search>
  18. </view>
  19. <view class="fa-column u-flex-1 u-flex fa-scroll">
  20. <scroll-view scroll-y="true" :style="{ height: scrollHg + 'px', width: '100vw' }" @scrolltolower="goLower">
  21. <!-- 多选 -->
  22. <view v-if="checkeType == 'selectpages'">
  23. <checkbox-group>
  24. <u-cell-item :arrow="false" v-for="(item, index) in list" :key="index" :title="item[showField]" @click.self="selectCell(index)">
  25. <checkbox
  26. slot="right-icon"
  27. shape="square"
  28. :color="theme.bgColor"
  29. :value="item[keyField] + ''"
  30. :checked="item.checked"
  31. ></checkbox>
  32. </u-cell-item>
  33. </checkbox-group>
  34. </view>
  35. <!-- 单选 -->
  36. <view class="" v-else>
  37. <u-radio-group v-model="radio_value">
  38. <u-cell-item :arrow="false" v-for="(item, index) in list" :key="index" :title="item[showField]" @click.self="selectCell(index)">
  39. <u-radio slot="right-icon" :active-color="theme.bgColor" :name="item[keyField] + ''"></u-radio>
  40. </u-cell-item>
  41. </u-radio-group>
  42. </view>
  43. <view class="u-p-10"><u-loadmore :status="status" /></view>
  44. </scroll-view>
  45. </view>
  46. <view class="fa-column select-footer u-text-center">
  47. <u-gap height="10" bg-color="#eaeaec"></u-gap>
  48. <view class="u-p-10 u-flex u-row-around">
  49. <view class="u-flex-1" v-if="checkeType == 'selectpages'" @click="clearAll"><text>清空</text></view>
  50. <!-- <view class="u-flex-1" @click="allSelect"> -->
  51. <!-- <text>全选</text> -->
  52. <!-- </view> -->
  53. <view class="u-flex-1" @click="confirm">
  54. <text>{{ checkeType == 'selectpages' ? '确定' : '取消' }}</text>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </u-popup>
  60. </view>
  61. </template>
  62. <script>
  63. import Emitter from '@/uview-ui/libs/util/emitter.js';
  64. export default {
  65. name: 'fa-selects',
  66. mixins: [Emitter],
  67. props: {
  68. value:{
  69. type:[String,Number],
  70. default:''
  71. },
  72. //查询id
  73. faId: {
  74. type: [Number, String],
  75. default: ''
  76. },
  77. //显示字段
  78. showField: {
  79. type: String,
  80. default: ''
  81. },
  82. //保存的键
  83. keyField: {
  84. type: String,
  85. default: ''
  86. },
  87. //提示
  88. title: {
  89. type: String,
  90. default: ''
  91. },
  92. checkeType: {
  93. type: String,
  94. default: 'selectpage'
  95. },
  96. //默认的值
  97. showValue: {
  98. type: [String, Number],
  99. default: ''
  100. }
  101. },
  102. watch: {
  103. //弹出高度
  104. show(newValue, oldValue) {
  105. if (newValue) {
  106. this.$nextTick(() => {
  107. setTimeout(() => {
  108. uni.createSelectorQuery()
  109. .in(this)
  110. .select('.fa-scroll')
  111. .boundingClientRect(rect => {
  112. console.log(rect);
  113. if (rect) {
  114. this.scrollHg = rect.height;
  115. }
  116. })
  117. .exec();
  118. }, 100); //在百度直接获取不到,需要延时
  119. });
  120. if (!this.list.length) {
  121. this.page = 1;
  122. this.getSelectPages();
  123. }
  124. } else {
  125. this.sendChange();
  126. }
  127. },
  128. //默认的数据
  129. showValue: {
  130. immediate: true,
  131. handler(val) {
  132. //第一次渲染默认就好
  133. if (val && !this.isFirst) {
  134. this.isFirst = true;
  135. this.getInitSelect();
  136. }
  137. }
  138. },
  139. //搜索
  140. q_word(newValue, oldValue) {
  141. this.list = [];
  142. this.page = 1;
  143. this.getSelectPages();
  144. }
  145. },
  146. data() {
  147. return {
  148. show: false,
  149. list: [],
  150. radio_value: '',
  151. scrollHg: 0,
  152. q_word: '',
  153. pageNum: 0,
  154. page: 1,
  155. totalPage: 0,
  156. status: 'loadmore',
  157. isFirst: false,
  158. page_lable: '',
  159. pagesLable: [], //初始化的值
  160. ids_ing: [], //已经加载的值
  161. ids: []
  162. };
  163. },
  164. methods: {
  165. close() {
  166. this.show = false;
  167. },
  168. //初始化值
  169. getInitSelect() {
  170. if (this.showValue) {
  171. let param = {
  172. id: this.faId,
  173. pageNumber: this.page,
  174. q_word: this.q_word,
  175. keyValue: this.showValue
  176. };
  177. this.$api.selectpage(param).then(res => {
  178. if (this.checkeType == 'selectpage') {
  179. this.page_lable = res.list[0][this.showField];
  180. this.radio_value = res.list[0][this.keyField] + '';
  181. } else {
  182. this.pagesLable = res.list;
  183. let ids = [];
  184. res.list.forEach(item => {
  185. ids.push(item[this.keyField]);
  186. });
  187. this.ids = ids;
  188. }
  189. });
  190. }
  191. },
  192. //获取数据
  193. getSelectPages() {
  194. if (!this.faId) {
  195. return;
  196. }
  197. let param = { id: this.faId, pageNumber: this.page, q_word: this.q_word };
  198. this.$api.selectpage(param).then(res => {
  199. this.status = res.total == 0 || this.page >= this.totalPage ? 'nomore' : 'loadmore';
  200. let list = [];
  201. if (this.checkeType == 'selectpages') {
  202. res.list.forEach(item => {
  203. item.checked = this.ids.indexOf(item[this.keyField]) != -1;
  204. list.push(item);
  205. //已选的
  206. this.pagesLable.forEach(it => {
  207. if (item[this.keyField] == it[this.keyField]) {
  208. this.ids_ing.push(it); //在已选的已经加载的数据
  209. }
  210. });
  211. });
  212. } else {
  213. list = res.list;
  214. }
  215. //一页的数量,取第一次就好
  216. if (!this.pageNum) {
  217. this.pageNum = list.length;
  218. }
  219. this.totalPage = Math.ceil(res.total / this.pageNum);
  220. this.list = [...this.list, ...list];
  221. });
  222. },
  223. //选择
  224. selectCell(index) {
  225. if (this.checkeType == 'selectpages') {
  226. this.$set(this.list[index], 'checked', !this.list[index].checked);
  227. } else {
  228. //单选
  229. this.radio_value = this.list[index][this.keyField];
  230. this.page_lable = this.list[index][this.showField];
  231. this.$emit('input', this.radio_value);
  232. this.close();
  233. setTimeout(() => {
  234. this.dispatch('u-form-item', 'on-form-blur', this.radio_value);
  235. }, 50);
  236. }
  237. },
  238. //加载更多
  239. goLower(e) {
  240. if (this.page == this.totalPage) {
  241. return;
  242. }
  243. this.status = 'loading';
  244. this.page++;
  245. this.getSelectPages();
  246. },
  247. //多选确定
  248. confirm() {
  249. if (this.checkeType == 'selectpages') {
  250. //先取未加载的数据的集合
  251. let data = this.pagesLable.filter(item => {
  252. if (
  253. this.$u.test.empty(this.ids_ing) || this.ids_ing.find(it => {
  254. return item[this.keyField] == it[this.keyField];
  255. })
  256. ) {
  257. return false;
  258. } else {
  259. return true;
  260. }
  261. });
  262. let ids = [];
  263. let res = [];
  264. this.list.forEach(item => {
  265. if (item.checked) {
  266. ids.push(item[this.keyField]);
  267. res.push(item);
  268. }
  269. });
  270. //追加未加载的选项
  271. data.forEach(item => {
  272. ids.push(item[this.keyField]);
  273. res.push(item);
  274. });
  275. this.pagesLable = res;
  276. this.ids = ids;
  277. this.$emit('input', ids.join(','));
  278. setTimeout(() => {
  279. this.dispatch('u-form-item', 'on-form-blur', ids.join(','));
  280. }, 50);
  281. }
  282. this.close();
  283. },
  284. //全选
  285. allSelect() {
  286. this.list.map(item => {
  287. item.checked = true;
  288. });
  289. },
  290. //清空
  291. clearAll() {
  292. this.list.map(item => {
  293. item.checked = false;
  294. });
  295. this.pagesLable = [];
  296. },
  297. //派发事件
  298. sendChange() {
  299. setTimeout(() => {
  300. if (this.checkeType == 'select') {
  301. this.dispatch('u-form-item', 'on-form-change', this.radio_value);
  302. } else {
  303. this.dispatch('u-form-item', 'on-form-change', this.checkbox_value);
  304. }
  305. }, 50);
  306. }
  307. // upPage(){
  308. // if(this.page==1){
  309. // return;
  310. // }
  311. // this.page--;
  312. // },
  313. // nextPage(){
  314. // if(this.page == this.totalPage){
  315. // return;
  316. // }
  317. // this.page++;
  318. // if(!this.list[this.page-1]){
  319. // this.getSelectPages();
  320. // }
  321. // }
  322. }
  323. };
  324. </script>
  325. <style lang="scss" scoped>
  326. .selectpage {
  327. width: 100%;
  328. }
  329. .select-pages {
  330. width: 100%;
  331. border: 1px solid #dcdfe6;
  332. padding: 5rpx 10rpx;
  333. }
  334. .u-flex-column {
  335. flex-direction: column;
  336. height: 100%;
  337. .fa-column {
  338. width: 100%;
  339. }
  340. }
  341. </style>