fa-selects.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <template>
  2. <view class="selects">
  3. <view class="" style="min-height: 70rpx;" @click="show = true">
  4. <rich-text :class="!lists_lable ? 'richColor' : ''" :nodes="nodes(lists_lable || '请选择' + title)"></rich-text>
  5. </view>
  6. <u-popup v-model="show" :popup="false" mode="bottom" height="600" @close="close">
  7. <view class="u-flex u-flex-column">
  8. <view class="fa-column u-flex-1 u-flex fa-scroll">
  9. <scroll-view scroll-y="true" :style="[{ height: scrollHg + 'px', width: '100vw' }]">
  10. <!-- 多选-->
  11. <view v-if="checkeType == 'selects'">
  12. <checkbox-group>
  13. <u-cell-item :arrow="false" v-for="(item, index) in list" :key="index" @click.self="selectCell(index)">
  14. <view slot="title"><rich-text :nodes="nodes(item[showField])"></rich-text></view>
  15. <checkbox
  16. slot="right-icon"
  17. shape="square"
  18. :class="item.disabled == true ? 'fa-disabled' : ''"
  19. :checked="item.checked"
  20. :color="theme.bgColor"
  21. :disabled="item.disabled == true"
  22. ></checkbox>
  23. </u-cell-item>
  24. </checkbox-group>
  25. </view>
  26. <!-- 单选 -->
  27. <view class="" v-else>
  28. <u-radio-group style="width: 100%;" v-model="radio_value">
  29. <u-cell-item :arrow="false" v-for="(item, index) in list" :key="index" @click.self="selectCell(index)">
  30. <view slot="title"><rich-text :nodes="nodes(item[showField])"></rich-text></view>
  31. <u-radio slot="right-icon" :active-color="theme.bgColor" :name="item[keyField]" :disabled="item.disabled == true"></u-radio>
  32. </u-cell-item>
  33. </u-radio-group>
  34. </view>
  35. </scroll-view>
  36. </view>
  37. <view class="fa-column select-footer u-text-center" v-if="checkeType == 'selects'">
  38. <u-gap height="10" bg-color="#eaeaec"></u-gap>
  39. <view class="u-p-10 u-flex u-row-around">
  40. <view class="u-flex-1" v-if="checkeType == 'selects'" @click="clearAll"><text>清空</text></view>
  41. <!-- <view class="u-flex-1" @click="allSelect"> -->
  42. <!-- <text>全选</text> -->
  43. <!-- </view> -->
  44. <view class="u-flex-1" @click="confirm"><text>确定</text></view>
  45. </view>
  46. </view>
  47. <view class="fa-column select-footer u-text-center" v-if="checkeType != 'selects'">
  48. <u-gap height="5" bg-color="#eaeaec"></u-gap>
  49. <view class="u-p-10 u-flex u-row-around">
  50. <view class="u-flex-1" @click="close"><text>取消</text></view>
  51. </view>
  52. </view>
  53. </view>
  54. </u-popup>
  55. </view>
  56. </template>
  57. <script>
  58. import Emitter from '@/uview-ui/libs/util/emitter.js';
  59. export default {
  60. name: 'fa-selects',
  61. mixins: [Emitter],
  62. props: {
  63. value: {
  64. type: [String, Number],
  65. default: false
  66. },
  67. //数据源
  68. faList: {
  69. type: [Object, Array, String],
  70. default: ''
  71. },
  72. //选择类型
  73. checkeType: {
  74. type: String,
  75. default: 'select'
  76. },
  77. title: {
  78. type: String,
  79. default: ''
  80. },
  81. //显示的字段
  82. showField: {
  83. type: String,
  84. default: 'name'
  85. },
  86. //取值得字段
  87. keyField: {
  88. type: String,
  89. default: 'id'
  90. },
  91. //默认的值
  92. showValue: {
  93. type: [String, Number],
  94. default: ''
  95. }
  96. },
  97. computed: {
  98. nodes() {
  99. return title => {
  100. return [
  101. {
  102. name: 'div',
  103. children: [
  104. {
  105. type: 'text',
  106. text: title
  107. }
  108. ]
  109. }
  110. ];
  111. };
  112. }
  113. },
  114. watch: {
  115. faList: {
  116. immediate: true,
  117. handler(val) {
  118. if (this.$u.test.array(val)) {
  119. if (val.length > 0 && this.$u.test.object(val[0])) {
  120. this.list = JSON.parse(JSON.stringify(val));
  121. } else {
  122. this.list = [];
  123. for (let i in val) {
  124. this.list.push({
  125. name: val[i],
  126. id: i
  127. });
  128. }
  129. }
  130. } else if (this.$u.test.object(val)) {
  131. this.list = [];
  132. for (let i in val) {
  133. this.list.push({
  134. name: val[i],
  135. id: i
  136. });
  137. }
  138. }
  139. if (this.checkeType == 'selects') {
  140. this.list.forEach((item, index) => {
  141. this.$set(this.list[index], 'checked', false);
  142. });
  143. }
  144. // 单选的默认值
  145. if (this.showValue && this.checkeType == 'select') {
  146. this.list.forEach((item, index) => {
  147. if (item[this.keyField] == this.showValue) {
  148. this.radio_value = this.showValue;
  149. this.lists_lable = item[this.showField];
  150. }
  151. });
  152. }
  153. // 多选的默认值
  154. if (this.showValue && this.checkeType == 'selects') {
  155. let arr = this.showValue.split(',');
  156. let lables = [];
  157. this.list.forEach((item, index) => {
  158. arr.forEach(id => {
  159. if (item[this.keyField] == id) {
  160. this.$set(this.list[index], 'checked', !this.list[index].checked);
  161. lables.push(item[this.showField]);
  162. }
  163. });
  164. });
  165. this.lists_lable = lables.join(',');
  166. }
  167. }
  168. },
  169. //显示高度
  170. show(newValue, oldValue) {
  171. if (newValue) {
  172. this.show = true;
  173. this.$nextTick(() => {
  174. setTimeout(() => {
  175. uni.createSelectorQuery()
  176. .in(this)
  177. .select('.fa-scroll')
  178. .boundingClientRect(rect => {
  179. console.log(rect);
  180. if (rect) {
  181. this.scrollHg = rect.height;
  182. }
  183. })
  184. .exec();
  185. }, 100); //在百度直接获取不到,需要延时
  186. });
  187. } else {
  188. this.sendChange();
  189. }
  190. }
  191. },
  192. data() {
  193. return {
  194. show: false,
  195. radio_value: '',
  196. checkbox_value: '',
  197. scrollHg: 200,
  198. lists_lable: '',
  199. list: []
  200. };
  201. },
  202. methods: {
  203. close() {
  204. this.show = false;
  205. },
  206. selectCell(index) {
  207. if (this.list[index].disabled == true) {
  208. return;
  209. }
  210. if (this.checkeType == 'selects') {
  211. this.$set(this.list[index], 'checked', !this.list[index].checked);
  212. } else {
  213. //单选值确定
  214. this.radio_value = this.list[index][this.keyField] || '';
  215. this.lists_lable = this.list[index][this.showField] || '';
  216. this.$emit('input', this.radio_value);
  217. this.close();
  218. setTimeout(() => {
  219. this.dispatch('u-form-item', 'on-form-blur', this.radio_value);
  220. }, 50);
  221. }
  222. },
  223. //多选的确定
  224. confirm() {
  225. let lable = [];
  226. let ids = [];
  227. this.list.forEach(item => {
  228. if (item.checked) {
  229. lable.push(item.name);
  230. ids.push(item.id);
  231. }
  232. });
  233. this.lists_lable = lable.join(',');
  234. this.checkbox_value = ids.join(',');
  235. this.$emit('input', this.checkbox_value);
  236. setTimeout(() => {
  237. this.dispatch('u-form-item', 'on-form-blur', this.checkbox_value);
  238. }, 50);
  239. this.close();
  240. },
  241. //全选
  242. allSelect() {
  243. this.list.map(item => {
  244. item.checked = true;
  245. });
  246. },
  247. //清空
  248. clearAll() {
  249. this.list.map(item => {
  250. item.checked = false;
  251. });
  252. },
  253. //派发事件
  254. sendChange() {
  255. setTimeout(() => {
  256. if (this.checkeType == 'select') {
  257. this.dispatch('u-form-item', 'on-form-change', this.radio_value);
  258. } else {
  259. this.dispatch('u-form-item', 'on-form-change', this.checkbox_value);
  260. }
  261. }, 50);
  262. }
  263. }
  264. };
  265. </script>
  266. <style lang="scss" scoped>
  267. .selects {
  268. width: 100%;
  269. }
  270. .richColor {
  271. color: #909399;
  272. }
  273. .u-flex-column {
  274. flex-direction: column;
  275. height: 100%;
  276. .fa-column {
  277. width: 100%;
  278. }
  279. }
  280. </style>