搜索页_封装搜索组件 Vue_支持联想模糊搜索_关键词标红

3 篇文章 0 订阅
2 篇文章 0 订阅

search 搜索页

  1. 【搜索页面,界面简洁大气,颜值即正义】
  2. 本地项目引入阿里图标库,小巧的字体文件节省空间
  3. 使用方法:“HBuilderX导入插件”,然后复制参考DEMO的代码
  4. 基于 Vue 、uniapp 开发,支持微信小程序、H5 等
    在这里插入图片描述
    在这里插入图片描述

插件地址

https://ext.dcloud.net.cn/plugin?id=11898

参考DEMO /components/pages/index

<zhangguangsen-search
	:hotList="hotList"
	:searchList="searchList"
	@onInput="onInput"\
	@onSearchConfirm="onSearchConfirm">
</zhangguangsen-search>
export default {
	data() {
		return {
			hotList:['aa','bb','cc','dd','测试一个超产的龙欧索','aa','bb','cc','dd','测试一个超产的龙欧索'],
			searchList:[]
		}
	},
	mounted(){
	},
	methods: {
		onInput(val){
			console.log('**input',val)
			//模拟后端返回数据,根据val调用接口
			setTimeout(()=>{
				 this.searchList = ['aabacd','bb','cc','dd','测试一个超产的龙欧索','aa',Math.random()]//这里模拟 axios 返回的数据
			},2000)
		},
		onSearchConfirm(searchVal){
			console.log('搜索词',searchVal)
		}
	}
}

组件代码

  • 可复制代码,自己封一个组件;再需要下载插件ZIP,将字体文件引入项目即可;
  • 推荐的用法,还是通过“HBuilderX导入插件”
<view class="search">
	<view class="search-head">
		<view class="head-icon__search iconfont icon-sousuo1"></view>
		<view class="head-input__search">
			<input v-model="val" :focus="true" :adjustPosition="false" placeholder="请输入配件名称" placeholder-class="head-input__placeholder" confirmType="搜索" :confirmHold="false" @input="handleInput" @click="handleClick" @confirm="handleConfirm"/>
			<button @click="handleConfirm">搜索</button>
		</view>
	</view>
	<view class="hotSearch">
		<view class="hotSearch-head">
			<view class="hotSearch-icon__hot iconfont icon-remensousuo"></view>
			<text class="hotSearch-text__hot">
				 热门搜索
			</text>
		</view>
		<view class="hotSearch-list">
			<view class="hotSearch-li" v-for="(item,index) in hotList" :key="index" @click="handleConfirm(item)">
				{{item}}
			</view>
		</view>
	</view>
	<view v-show="showPop">
		<view class="pop-search__list">
			<view class="pop-search__li" v-for="(item,index) in formatSearchList" :key="index" @click="handleConfirm(item)">
				<text v-for="(titem,tindex) in item" :key="tindex" :class="titem.key ? 'active' : ''">{{titem.str}}</text>
			</view>
		</view>
		<view class="pop-search__mask" @click="showPop=false"></view>
	</view>
</view>
props:{
	hotList:{
		type:Array
	},
	searchList:{
		type:Array
	}
},
watch:{
	searchList:{
		handler(searchList){
			uni.hideLoading();
			console.log('watch',searchList)
			if(searchList.length>0 && this.val){
				this.formatSearchList = searchList.map(item=>this.hilight_word(this.val, item))
			}
		},
		deep:true
	}
},
data() {
	return {
		val:'',
		showPop:false,
		formatSearchList:[]
	}
},
mounted(){
},
methods: {
	handleConfirm(val){
		let searchVal = val
		if(Array.isArray((val))){
			searchVal = val.map(({str})=>str).join('')
		}else if(val instanceof Object){
			searchVal = this.val
		}
		this.$emit('onSearchConfirm',searchVal)
	},
	handleClick(){
		this.showPop = !!this.val
	},
	handleInput(e){
		this.showPop = !!this.val
		if(!this.val) {
			return
		}
		uni.showLoading({
			title: '加载中'
		});
		setTimeout(()=>uni.hideLoading(),3000)
		this.$emit('onInput',this.val)
	},
	// 根据搜索字分割字符
	hilight_word: function (key, word) {
		key=key.trim()
		word=''+word
		let idx = word.indexOf(key), t = [];
	 
		if (idx > -1) {
		  if (idx == 0) {
			t =this.hilight_word(key, word.substr(key.length));
			t.unshift({ key: true, str: key });
			return t;
		  }
	 
		  if (idx > 0) {
			t =this.hilight_word(key, word.substr(idx));
			t.unshift({ key: false, str: word.substring(0, idx) });
			return t;
		  }
		}
		return [{ key: false, str: word }];
	}
}
<style lang="scss">
@font-face {
  font-family: "iconfont"; /* Project id 3928599 */
  src: url('@/static/zhangguangsen-search/zhangguangsen-search.woff2?t=1681960188787') format('woff2'),
       url('@/static/zhangguangsen-search/zhangguangsen-search.woff?t=1681960188787') format('woff'),
       url('@/static/zhangguangsen-search/zhangguangsen-search.ttf?t=1681960188787') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-remensousuo:before {
  content: "\e73d";
}

.icon-sousuo1:before {
  content: "\e61c";
}

.search{
	background-color: #fff;
	overflow: hidden;
	&-head{
		display: flex;
		align-items: center;
		padding:0 10rpx 0 47rpx;
		margin:30rpx 30rpx 0;
		height: 70rpx;
		background: #F5F5F5;
		border-radius: 35rpx;
		.head-icon__search{
			font-size: 30rpx;
			color: #231815;
		}
		.head-input__search{
			display: flex;
			align-items: center;
			flex: 1;
			input{
				margin-left: 15rpx;
				border: none;
				height: 29rpx;
				font-size: 30rpx;
				font-weight: 400;
				color: #AAAAAA;
				line-height: 28rpx;
				flex:1;
			}
			button{
				width: 128rpx;
				height: 53rpx;
				background: linear-gradient(0deg, #0AA0F5, #00E3F2);
				border-radius: 30rpx;
				font-size: 28rpx;
				font-weight: 500;
				color: #FFFFFF;
				line-height: 42rpx;
			}
			.head-input__placeholder{
				color: #AAAAAA;
			}
		}
	}
	.hotSearch{
		margin-top: 30rpx;
		&-head{
			display: flex;
			align-items: center;
			padding:0 0 0 30rpx;
		}
		&-icon__hot{
			margin-left: 10rpx;
			font-size: 30rpx;
			color: rgb(255,43,57);
		}
		&-text__hot{
			margin-left: 10rpx;
			font-size: 30rpx;
			color: #999999;
		}
		&-list{
			padding: 20rpx 0 50rpx 30rpx;
			display: flex;
			flex-wrap: wrap;
		}
		&-li{
			margin: 10rpx 0 0 10rpx;
			padding: 0 20rpx;
			border-radius: 20rpx;
			background: #f2f2f2;
			line-height: 50rpx;
			&:first-child{
				margin-left: 0;
			}
		}
	}
}
.pop{
	&-search{
		&__mask{
			position: fixed;
			top: 100rpx;
			bottom: 0;
			left: 0;
			right: 0;
			background-color: rgba(0, 0,0,.3);
			z-index: 1;
		}
		&__list{
			padding:0 30rpx;
			position: fixed;
			top: 100rpx;
			left: 0;
			right: 0;
			background-color: #fff;
			z-index: 9;
		}
		&__li{
			font-size: 30rpx;
			color: #231815;
			line-height: 90rpx;
			border-bottom: solid 1px #F5F5F5;
			.active{
				color: red;
			}
		}
	}
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值