移动端基于Vant组件封装底部弹出搜索多选列表:
效果图如下:
使用到的组件:van-popup,van-search
组件页面代码:searchDataPopup.vue
<template>
<van-popup class="search-data-popup" v-model="show" position="bottom" :lazy-render="false">
<div class="header-line">
<div class="cancel" @click="onSearchCancel">取消</div>
<div class="title">{{ title }}</div>
<div class="sure" @click="onSearchConfirm">确定</div>
</div>
<van-search placeholder="输入您想搜索的内容" v-model="searchValue" @input="inputSearchValue" />
<div class="tip">已选{{temp_datas.length}}条</div>
<div class="lists">
<div class="line" v-for="(item, index) in options" @click="checkedLine(item)">
<div class="name">{{ item.username }}</div>
<img src="@/assets/img/organize-tick-icon.png" v-if="getArrayColumn(temp_datas, 'gpid').indexOf(item.gpid) !== -1" />
</div>
</div>
</van-popup>
</template>
<script>
export default {
name: "searchDataPopup",
props: {
showPicker: Boolean, //是否显示
datas: Array, //未根据搜索内容筛选的所有列表数据
defaultDatas: Array, //默认选中数据
title: String //标题
},
data(){
return {
searchValue: "", //搜索框内容
options: [], //根据搜索内容筛选出来的列表数据
temp_datas: [] //选中的列表数据,通过确定按钮传给父组件
}
},
computed: {
show: {
get() {
return this.showPicker;
},
set() {
this.$emit("cancel");
},
},
},
mounted(){
this.temp_datas = JSON.parse(JSON.stringify(this.defaultDatas));
this.searchValue = "";
this.options = [];
},
methods: {
inputSearchValue(query) {
//搜索框值发生改变
if (query !== '') {
setTimeout(() => {
this.options = this.datas.filter(item => {
return item.username.indexOf(query.toLowerCase()) > -1;
});
}, 200);
} else {
this.options = [];
}
},
checkedLine(item) {
//选中行
if(this.getArrayColumn(this.temp_datas, 'gpid').indexOf(item.gpid) !== -1) {
//已经选中此行数据,再次点击则取消选中
this.temp_datas = this.temp_datas.filter(row => {
return row.gpid !== item.gpid;
});
} else {
//未选中此行数据,添加
this.temp_datas.push(item);
}
},
onSearchCancel() {
//取消
this.$emit("cancel");
},
onSearchConfirm() {
//确认
this.$emit("confirm", this.temp_datas);
},
getArrayColumn(arr, column){
//获取二维数组指定元素的一维数组
var temp = [];
for(let i = 0; i < arr.length; i++) {
temp.push(arr[i][column]);
}
return temp;
}
}
}
</script>
<style scoped>
.search-data-popup .tip {
color: #666;
padding-bottom: 5px;
}
.search-data-popup .header-line {
display: flex;
justify-content: space-between;
align-items: center;
height: 44px;
}
.search-data-popup .header-line .cancel {
padding: 0 16px;
font-size: 14px;
color: #969799;
}
.search-data-popup .header-line .title {
font-weight: 500;
font-size: 16px;
color: #343434;
}
.search-data-popup .header-line .sure {
padding: 0 16px;
font-size: 14px;
color: #576b95;
}
.search-data-popup .lists {
display: flex;
flex-direction: column;
padding: 10px 12px 20px 12px;
height: 200px;
overflow: auto;
}
.search-data-popup .lists .line {
line-height: 40px;
font-size: 16px;
color: #000;
display: flex;
justify-content: space-between;
align-items: center;
}
.search-data-popup .lists .line img {
width: 20px;
height: 20px;
}
</style>
父页面引入方式如下
<!-- 我的个人信息 -->
<template>
<div class="my-info">
<van-form ref="ruleForm">
<van-field
readonly
clickable
autosize
rows="1"
type="textarea"
name="selectData"
:value="getArrayColumn(ruleForm.selectData, 'username').join(',')"
label="选择列表"
@click="showDataPopup"
/>
<searchDataPopup v-if="showDataPicker" :showPicker="showDataPicker" title="请选择用户" :datas="dataList" :defaultDatas="ruleForm.selectData" @confirm="onDataPickerConfirm" @cancel="showDataPicker = false"></searchDataPopup>
</van-form>
</div>
</template>
<script>
import searchDataPopup from '@/components/searchDataPopup'
export default {
name: "MyProfile",
components: { searchDataPopup },
data() {
return {
ruleForm: {
selectData: []
},
showDataPicker: false,
dataList: []
};
},
created() {
//获取用户列表
this.getUserOptions();
},
methods: {
onDataPickerConfirm(data) {
//点击确定
this.ruleForm.selectData = data;
this.showDataPicker = false;
},
showDataPopup() {
//显示Picker
this.showDataPicker = true;
},
getUserOptions() {
//获取用户列表
axios('/xxxx', "get", {
}).then((response) => {
this.dataList = response;
}).catch((error) => {
});
},
getArrayColumn(arr, column){
//获取二维数组指定元素的一维数组
var temp = [];
for(let i = 0; i < arr.length; i++) {
temp.push(arr[i][column]);
}
return temp;
}
}
};
</script>
这样就大功告成了!