uniApp封装查询组件

介绍

在开发微信小程序时总会遇到需要查询的,每有一个页面需要查询时就要写,这样写太浪费时间,自己直接封装一个,当需要查询方法的时候,引入这个组件就可以了。

话不多说,上代码!

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(){
            // 点击重置时需要处理...
        }
    }
}

最终效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值