VanFieldCheckbox.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <template>
  2. <div class="dh-field">
  3. <div class="van-hairline--bottom">
  4. <van-field
  5. v-model="resultLabel"
  6. v-bind="$attrs"
  7. readonly
  8. :is-link="$attrs.disabled === undefined"
  9. error-message-align="right"
  10. input-align="right"
  11. @click="showPopu($attrs.disabled)"
  12. class="dh-cell"
  13. />
  14. {{show}}
  15. <van-popup v-model:show="show" position="bottom" class="">
  16. popup
  17. <!-- <div class="van-picker__toolbar">
  18. <button type="button" class="van-picker__cancel" @click="cancel">
  19. 取消
  20. </button>
  21. <div class="van-ellipsis van-picker__title">{{ $attrs.label }}</div>
  22. <button type="button" class="van-picker__confirm" @click="onConfirm">
  23. 确认
  24. </button>
  25. </div>
  26. <div class="checkbox-con" style="max-height: 264px; overflow-y: auto">
  27. <van-field
  28. v-model="searchVal"
  29. placeholder="搜索"
  30. @input="search"
  31. v-if="isSearch"
  32. input-align="left"
  33. />
  34. <van-cell title="全选">
  35. <template #right-icon>
  36. <van-checkbox
  37. name="all"
  38. @click="toggleAll"
  39. v-model="checkedAll"
  40. />
  41. </template>
  42. </van-cell>
  43. <van-checkbox-group
  44. v-model="checkboxValue"
  45. @change="change"
  46. ref="checkboxGroup"
  47. >
  48. <van-cell-group>
  49. <van-cell
  50. v-for="(item, index) in columnsData"
  51. clickable
  52. :key="item[option.value]"
  53. :title="item[option.label]"
  54. @click="toggle(index)"
  55. >
  56. <template #right-icon>
  57. <van-checkbox :name="item[option.value]" ref="checkboxes" />
  58. </template>
  59. </van-cell>
  60. </van-cell-group>
  61. </van-checkbox-group>
  62. </div> -->
  63. </van-popup>
  64. </div>
  65. </div>
  66. </template>
  67. <script>
  68. export default {
  69. name: "VanFieldCheckbox",
  70. model: {
  71. prop: "selectValue",
  72. },
  73. props: {
  74. columns: {
  75. type: Array,
  76. default: function () {
  77. return [];
  78. },
  79. },
  80. selectValue: {
  81. type: Array,
  82. default: function () {
  83. return [];
  84. },
  85. },
  86. option: {
  87. type: Object,
  88. default: function () {
  89. return { label: "label", value: "value" };
  90. },
  91. },
  92. isSearch: {
  93. type: Boolean,
  94. default: false,
  95. },
  96. },
  97. computed: {
  98. resultLabel: {
  99. get() {
  100. const res = this.columns.filter((item) => {
  101. return this.resultValue.indexOf(item[this.option.value]) > -1;
  102. });
  103. const resLabel = res.map((item) => {
  104. return item[this.option.label];
  105. });
  106. return resLabel.join(",");
  107. },
  108. set() {},
  109. },
  110. },
  111. data() {
  112. return {
  113. show: false,
  114. searchVal: "",
  115. columnsData: JSON.parse(JSON.stringify(this.columns)),
  116. checkboxValue: JSON.parse(JSON.stringify(this.selectValue)),
  117. checkedAll: false,
  118. resultValue: JSON.parse(JSON.stringify(this.selectValue)),
  119. };
  120. },
  121. methods: {
  122. search(val) {
  123. if (val) {
  124. this.columnsData = this.columnsData.filter((item) => {
  125. return item[this.option.label].indexOf(val) > -1;
  126. });
  127. } else {
  128. this.columnsData = JSON.parse(JSON.stringify(this.columns));
  129. }
  130. },
  131. getData(val) {
  132. const res = this.columnsData.filter((item) => {
  133. return val.indexOf(item[this.option.value]) > -1;
  134. });
  135. return res;
  136. },
  137. onConfirm() {
  138. this.resultValue = this.checkboxValue;
  139. this.show = !this.show;
  140. this.$emit("confirm", this.resultValue, this.getData(this.resultValue));
  141. },
  142. change(val) {
  143. this.$emit("change", val, this.getData(this.resultValue));
  144. },
  145. cancel() {
  146. this.show = !this.show;
  147. this.$emit("cancel", this.resultValue);
  148. },
  149. toggle(index) {
  150. this.$refs.checkboxes[index].toggle();
  151. },
  152. toggleAll() {
  153. this.$refs.checkboxGroup.toggleAll(this.checkedAll);
  154. },
  155. showPopu(disabled) {
  156. console.log('showPopu');
  157. this.columnsData = JSON.parse(JSON.stringify(this.columns));
  158. this.checkboxValue = JSON.parse(JSON.stringify(this.selectValue));
  159. this.resultValue = JSON.parse(JSON.stringify(this.selectValue));
  160. if (disabled !== undefined && disabled !== false) {
  161. return false;
  162. } else {
  163. this.show = !this.show;
  164. }
  165. },
  166. },
  167. watch: {
  168. selectValue: function (newVal) {
  169. this.resultValue = newVal;
  170. },
  171. resultValue(val) {
  172. this.searchVal = "";
  173. this.columnsData = JSON.parse(JSON.stringify(this.columns));
  174. this.$emit("input", val);
  175. },
  176. columnsData: {
  177. handler(val) {
  178. if (val.length && val.length === this.checkboxValue.length) {
  179. this.checkedAll = true;
  180. } else {
  181. this.checkedAll = false;
  182. }
  183. },
  184. immediate: true,
  185. },
  186. checkboxValue: {
  187. handler(val) {
  188. if (val.length && val.length === this.columnsData.length) {
  189. this.checkedAll = true;
  190. } else {
  191. this.checkedAll = false;
  192. }
  193. },
  194. immediate: true,
  195. },
  196. },
  197. };
  198. </script>
  199. <style lang="less" scoped>
  200. .dh-field {
  201. padding: 0 16px;
  202. background: #fff;
  203. .dh-cell.van-cell {
  204. padding: 10px 0;
  205. }
  206. .dh-cell.van-cell--required::before {
  207. left: -8px;
  208. }
  209. .van-popup {
  210. border-radius: 20px 20px 0 0;
  211. }
  212. }
  213. </style>