SelectPicker.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <van-popup class="search-data-popup" round lazy-render v-model="show" position="bottom" >
  3. <div class="header-line">
  4. <div class="cancel" @click="onSearchCancel">取消</div>
  5. <div class="title">{{ title }}</div>
  6. <div class="sure" @click="onSearchConfirm">确定</div>
  7. </div>
  8. <van-search v-if="showSearch" placeholder="输入您想搜索的内容" v-model="searchValue" @input="inputSearchValue" />
  9. <!-- <div class="tip">已选{{temp_datas.length}}条</div>-->
  10. <div v-if="itemList?.length >0" class="lists">
  11. <div class="line" v-for="(item, index) in itemList" :key="item[valueKey]">
  12. <van-cell
  13. clickable
  14. :key="item[valueKey]"
  15. :title="item[valueKey]"
  16. @click="click(item,index)">
  17. <template #right-icon>
  18. <van-checkbox v-model="item.checked"/>
  19. </template>
  20. </van-cell>
  21. </div>
  22. </div>
  23. <div v-else class="lists">
  24. <van-empty description="暂无数据" />
  25. </div>
  26. </van-popup>
  27. </template>
  28. <script>
  29. export default {
  30. props: {
  31. showPicker: {
  32. types:Boolean,
  33. default:false
  34. }, //是否显示
  35. options: {
  36. type:Array,
  37. default: ()=>[],
  38. }, //未根据搜索内容筛选的所有列表数据
  39. value: {
  40. type:Array,
  41. default: ()=>[],
  42. },//默认选中数据
  43. //自定义字段
  44. valueKey:{
  45. type: String,
  46. default:'label'
  47. },
  48. showSearch:{
  49. type:Boolean,
  50. default:true
  51. },
  52. title: String //标题
  53. },
  54. data(){
  55. return {
  56. searchValue: "", //搜索框内容
  57. itemList:[],
  58. }
  59. },
  60. watch:{
  61. temp_datas:{
  62. handler(val){
  63. this.itemList = val;
  64. },
  65. deep:true
  66. },
  67. },
  68. computed: {
  69. columns(){
  70. return this.options
  71. },
  72. temp_datas(){
  73. this.columns.forEach(v=>{
  74. this.value.forEach((item)=>{
  75. if(v[this.valueKey] === item[this.valueKey]){
  76. v.checked = true;
  77. }else {
  78. v.checked = false;
  79. }
  80. })
  81. })
  82. return this.columns
  83. },
  84. show:{
  85. get(){
  86. return this.showPicker;
  87. },
  88. set(){
  89. this.$emit("cancel");
  90. },
  91. },
  92. },
  93. methods: {
  94. click(v,i){
  95. this.$set(this.columns[i],'checked',!this.columns[i].checked);
  96. },
  97. inputSearchValue(query) {
  98. if(query == ''){return this.itemList = this.options }
  99. //搜索框值发生改变
  100. setTimeout(() => {
  101. this.itemList= this.temp_datas.filter(item => {
  102. return item[this.valueKey].indexOf(query.toLowerCase()) > -1;
  103. });
  104. }, 200);
  105. },
  106. onSearchCancel() {
  107. //取消
  108. this.$emit("cancel");
  109. },
  110. onSearchConfirm() {
  111. let arr = this.columns.filter(v=>v.checked === true)
  112. //确认
  113. this.$emit("confirm", arr);
  114. this.show = false;
  115. },
  116. },
  117. }
  118. </script>
  119. <style scoped>
  120. .search-data-popup .tip {
  121. color: #666;
  122. padding-bottom: 5px;
  123. }
  124. .search-data-popup .header-line {
  125. display: flex;
  126. justify-content: space-between;
  127. align-items: center;
  128. height: 90px;
  129. }
  130. .search-data-popup .header-line .cancel {
  131. padding: 0 30px;
  132. font-size: 28px;
  133. color: #969799;
  134. }
  135. .search-data-popup .header-line .title {
  136. font-weight: 500;
  137. font-size: 30px;
  138. color: #343434;
  139. }
  140. .search-data-popup .header-line .sure {
  141. padding: 0 30px;
  142. font-size: 28px;
  143. color: #1989fa;
  144. }
  145. .search-data-popup .lists {
  146. display: flex;
  147. flex-direction: column;
  148. padding: 10px 12px 20px 12px;
  149. min-height: 300px;
  150. max-height: 700px;
  151. overflow: auto;
  152. }
  153. .search-data-popup .lists .line {
  154. line-height: 40px;
  155. font-size: 16px;
  156. color: #000;
  157. display: flex;
  158. justify-content: space-between;
  159. align-items: center;
  160. }
  161. .search-data-popup .lists .line img {
  162. width: 20px;
  163. height: 20px;
  164. }
  165. </style>