fa-selectpages.vue 8.5 KB

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