介绍
在开发微信小程序时总会遇到需要查询的,每有一个页面需要查询时就要写,这样写太浪费时间,自己直接封装一个,当需要查询方法的时候,引入这个组件就可以了。
话不多说,上代码!
html部分
里面运用了三目运算符来判断样式,可根据设计图来改成自己需要的样式
<template>
<view class="drawerSearch">
<view class="example-body">
<view class="search">
<uni-search-bar :placeholder="placeholder" v-model="form[name]" :readonly="readonly" clearButton="none" cancelButton="none"
bgColor="#F6F7FB" @confirm="fun_Search" />
<view :class="searchBnt 'r' : 'searchBnt'" @click="fun_Search">
搜索
</view>
<!-- 这里用的icon是自己引入的 不需要可以不写 -->
<view @click="fun_Toggle('top')" class="screen" v-if="isShowBtn">筛选<text class="shaixuan icon-shaixuan"></text></view>
</view>
<view class="drawer">
<uni-popup ref="popup" background-color="#fff" @change="fun_Change">
<view class="head">
<uni-icons type="closeempty" size="16" @tap="fun_Closeempty"></uni-icons>
<text>筛选</text>
<view class="k"></view>
</view>
<uni-forms ref="baseForm" :modelValue="form">
<view class="form" v-for="(item,index) in searchForm" :key="index">
<uni-forms-item :label="item.label" v-if="item.type === 'input'">
<uni-easyinput :placeholderStyle="placeholderStyle" :placeholder="item.placeholder ? item.placeholder : '请输入'" :border="false" v-model="form[item.key]" />
</uni-forms-item>
<uni-forms-item :label="item.label" v-if="item.type === 'picker'">
<!-- 这里用的是封装过的 是需要请求接口的 -->
<PickerSelect ref="select" :keyValue="item.key" :requestUrl="item.url" @fun_SendId="fun_SendId" />
</uni-forms-item>
<uni-forms-item :label="item.label" v-if="item.type === 'slotPicker'">
<!-- 这里是需要通过父级传递的选择值 -->
<picker ref="picker" @change="fun_SlotChangeSelect($event,item.key)" :value="form[item.key]" range-key="name" :range="item.columns" placeholder="请选择">
<view class="uni-input" :style="slotPickerName ? 'color: #333333;' : 'color: #B3BAC7;'">
{{slotPickerName ? slotPickerName : "请选择"}}<uni-icons type="forward" size="16" color="#B3BAC7" />
</view>
</picker>
</uni-forms-item>
<uni-forms-item :label="item.label" v-if="item.type === 'date'">
<picker mode="date" :fields="item.fields ? item.fields : 'day'" :value="form[item.key]" @change="fun_ChangeData($event,item.key)">
<view class="date-input" :style="form[item.key] ? 'color: #333333;' : 'color: #B3BAC7;'">{{form[item.key] ? form[item.key] : "点击选择时间"}}</view>
</picker>
</uni-forms-item>
</view>
</uni-forms>
<view class="btn">
<view class="reset" @click="fun_Reset">重置</view>
<view class="submit" @click="fun_ClosePopup">确定</view>
</view>
</uni-popup>
</view>
</view>
<!-- 返回顶部 -->
<view class="backTop" v-if="topShow" @click="fun_BackTop">
<uni-icons type="top" size="22" color="#333333" />
</view>
</view>
</template>
js部分
里面用到封装过得选择器有兴趣的可以去看看 picker封装
// 引入组件
import PickerSelect from "@/components/picker/index.vue";
export default {
components: {
PickerSelect
},
options: {
styleIsolation: 'shared'
},
data() {
return {
type: 'center',
// 输入框占位符样式
placeholderStyle:"color:#B3BAC7;font-size: 14px;",
// 基础表单数据
form: {},
// slot 选择器显示字段
slotPickerName:"",
// 是否显示返回顶部
topShow: false,
// 当前滚动高度
scrollTop: 0
}
},
// 接收来自父组件的属性
props: {
// 查询表单数组
searchForm: {
type: Array,
default: () => {
return [];
},
},
// 查询输入框字段名
name: {
type: String,
default: "name" // 查询输入框的key
},
// 是否禁用
readonly:{
type:Boolean,
default:false
},
// 输入框占位符
placeholder: {
type: String,
default: "请输入"
},
// 是否显示筛选
isShowBtn: {
type: Boolean,
default: true
},
},
// 模板编译完成
mounted() {
},
// 自定义方法
methods: {
/**
* @description 搜索
*/
fun_Search() {
delete this.form.undefined;
// 向父组件传值
this.$emit("fun_Search", this.form);
},
/**
* slot的选择方法
*/
fun_SlotChangeSelect(val,key){
// 遍历数据
this.searchForm.map(e=>{
// 判断选择的key
if(e.key === key){
// 回显数据
this.slotPickerName = e.columns[val.detail.value].name; // 显示的name
this.form[key] = e.columns[val.detail.value].value; // 查询的value
}
})
},
// 打开窗口
fun_Toggle(type) {
this.type = type
// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
this.$refs.popup.open(type)
},
/**
* @description 选择时触发的方法
* @param {选择的值} e
*/
fun_SendId(e) {
// 选中的id赋值
this.form[e.key] = e.value;
},
// 关闭窗口
fun_Change(e) {
console.log('当前模式:' + e.type + ',状态:' + e.show);
},
/**
* 确定
*/
fun_ClosePopup() {
// 关闭弹窗
this.$refs.popup.close()
},
/**
* 重置
*/
fun_Reset() {
// 清空form
for (const key in this.form) {
this.form[key] = "";
}
// 判断是否有选择器
if(this.$refs.select){
// 遍历
this.$refs.select.map(e=>{
e.name = "";
})
}
this.slotPickerName = "";
// 向父组件传值
this.$emit("fun_Reset");
},
/**
* 关闭
*/
fun_Closeempty() {
// 关闭弹窗
this.$refs.popup.close()
},
// 日期方法
fun_ChangeData(e, key) {
// 获取选择的值
this.$set(this.form, key, e.detail.value);
this.date = e.detail.value
},
// 监听滚动
fun_TopData(e) {
// 这个e直接是滚动时候的高度
this.topShow = e > 300;
},
// 返回顶部
fun_BackTop() {
uni.pageScrollTo({
scrollTop: this.scrollTop,
duration: 300
});
}
}
}
css部分
.drawerSearch{
.drawer{
.head{
text-align: center;
color: #333333;
font-size: 16px;
padding: 10px 0;
margin: 0 10px;
border-bottom: 1px solid #E5E5E5;
display: flex;
justify-content: space-between;
.k {
width: 16px;
height: 16px;
}
}
}
.search{
display: flex;
align-items: center;
uni-search-bar{
width: 100%;
flex: 1;
}
/deep/.uni-searchbar{
padding: 10px 5px 10px 15px;
.uni-searchbar__box{
border: 1px solid #E44E4E;
border-radius: 50px !important;
justify-content: left !important;
.uni-searchbar__box-search-input{
flex: 0.8 !important;
}
.uni-searchbar__box-icon-search {
padding: 0 5px 0 11px;
}
.uni-searchbar__text-placeholder {
line-height: 18px;
margin-left: 0;
}
}
}
.searchBnt{
position: absolute;
right: 20%;
z-index: 1;
margin-bottom: 2px;
color: #E44E4E;
border-left: 1px solid #E44E4E;
padding-left: 10px;
}
.r{
position: absolute;
right: 7%;
z-index: 1;
margin-bottom: 2px;
color: #E44E4E;
border-left: 1px solid #E44E4E;
padding-left: 10px;
}
.screen{
padding-right: 15px;
color: #E44E4E;
}
}
uni-transiton{
view{
&:first-child{
height: 100vh;
}
}
}
.btn{
display: flex;
margin-top: 50px;
line-height: 46px;
border-top: 1px solid #E5E5E5;
.submit, .reset {
flex: 1;
text-align: center;
font-size: 16px;
}
.submit {
background-color: #E44E4E;
color: #FFFFFF;
}
}
.uni-forms{
padding: 0 10px;
.form{
padding: 4px 0;
border-bottom: 1px solid #E5E5E5;
}
.uni-forms-item{
margin: 0;
display: flex;
align-items: center;
box-sizing: border-box;
&:last-child{
border: none;
}
.uni-forms-item__label{
width: auto !important;
}
.uni-forms-item__content{
text-align: right;
.uni-input {
color: #B3BAC7;
}
.date-input {
color: #333333;
}
.uni-easyinput{
.uni-easyinput__content{
border: none;
text-align: right;
}
}
.uni-stat__select{
.uni-stat-box{
.uni-select{
border: none;
text-align: right;
}
}
}
.uni-date{
.uni-date-editor{
.uni-date-x{
text-align: right;
.icon-calendar{
display: none;
}
}
}
}
.picker{
text-align: right;
.uni-input {
display: flex;
justify-content: flex-end;
align-items: center;
.uni-icons {
margin-left: 3px;
}
}
}
}
}
}
.backTop {
position: fixed;
right: 26px;
bottom: 90px;
width: 38px;
height: 38px;
border-radius: 50%;
background-color: #FFFFFF;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #E5E5E5;
}
}
其他页面引入
html部分
<DrawerSearch ref="drawerSearch" :searchForm="searchForm" name="name" placeholder="请输入您要查询的名称"
@fun_Search="fun_OnSearch"></DrawerSearch>
js部分
这里用了官方api来监听滚动 监听滚动
// 引入组件
import DrawerSearch from "@/components/drawerSearch/index.vue"; // 这里是封装组件地址
export default {
// 声明组件
components: {
DrawerSearch,
},
data() {
return {
// 查询字段
searchForm: [{
type: "picker",
label: "资质资格类型",
key: "certTypeNum",
url: "url", // 需要请求的接口地址
value: ""
},
{
type: "input",
label: "证书编号",
key: "certIds",
value: ""
},
{
type: "input",
label: "发证机关",
key: "organNames",
value: ""
},
{
type: "picker",
label: "证书状态",
key: "isValids",
url: "url", // 需要请求的接口地址
value: ""
},
{
type: "date",
label: "发证日期",
key: "organDates",
value: ""
},
{
type: "slotPicker",
label: "状态",
key: "state",
columns: [{
name: "保存",
value: "bc"
},
{
name: "提交",
value: "tj"
},
{
name: "通过",
value: "tg"
},
{
name: "退回",
value: "th"
}
],
value: ""
},
],
}
},
// 页面滚动时监听
onPageScroll(e) {
//调用子组件方法
this.$refs.drawerSearch.fun_TopData(e.scrollTop);
},
// 自定义方法
methods: {
/**
* @param {Object} e 传递的数据
* 查询方法
*/
fun_OnSearch(e) {
// 这里是点击查询时间返回输入的值
console.log(e);
// 根据项目需求要做的处理 例如 清空原有数据、还原分页、重新请求参数
},
/**
* 重置方法
*/
fun_Reset(){
// 点击重置时需要处理...
}
}
}