personList.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <div class="personList">
  3. <van-search
  4. v-model="value"
  5. show-action
  6. placeholder="请输入搜索关键词"
  7. @search="onSearch"
  8. @cancel="onCancel"
  9. />
  10. <van-list
  11. v-model:loading="loading"
  12. :finished="finished"
  13. finished-text="没有更多了"
  14. @load="onLoad"
  15. >
  16. <van-cell title="全选">
  17. <template #right-icon>
  18. <input type="checkbox" v-model="isAll" @change="selectAll" />
  19. </template>
  20. </van-cell>
  21. <van-cell v-for="(item, index) in list" :key="item" :title="item">
  22. <template #right-icon>
  23. <input
  24. type="checkbox"
  25. :ref="getList"
  26. @change="selectPerson(item, index)"
  27. />
  28. </template>
  29. </van-cell>
  30. </van-list>
  31. </div>
  32. </template>
  33. <script>
  34. import { ref, toRef } from "vue";
  35. export default {
  36. name: "personList",
  37. emits: ["selected"],
  38. setup(props, { emit }) {
  39. const list = [];
  40. const loading = ref(false);
  41. const finished = ref(false);
  42. const onLoad = () => {
  43. // 异步更新数据
  44. // setTimeout 仅做示例,真实场景中一般为 ajax 请求
  45. setTimeout(() => {
  46. for (let i = 0; i < 10; i++) {
  47. list.push(list.length + 1);
  48. }
  49. // 加载状态结束
  50. loading.value = false;
  51. // 数据全部加载完成
  52. if (list.length >= 10) {
  53. finished.value = true;
  54. }
  55. }, 1000);
  56. };
  57. // 搜索
  58. const value = ref("");
  59. const onSearch = (val) => showToast(val);
  60. const onCancel = () => showToast("取消");
  61. // 选择人员
  62. let selects = [];
  63. // 全选
  64. let isAll = ref(false);
  65. let checks = [];
  66. const getList = (el) => {
  67. checks.push(el);
  68. };
  69. const selectAll = () => {
  70. checks.forEach((item) => {
  71. item.checked = isAll.value;
  72. });
  73. if (isAll) {
  74. selects = list;
  75. } else {
  76. selects = [];
  77. }
  78. emit("selected", selects.join(","));
  79. };
  80. const selectPerson = (value, index) => {
  81. if (checks[index].checked) {
  82. selects.push(value);
  83. } else {
  84. selects.splice(selects.indexOf(value), 1);
  85. }
  86. if (selects.length == getList.length) {
  87. isAll.value = true;
  88. } else {
  89. isAll.value = false;
  90. }
  91. emit("selected", selects.join(","));
  92. };
  93. return {
  94. list,
  95. onLoad,
  96. loading,
  97. finished,
  98. selectPerson,
  99. value,
  100. onSearch,
  101. onCancel,
  102. selectAll,
  103. getList,
  104. isAll,
  105. };
  106. },
  107. };
  108. </script>
  109. <style scoped>
  110. .personList {
  111. height: 65vh;
  112. overflow: auto;
  113. margin: 10px;
  114. }
  115. .van-button {
  116. top: -5px;
  117. }
  118. .search {
  119. height: 40px;
  120. line-height: 40px;
  121. }
  122. .van-list {
  123. height: 80%;
  124. margin-top: 5px;
  125. }
  126. .keyword {
  127. width: 70%;
  128. height: 25px;
  129. border-radius: 25px;
  130. border: 1px solid;
  131. padding-left: 15px;
  132. }
  133. </style>