uni-app商城中的搜索功能

这篇具有很好参考价值的文章主要介绍了uni-app商城中的搜索功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 一、效果图

uniapp实现搜索功能,uniapp,vue,uni-app

二、代码

首先由首页顶部的搜索跳转到真正的搜索页面,输入内容后回车即可完成搜索(假数据,无请求数据 )

uniapp实现搜索功能,uniapp,vue,uni-app

 ① 首页布局文章来源地址https://www.toymoban.com/news/detail-517033.html

<template>
	<view class="index">
		<view class="index_header">
			<view class="header_search u-flex" @click="goSearch('/pages/search/search')">
				<image src="@/static/icon/search.png"></image>
				<swiper :indicator-dots="false" autoplay :interval="3000" :duration="200" vertical circular>
					<swiper-item class="u-flex" v-for="(item, index) in searchHotWords" :key="index">
						<text>{{ item.queryName }}</text>
					</swiper-item>
				</swiper>
			</view>
		</view>
		<!-- 轮播图 -->
		<view class="banner_main">
			<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
				<swiper-item class="swiper_item" v-for="(item, index) in swiperList" :key="item.id">
					<image :src="item.image_url"></image>
				</swiper-item>
			</swiper>
		</view>
		<!-- 精品内容 -->
		<view class="index_boutique">
			<view class="boutique_title">
				<view class="title_name">精选品牌</view>
				<view class="title_more">更多<text decode="true">{{`&gt;`}}</text> </view>
			</view>
			<view class="boutique_flex">
				<view class="flex_item" v-for="(item,index) in boutiqueData" :key="index">
					<image :src="item.icon"></image>
					<text>{{item.name}}</text>
				</view>
			</view>
		</view>
		<!-- 秒杀内容 -->
		<view class="index_goodsSeckill" v-for="(item,index) in 2" :key="index">
			<view class="goodsSeckill_title">
				<view>精品好货限时秒杀</view>
				<view>更多<text decode="true">{{`&gt;`}}</text> </view>
			</view>
			<scroll-view scroll-x="true" class="scroll_x">
				<view class="group">
					<view class="group_item" v-for="(item,index) in groupData" :key="index">
						<image :src="item" ></image>
					</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>
<script>
	export default {
		data() {
			return {
				searchHotWords: [], //上下轮播
				swiperList: [
					{
						id: 0,
						image_url: 'https://img1.baidu.com/it/u=3607749763,1307051166&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=395'
					},
					{
						id: 1,
						image_url: 'https://img2.baidu.com/it/u=3787232916,2002133981&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=330'
					},
					{
						id: 2,
						image_url: 'https://img1.baidu.com/it/u=1747903847,3582374480&fm=253&fmt=auto&app=138&f=JPEG?w=640&h=340'
					},
				],
				boutiqueData:[
					{
						name:'最新产品',
						icon:'https://img2.baidu.com/it/u=985455910,26809051&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
					},
					{
						name:'商城优惠',
						icon:'https://img0.baidu.com/it/u=3121986855,4254644576&fm=253&fmt=auto&app=138&f=JPEG?w=192&h=192'
					},
					{
						name:'耐克',
						icon:'https://img2.baidu.com/it/u=1448619545,1082052059&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889'
					},
					{
						name:'匡威',
						icon:'https://img0.baidu.com/it/u=3829531841,2525898258&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888'
					},
					{
						name:'安踏',
						icon:'https://img2.baidu.com/it/u=2638020669,1516398200&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
					},
					{
						name:'特步',
						icon:'https://img2.baidu.com/it/u=565884609,3441124675&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200'
					},
					{
						name:'回力',
						icon:'https://img1.baidu.com/it/u=3541707458,1538767806&fm=253&fmt=auto&app=138&f=JPEG?w=325&h=260'
					},
					{
						name:'安德玛',
						icon:'https://img0.baidu.com/it/u=3641495928,1121782624&fm=253&fmt=auto&app=120&f=JPEG?w=550&h=597'
					},
					{
						name:'更多',
						icon:'https://img2.baidu.com/it/u=277836883,1911262877&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
					}
				],	
				groupData:[
					'https://ecmb.bdimg.com/tam-ogel/-2064240070_1019900854_300_200.jpg',
					'https://ecmb.bdimg.com/tam-ogel/-1695554568_836595986_300_200.jpg',
					'https://ecmb.bdimg.com/tam-ogel/472596168_-952405378_300_200.jpg',
					'http://t14.baidu.com/it/u=1046111119,3304410177&fm=224&app=112&f=JPEG?w=500&h=500',
					'http://t15.baidu.com/it/u=2301462117,1422483236&fm=224&app=112&f=JPEG?w=500&h=500'
				]
			}
		},
		onLoad() {
			this.getHotWords()
		},
		methods: {
			getHotWords() {
				uni.request({
					url: 'https://api.tian-x.cn/api/Search/placeHolder',
				}).then(res => {
					console.log('res', res[1].data.data);
					if (res[1].data.data.length != 0) {
						this.searchHotWords = res[1].data.data
					} else {
						this.searchHotWords.push({
							queryName: '搜一搜'
						})
					}
				})
			},
			// 跳转搜索页
			goSearch(url) {
				uni.navigateTo({
					url
				})
			}
		}
	}
</script>

<style lang="less">
	page {
		background-color: #F7F7F7;
	}

	.u-flex {
		display: flex;
		flex-direction: row;
		align-items: center;
	}

	.index {
		.index_header {
			padding: 0 20rpx;
			.header_search {
				background-color: rgba(255, 255, 255, 0.7);
				border-radius: 30rpx;
				color: #aaa;
				font-size: 26rpx;
				padding-left: 20rpx;
				height: 64rpx;
				flex: 1;
				image {
					width: 32rpx;
					height: 32rpx;
					margin: 0 20rpx 0 30rpx;
				}
				swiper {
					height: 100%;
					width: 60%;
				}
			}
		}
		.banner_main {
			padding: 20rpx;
			swiper {
				width: 100%;
				height: 300rpx;
				border-radius: 12rpx;
				overflow: hidden;
				.swiper_item{
					image{
						border-radius: 12rpx;
						width: 100%;
						height: 100%;
					}
				}
			}
		}
		.index_boutique{
			margin: 10rpx 20rpx 0;
			padding: 18rpx 20rpx 40rpx 22rpx;
			box-sizing: border-box;
			background: #FFFFFF;
			border-radius: 20rpx;
			.boutique_title{
				display: flex;
				justify-content: space-between;
				.title_name{
					font-size: 30rpx;
					font-weight: bold;
					color: #333333;
				}
				.title_more{
					font-size: 24rpx;
					color: #333333;
				}
			}
			.boutique_flex{
				margin-top: 20rpx;
				display: flex;
				flex-wrap: wrap;
				.flex_item{
					margin-top: 60rpx;
					display: flex;
					flex-direction: column;
					align-items: center;
					width: 20%;
					image{
						width: 58rpx;
						height: 41rpx;
					}
					text{
						margin-top: 16rpx;
						font-size: 24rpx;
						font-weight: normal;
						color: #333333;
					}
				}
			}
		}
		.index_goodsSeckill{
			margin: 25rpx 20rpx 0;
			padding: 20rpx 19rpx 50rpx 21rpx;
			height: 346rpx;
			background: #FFFFFF;
			border-radius: 20rpx;
			.goodsSeckill_title{
				display: flex;
				justify-content: space-between;
				view:first-child{
					font-size: 30rpx;
					font-weight: bold;
					color: #333333;
				}
				view:last-child{
					font-size: 24rpx;
					color: #333333;
				}
			}
			.scroll_x{
				margin-top: 28rpx;
				box-sizing: border-box;
				.group{
					white-space: nowrap;
					.group_item{
						width: 220rpx;
						height: 220rpx;
						display: inline-block;
						margin-right: 10rpx;
						image{
							border-radius: 14rpx;
							width: 220rpx;
							height: 220rpx;
						}
					}
				}
			}
		}
	}
</style>

② 搜索页面布局

<template>
	<view>
		<view class="search">
			<view class="search_box">
				<image src="@/static/icon/search.png"></image>
				<input type="text" confirm-type="search" v-model="keyword" @confirm="searchClick(key)" @input="changeInput" :placeholder="defaultKeyword" />
				<image src="@/static/icon/del_text.png" v-show="keyword" @click="delKeyword()"></image>
			</view>
			<view class="search_btn" @click="searchClick(key)">搜索</view>
		</view>
		<view class="bottom">
			<!-- 搜索关键词列表 -->
			<view class="keyword-list-box" v-show="keywordList">
				<view class="keyword-entry" hover-class="keyword-entry-tap" v-for="(item,idx) in keywordList" :key="idx" @click="searchClick(keyword)">
					<image src="@/static/icon/search.png"></image>
					<rich-text :nodes="item.htmlStr"></rich-text>
				</view>
			</view>
			<!-- 历史记录+热搜词汇 -->
			<view v-if="keywordList.length == 0">
				<view class="history">
					<view class="title">
						<text>历史记录</text>
						<image src="@/static/icon/del.png" @click="oldDelete()"></image>
					</view>
					<view v-if="oldKeywordList.length>0">
						<view class="item_box">
							<view class="item" v-for="(keyword, index) in oldKeywordList" @tap="searchClick(keyword)" :key="index">{{ keyword }}</view>
						</view>
					</view>
					<view v-else style="font-size: 26rpx; color: #ccc;">暂无搜索记录</view>
				</view>
				<view class="hot">
					<view class="title"><text>搜索发现</text></view>
					<view class="item_box">
						<view class="item" v-for="(item, index) in hotWords" :key="index" @click="searchClick(item.queryName)">
							<image src="@/static/icon/hot.png" v-if="item.hot"></image>
							<text>{{ item.queryName }}</text>
						</view>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			keyword: '',
			defaultKeyword: '',
			oldKeywordList: [], //历史记录数据
			keywordList: [],
			searchTimer: null,
			hotWords: []
		}
	},
	onLoad(e) {
		this.loadOldKeyword() //进来页面先在缓存取值
		this.getHotWords()
		if (e.key) {
			this.keyword = e.key
		}
	},
	methods: {
		// 获取最近搜索热词
		getHotWords() {
			uni.request({
				url:'' //请求搜索的热词
			}).then(res=> {
				// 模拟的数据
				let mockData = [
					{
						queryName:'音响',
						querySubType:99,
						queryType:9
					},
					{
						queryName:'高压锅',
						querySubType:99,
						queryType:9
					},
					{
						queryName:'电脑',
						querySubType:99,
						queryType:9
					},
					{
						queryName:'电视',
						querySubType:99,
						queryType:9
					},
					{
						queryName:'笔记本',
						querySubType:99,
						queryType:9
					}
				]
				this.hotWords = mockData
				// this.hotWords = res.data  请求到的数据
				this.getRandomKeyword()
			})
		},
		// 获取随机热词填入输入框
		getRandomKeyword() {
			const random = Math.floor(Math.random() * this.hotWords.length)
			this.defaultKeyword = this.hotWords[random].queryName
		},
		// 删除input输入的内容
		delKeyword() {
			this.keyword = ''
			this.keywordList = []
		},
		loadOldKeyword() {
			uni.getStorage({
				key: 'OldKeys',
				success: res => {
					let OldKeys = JSON.parse(res.data)
					this.oldKeywordList = OldKeys
				}
			})
		},
		// 删除历史记录
		oldDelete() {
			uni.showModal({
				title: '删除',
				content: '确定删除历史搜索记录吗?',
				confirmColor: '#c30d23',
				success: res => {
					if (res.confirm) {
						console.log('用户点击确定')
						this.oldKeywordList = []
						uni.removeStorage({
							key: 'OldKeys'
						})
					} else if (res.cancel) {
						console.log('用户点击取消')
					}
				}
			})
		},
		// input事件
		changeInput() {
			if (!this.keyword) {
				this.keywordList = []
				return
			}
			// input的防抖
			this.$u.debounce(() => {
				uni.request({
					url:'https://api.tian.cn/api/Search/suggest?query='+ this.keyword
				}).then(res=> {
					let words = res[1].data.data
			
					if (words.length != 0) {
						this.keywordList = this.drawCorrelativeKeyword(words, this.keyword)
					}
				})
			}, 200)
		},
		// 高亮显示关键词
		drawCorrelativeKeyword(keywords, keyword) {
			var len = keywords.length,
				keywordArr = []
			for (var i = 0; i < len; i++) {
				var row = keywords[i]
				//定义高亮#9f9f9f
				var html = row.queryName.replace(keyword, "<span style='color: #9f9f9f;'>" + keyword + '</span>')
				html = '<div>' + html + '</div>'
				var tmpObj = {
					keyword: row.word,
					htmlStr: html
				}
				keywordArr.push(tmpObj)
			}
			return keywordArr
		},
		searchClick(key) {
			console.log('key============',key);
			key = key ? key : this.keyword ? this.keyword : this.defaultKeyword
			this.keyword = key
			this.saveKeyword(key) //保存为历史
			uni.navigateTo({
				url: '/pages/goodsList/goodsList?key=' + key
			})
		},
		// 保存为历史记录
		saveKeyword(keyword) {
			uni.getStorage({
				key: 'OldKeys',
				success: res => {
					let OldKeys = JSON.parse(res.data)
					let findIndex = OldKeys.indexOf(keyword)
					if (findIndex == -1) {
						OldKeys.unshift(keyword)
					} else {
						OldKeys.splice(findIndex, 1)
						OldKeys.unshift(keyword)
					}
					//最多10个纪录
					OldKeys.length > 10 && OldKeys.pop()
					uni.setStorage({
						key: 'OldKeys',
						data: JSON.stringify(OldKeys)
					})
					this.oldKeywordList = OldKeys //更新历史搜索
				},
				fail: e => {
					var OldKeys = [keyword]
					uni.setStorage({
						key: 'OldKeys',
						data: JSON.stringify(OldKeys)
					})
					this.oldKeywordList = OldKeys //更新历史搜索
				}
			})
		}
	}
}
</script>

<style lang="scss">
.search {
	display: flex;
	align-items: center;
	height: 120rpx;
	padding-bottom: 30rpx;
	background-color: #f7f7f7;
	font-size: 26rpx;
	& > image {
		width: 18rpx;
		height: 31rpx;
		margin-left: 53rpx;
	}
	.search_box {
		display: flex;
		align-items: center;
		width: 600rpx;
		height: 60rpx;
		background-color: #ffffff;
		// box-shadow: 2rpx 2rpx 2rpx red;
		border-radius: 30rpx;
		margin: 0 12rpx 0 25rpx;
		padding-left: 18rpx;
		image:nth-child(1) {
			margin: 0 18rpx 0 7rpx;
			width: 28rpx;
			height: 28rpx;
		}
		image:nth-child(3) {
			margin: 0 14rpx 0 auto;
			width: 31rpx;
			height: 31rpx;
		}
		input {
			height: 60rpx;
			// letter-spacing: 4rpx;
			line-height: 60rpx;
			color: #969696;
		}
	}
	.search_btn {
		width: 96rpx;
		height: 52rpx;
		background-color: #fff;
		color: pink;
		border-radius: 26rpx;
		line-height: 52rpx;
		text-align: center;
	}
}
.bottom {
	margin-top: -10rpx;
	border-radius: 24rpx 24rpx 0 0;
	background-color: #ffffff;
	overflow: hidden;
	// padding: 34rpx 36rpx 0;
}

.hot,
.history {
	margin: 34rpx 0;
	padding: 0 36rpx;
}
.history {
	margin-bottom: 68rpx !important;
}
.title {
	display: flex;
	align-items: center;
	font-size: 30rpx;
	color: #262626;
	font-family: Pingfang-Bold;
	margin-bottom: 34rpx;
	font-weight: bold;
	image {
		width: 25rpx;
		height: 28rpx;
		margin: 0 6rpx 0 auto;
	}
}
.item_box {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	font-size: 26rpx;
	.item {
		display: flex;
		align-items: center;
		height: 48rpx;
		margin: 0 24rpx 24rpx 0;
		padding: 0 24rpx;
		line-height: 48rpx;
		border-radius: 24rpx;
		color: #333333;
		background-color: #f4f4f4;
		image {
			margin-right: 8rpx;
			width: 21rpx;
			height: 26rpx;
		}
	}
}
.keyword-list-box {
	position: fixed;
	top: 120rpx;
	width: 750rpx;
	background-color: #fff;
	z-index: 1;
}
.keyword-entry-tap {
	background-color: #eee;
}
.keyword-entry {
	display: flex;
	align-items: center;
	height: 80rpx;
	font-size: 26rpx;
	color: #333;
	padding: 0 30rpx;
	border-bottom: solid 1rpx #f7f7f7;
	image {
		width: 29rpx;
		height: 30rpx;
		margin-right: 30rpx;
	}
	text {
		margin-left: auto;
		color: #777;
		font-size: 22rpx;
	}
}
</style>

③ 商品列表页布局

<template>
	<view class="goodsList">
		<view class="header u-flex">
			<view class="search-box u-flex" @click="goToSearch(queryName)">
				<view class="keyword u-flex" v-if="queryName != ''">
					<text>{{ queryName }}</text>
					<image src="@/static/icon/close_white.png" @click.stop="goToSearch()"></image>
				</view>
			</view>
			<!-- 右侧的菜单切换 -->
			<image class="toggle-icon"
				:src="isShowMenu == 'card' ? '../../static/icon/arrange_list_black.png' : '../../static/icon/arrange_cell_black.png'"
				@click="switchMenu"></image>
		</view>
		<!-- tab切换 -->
		<view class="tabs_main u-flex">
			<view class="item">
				<view @click="tabsPop = true" class="u-flex"
					:style="{ color: tabs_id == 0 || tabs_id == 8 ? '#BF1111' : '#333' }">
					<text>{{ tabs_id == 0 ? '综合' : '销量' }}</text>
					<u-icon name="arrow-down" :color="tabs_id == 0 || tabs_id == 8 ? '#BF1111' : '#333' "></u-icon>
				</view>
				<u-popup :show="tabsPop" mode="top" round="16" @close="tabsPop=false">
					<view class="sort-rule u-flex-col">
						<view class="u-flex" :style="{ color: tabs_id == 0 ? '#BF1111' : '#333' }"
							@click="sortClick(0), (tabsPop = false)">
							<text>综合排序</text>
							<u-icon v-if="tabs_id == 0" name="checkmark" :color="tabs_id ==0 ? '#BF1111':'#333'">
							</u-icon>
						</view>
						<view class="u-flex" :style="{ color: tabs_id == 8 ? '#BF1111' : '#333' }"
							@click="sortClick(8), (tabsPop = false)">
							<text>销量排序</text>
							<u-icon v-if="tabs_id == 8" name="checkmark"></u-icon>
						</view>
					</view>
				</u-popup>
			</view>
			<view class="item" @click="sortClick(7)" :style="{ color: tabs_id == 7 ? '#BF1111' : '#333' }">新品</view>
			<view class="item" @click="sortClick(3)"
				:style="{ color: tabs_id == 1 || tabs_id == 2 ? '#BF1111' : '#333' }">
				<view class="u-flex">
					<text>价格</text>
					<u-icon :name="tabs_id == 1 ?'arrow-down':'arrow-up'"
						:color=" tabs_id == 1 || tabs_id == 2 ? '#BF1111' : '#333' "></u-icon>
				</view>

			</view>
			<view class="item" @click="sortClick(6)" :style="{ color: tabs_id == 6 ? '#BF1111' : '#333' }">信用</view>
			<view class="item">
				<view class="u-flex" @click="screenPop = true" :style="{ color: filterColor }">
					<text>筛选</text>
					<u-icon name="list-dot" size="20"></u-icon>
				</view>
				<!-- 筛选弹出层 -->
				<u-popup :show="screenPop" @close="screenPop=false" mode="right" :duration="600">
					<scroll-view scroll-y class="filterPopup">
						<view class="services">
							<view class="services-title u-flex">
								<view class="title">折扣与服务</view>
							</view>
							<view class="list u-flex">
								<text :class="{ active: isActive(item, 'services') }" v-for="(item, index) in services"
									:key="index" @click="paramsFilter(item, 'services')">
									{{ item.name }}
								</text>
							</view>
						</view>
						<view class="services">
							<view class="services-title u-flex">
								<view class="title">价格区间</view>
							</view>
							<view class="price-box u-flex">
								<input type="text" placeholder="最低价" v-model.number="filter.minPrice"
									@blur="getGoodsList" />
								<text>-</text>
								<input type="text" placeholder="最高价" v-model.number="filter.maxPrice"
									@blur="getGoodsList" />
							</view>
						</view>
						<view class="services">
							<view class="head u-flex">
								<view class="title">分类</view>
							</view>
							<view class="list u-flex">
								<text :class="{ active: isActive(item, 'cateOne') }"
									v-for="(item, index) in screenInfo.cateOne" :key="index"
									@click="paramsFilter(item, 'cateOne')">
									{{ item.name }}
								</text>
							</view>
						</view>
						<view class="services" v-if="screenInfo.brands">
							<view class="head u-flex">
								<view class="title">品牌</view>
							</view>
							<view class="list u-flex">
								<text :class="{ active: isActive(item, 'brands') }"
									v-for="(item, index) in screenInfo.brands" :key="index"
									@click="paramsFilter(item, 'brands')">
									{{ item.name }}
								</text>
							</view>
						</view>
						<view class="services" v-for="(itemm, index) in screenInfo.Product" :key="index">
							<view class="head u-flex">
								<view class="title">{{ itemm.name }}</view>
							</view>
							<view class="list u-flex">
								<text :class="{ active: v.selected }" v-for="(v, i) in itemm.attChildren" :key="i"
									@click="prodFn(itemm, v)">
									{{ v.name }}
								</text>
							</view>
						</view>
					</scroll-view>
					<view class="btns u-flex">
						<view class="btn reset u-flex" @click="handleReset">重置</view>
						<view class="btn confirm u-flex" @click="screenPop = false">确定({{ total }}件商品)</view>
					</view>
				</u-popup>
			</view>
		</view>
		<!-- 右上角菜单的切换效果 -->
		<view class="goodslist-card" v-if="isShowMenu == 'card'">
			<view class="item" v-for="(item, index) in goodsList" :key="index">
				<view class="goods-img u-flex">
					<u-image :src="item.goodsInfo.imgs || item.goodsInfo.imgq" :lazy-load="true" width="346rpx"
						height="346rpx"></u-image>
				</view>
				<view class="labelbox">
					<text v-for="(vv, lindex) in item.label.normal" :key="lindex"
						:style="{ backgroundColor: getLabelColor(vv.attrs) }">{{ vv.text }}</text>
				</view>
				<view class="title">{{ item.goodsInfo.name }}</view>
				<view class="subtitle">
					<text
						v-if="!item.goodsInfo.coreSellingPoint || item.goodsInfo.coreSellingPoint.length == 0">{{ item.goodsInfo.summary }}</text>
					<view v-else class="selling-point">
						<text v-for="(sitem, sindex) in item.goodsInfo.coreSellingPoint"
							:key="sindex">{{ sitem }}</text>
					</view>
				</view>
				<view class="price">
					<text>¥</text>
					<text class="priceMin">{{ item.goodsInfo.priceMin / 100 }}</text>
					<text class="spec" v-if="item.goodsInfo.priceTag">起</text>
					<text class="marketPrice"
						v-if="item.goodsInfo.priceMin != item.goodsInfo.marketPrice">¥{{ item.goodsInfo.marketPrice / 100 }}</text>
				</view>
				<view class="comment">
					<text>{{ item.goodsInfo.comment.count > 100000 ? '10万+' : item.goodsInfo.comment.count }}条评论</text>
					<text
						v-if="item.goodsInfo.comment.positiveRate > 0">{{ item.goodsInfo.comment.positiveRate }}%好评</text>
				</view>
			</view>
		</view>
		<!-- 切换为列表视图 -->
		<view class="goodslist-list" v-if="isShowMenu == 'list'">
			<view class="item u-flex" v-for="(item, index) in goodsList" :key="index"
				@click="goToDetail(item.data.goodsInfo.gid)">
				<view class="u-flex">
					<u-image width="252rpx" height="252rpx" :src="item.goodsInfo.imgs || item.goodsInfo.imgq"
						:lazy-load="true"></u-image>
				</view>
				<view class="content u-flex-col">
					<view class="title u-line-1">{{ item.goodsInfo.name }}</view>
					<view class="subtitle u-line-1">{{ item.goodsInfo.summary }}</view>
					<view class="selling-point" v-if="item.goodsInfo.coreSellingPoint">
						<text v-for="(sitem, sindex) in item.goodsInfo.coreSellingPoint"
							:key="sindex">{{ sitem }}</text>
					</view>
					<view class="price">
						<text>¥</text>
						<text class="priceMin">{{ item.goodsInfo.priceMin / 100 }}</text>
						<text class="spec" v-if="item.goodsInfo.priceTag">起</text>
						<text class="marketPrice"
							v-if="item.goodsInfo.priceMin != item.goodsInfo.marketPrice">¥{{ item.goodsInfo.marketPrice / 100 }}</text>
					</view>
					<view class="labelbox">
						<text v-for="(litem, lindex) in item.label.normal" :key="lindex"
							:style="{ backgroundColor: getLabelColor(litem.attrs) }">{{ litem.text }}</text>
					</view>
					<view class="comment">
						<text>{{ item.goodsInfo.comment.count > 100000 ? '10万+' : item.goodsInfo.comment.count }}条评论</text>
						<text
							v-if="item.goodsInfo.comment.positiveRate > 0">{{ item.goodsInfo.comment.positiveRate }}%好评</text>
					</view>
				</view>
			</view>
		</view>
		<view v-show="showLoadmore">
			<u-loadmore :status="loadingStatus" :margin-top="20" :margin-bottom="40" bg-color="#f9f9f9" :font-size="24"
				:load-text="loadingText" color="#999" />
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				total: 0, //总商品数
				pageIdx: 0, //页数
				loadingStatus: 'loadmore',
				loadingText: {
					loadmore: '上拉加载更多',
					loading: '努力加载中~',
					nomore: '我也是有底线的'
				},
				queryName: '洗衣机',
				isShowMenu: 'card',
				queryID: '',
				tabsPop: false, //综合销量的弹出层
				tabs_id: 0,
				screenPop: false, //筛选弹出层
				screenInfo: {
					cateOne: [{
						name: '家电类',
						outIdx: -1,
						outer: false
					}],
					brands: [{
							count: 4,
							name: "小米",
							outer: true,
							outIdx: 4
						},
						{
							count: 5,
							name: "中米",
							outer: true,
							outIdx: 4
						},
						{
							count: 6,
							name: "大米",
							outer: true,
							outIdx: 4
						}
					],
					Product: [{
							name: '产品分类',
							attChildren: [{
									count: 13,
									name: "内衣洗衣机",
									outer: true,
									outIdx: 2
								},
								{
									count: 13,
									name: "迷你洗衣机",
									outer: true,
									outIdx: 2
								},
								{
									count: 13,
									name: "全自动洗衣机",
									outer: true,
									outIdx: 2
								}
							]
						},
						{
							name: '等级分类',
							attChildren: [{
									count: 13,
									name: "一级类别",
									outer: true,
									outIdx: 2
								},
								{
									count: 13,
									name: "二级类别",
									outer: true,
									outIdx: 2
								},
								{
									count: 13,
									name: "三级类别",
									outer: true,
									outIdx: 2
								}
							]
						},
						{
							name: '排水方式',
							attChildren: [{
									count: 13,
									name: "上排水",
									outer: true,
									outIdx: 2
								},
								{
									count: 13,
									name: "下排水",
									outer: true,
									outIdx: 2
								},
							]
						}
					]
				},
				services: [{
						count: 1,
						name: '会员',
						outIdx: -1,
						outer: false
					},
					{
						count: 1,
						name: '预售',
						outIdx: -1,
						outer: false
					},
					{
						count: 1,
						name: '包邮',
						outIdx: -1,
						outer: false
					}
				],
				filter: {
					attr: [],
					brands: [],
					cateOne: [],
					category2: [],
					category3: [],
					maxPrice: null,
					minPrice: null,
					services: [],
					special: [],
					specialCoupon: [],
					tags: []
				},
				filterColor: '#333',
				goodsList: [{
						goodsInfo: {
							name: '我是商品的标题',
							imgs: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
							imgq: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
							coreSellingPoint: [],
							summary: '我是商品的小标题',
							priceMin: 2000,
							priceTag: 300,
							marketPrice: 0,
							comment: {
								count: 3600,
								positiveRate: 100
							}
						},
						label: {
							normal: [{
								attrs: `{"font":"default","height":42,"width":192,"bgColor":"#000000",
										"imageUrl":"https://img.youpin.mi-img.com/tag/4167059a2a83e6dece26ebc1300abaf8.png?w\u003d192\u0026h\u003d42",
										"jumpUrl":"","priority":6001.0,"displayStatus":1,"fontColor":"#FFFFFF"}`,
								businessId: 0,
								ext: "null",
								labelId: 825,
								labelName: "会员折扣",
								text: "会员折扣",
								type: "sale",
							}, ]
						},
					},
					{
						goodsInfo: {
							name: '我是商品的标题',
							imgs: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
							imgq: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
							coreSellingPoint: [],
							summary: '我是商品的小标题',
							priceMin: 2000,
							priceTag: 300,
							marketPrice: 0,
				 		comment: {
								count: 3600,
								positiveRate: 100
							}
						},
						label: {
				 		normal: [{
								attrs: `{"font":"default","height":42,"width":192,"bgColor":"#000000",
				 						"imageUrl":"https://img.youpin.mi-img.com/tag/4167059a2a83e6dece26ebc1300abaf8.png?w\u003d192\u0026h\u003d42",
				 						"jumpUrl":"","priority":6001.0,"displayStatus":1,"fontColor":"#FFFFFF"}`,
								businessId: 0,
								ext: "null",
								labelId: 825,
								labelName: "会员折扣",
								text: "会员折扣",
								type: "sale",
							}, ]
				 	},
					},
				],
			}
		},
		onLoad(e) {
			this.queryName = e.key
			this.getGoodsList()
		},
		computed: {
			showLoadmore() {
				return this.goodsList.length !== 0 ? true : false
			}
		},
		onReachBottom() {
			if (this.pageIdx < this.total) {
				// this.getGoodsList('more')
				this.loadingStatus = 'loading'
			} else {
				this.loadingStatus = 'nomore'
			}
		},
		methods: {
			getLabelColor(str) {
				console.log(str, 'str=============');
				return str.substr(str.indexOf('#'), 7)
			},
			getGoodsList() { //获取商品数据
			},
			// 切换右侧菜单
			switchMenu() {
				this.isShowMenu == 'card' ? this.isShowMenu = 'list' : this.isShowMenu = 'card'
			},
			sortClick(id) {
				// 当点击筛选ID和目前列表的筛选ID一致时,不请求数据,节省流量
				if (id == this.tabs_id) return
				switch (id) {
					case 3:
						switch (this.tabs_id) {
							case 1:
								this.tabs_id = 2
								console.log('降序排列')
								break
							case 2:
								this.tabs_id = 1
								console.log('升序排列')
								break
							default:
								this.tabs_id = 2
								console.log('降序排列')
						}
						break
					default:
						this.tabs_id = id
				}
				// this.goodsList = []
				// this.pageIdx = 0
				// this.sortLoading = true
				// this.getGoodsList()
			},
			isActive(item, type) {
				console.log('item', item);
				console.log('type', type);
				if (this.filter[type].indexOf(item.name) == -1) {
					return false
				} else {
					return true
				}
			},
			paramsFilter(item, type) {
				if (this.filter[type].indexOf(item.name) == -1) {
					this.filter[type].push(item.name)
				} else {
					this.filter[type].splice(this.filter[type].indexOf(item.name), 1)
				}
				this.filterColor = '#BF1111'
				// this.getGoodsList()
			},
			prodFn(item, v) {
				console.log('item', item)
				console.log('v', v)
				let result = []
				item.attChildren.some((vv, i) => {
					if (vv.name == v.name) {
						if (!vv.selected) {
							this.$set(vv, 'selected', true)
						} else {
							vv.selected = false
						}
					}
					if (vv.selected) {
						result.push(vv)
					} else {
						result.splice(i, 1)
					}
				})
				// console.log('result',result)
				let str = []
				result.forEach(x => {
					str.push(x.name)
				})
				// console.log(str)
				let obj = {
					name: item.name,
					attrValue: []
				}
				// console.log(obj)
				let flag = true
				this.filter.attr.forEach(item => {
					if (item.name === obj.name) {
						// 对象里的唯一标识name
						flag = false
					}
				})
				if (flag) {
					this.filter.attr.push(obj)
				}
				this.filter.attr.forEach((x, i) => {
					if (x.name == item.name) {
						x.attrValue = str
					}
					if (x.attrValue.length == 0) {
						this.filter.attr.splice(i, 1)
					}
				})

				this.filterColor = '#BF1111'
				this.getGoodsList()
			},
			// 弹框重置按钮
			handleReset() {
				Object.assign(this.$data.filter, this.$options.data().filter)
				this.screenInfo.Product.forEach(x => {
					x.attChildren.forEach(s => {
						s.selected = false
					})
				})
				this.filterColor = '#333'
				this.getGoodsList()
			},
			goToSearch(key) {
				if (key) {
					uni.redirectTo({
						url: '../search/search?key=' + key
					})
				} else {
					uni.redirectTo({
						url: '../search/search'
					})
				}
			},
		}
	}
</script>

<style lang="less">
	.u-flex {
		display: flex;
		align-items: center;
		flex-direction: row;
	}

	.u-flex-col {
		display: flex;
		flex-direction: column;
	}

	page {
		background-color: #f7f7f7;
	}

	.goodsList {

		.header,
		.tabs_main {
			position: fixed;
			width: 750rpx;
			font-size: 26rpx;
			background-color: #f7f7f7;
			z-index: 1080;
		}

		.header {
			top: 0;
			justify-content: space-between;
			// padding: 0 20rpx;
			height: 60rpx;

			.search-box {
				flex: 1;
				padding-left: 18rpx;
				height: 60rpx;
				background-color: #ffffff;
				border-radius: 30rpx;

				.keyword {
					padding: 2rpx 16rpx;
					color: #fff;
					border-radius: 30rpx;
					background-color: rgb(153, 153, 153);

					image {
						width: 32rpx;
						height: 32rpx;
					}
				}
			}

			.toggle-icon {
				width: 64rpx;
				height: 64rpx;
			}
		}

		.tabs_main {
			top: 60rpx;
			height: 80rpx;
			color: #333333;

			.item {
				display: flex;
				align-items: center;
				justify-content: center;
				width: 20%;
				height: inherit;

				&>view {
					width: 100%;
					height: inherit;
					justify-content: center;
				}

				u-icon {
					margin-left: 4rpx;
				}

				.sort-rule {
					justify-content: space-around;
					padding: 10rpx 24rpx;
					height: 160rpx;
					background-color: #f7f7f7;

					&>view {
						justify-content: space-between;
					}
				}

				.filterPopup {
					height: 92%;

					// padding: 10rpx 0;
					.services {
						margin-bottom: 20rpx;
						padding: 0 20rpx;

						.services-title {
							justify-content: space-between;
							height: 60rpx;
							font-size: 28rpx;
							color: #555;

							.title {
								font-weight: bold;
							}

							.all {
								color: #999;
								font-size: 22rpx;
							}
						}

						.list {
							flex-wrap: wrap;
							margin-top: 10rpx;

							text {
								margin: 0 16rpx 20rpx 0;
								padding: 0 10rpx;
								height: 52rpx;
								width: 176rpx;
								max-width: 176rpx;
								font-size: 24rpx;
								line-height: 51rpx;
								text-align: center;
								border-radius: 26rpx;
								background-color: rgb(244, 244, 244);
								overflow: hidden;
								white-space: nowrap;
								text-overflow: ellipsis;
								border: 1rpx solid rgb(244, 244, 244);
							}

							text:nth-child(3n) {
								margin-right: 0;
							}

							.active {
								color: #bf1111;
								border: 1rpx solid rgb(191, 17, 17);
								background-color: rgb(246, 237, 237);
							}
						}

						.price-box {
							justify-content: space-between;
							margin-top: 10rpx;

							input {
								height: 52rpx;
								width: 240rpx;
								margin-bottom: 20rpx;
								text-align: center;
								border-radius: 26rpx;
								background-color: rgb(244, 244, 244);
							}

							text {
								margin-bottom: 20rpx;
							}
						}
					}
				}

				.btns {
					justify-content: space-around;
					height: 8%;

					// background-color: #EEEEEE;
					.btn {
						justify-content: center;
						height: 80%;
						width: 46%;
						border-radius: 60rpx;
					}

					.reset {
						color: rgb(51, 51, 51);
						border: 1rpx solid rgb(204, 204, 204);
					}

					.confirm {
						color: #fff;
						background: linear-gradient(to right, rgb(240, 78, 46), rgb(213, 16, 16));
					}
				}
			}
		}

		.goodslist-card {
			display: flex;
			justify-content: space-between;
			flex-wrap: wrap;
			padding: 0 20rpx;
			margin-top: 140rpx;
			background-color: #f7f7f7;

			.item {
				position: relative;
				width: 346rpx;
				margin-bottom: 24rpx;
				padding-bottom: 20rpx;
				border-radius: 8rpx;
				background-color: #ffffff;
				font-size: 28rpx;
				overflow: hidden;

				.goods-img {
					justify-content: center;
					width: 346rpx;
					height: 346rpx;
					border-radius: 8rpx 8rpx 0 0;
				}

				.labelbox {
					position: absolute;
					top: 308rpx;
					left: 0;

					text {
						display: inline-block;
						border-radius: 2rpx;
						color: #ffffff;
						margin-right: 10rpx;
						text-align: center;
						height: 32rpx;
						padding: 0 10rpx;
						line-height: 32rpx;
						font-size: 24rpx;
					}
				}

				.title,
				.subtitle {
					width: 346rpx;
					padding-left: 16rpx;
					padding-right: 6rpx;
					white-space: nowrap;
					text-overflow: ellipsis;
					-webkit-box-pack: center;
					overflow: hidden;
				}

				.title {
					font-size: 30rpx;
					color: rgb(51, 51, 51);
					line-height: 42rpx;
					margin-top: 6rpx;
				}

				.subtitle {
					font-size: 26rpx;
					color: rgb(153, 153, 153);
					margin-top: 4rpx;
					line-height: 36rpx;

					.selling-point {
						text {
							font-size: 22rpx;
							display: inline-block;
							margin-right: 8rpx;
							padding: 0 12rpx;
							border-radius: 36rpx;
							background-color: rgb(248, 248, 248);
						}
					}
				}

				.price {
					margin-top: 10rpx;
					padding-left: 16rpx;
					color: rgb(227, 13, 13);
					font-size: 26rpx;
					height: 40rpx;
					font-family: 'AllAndNone';

					.priceMin {
						font-size: 34rpx;
						margin-right: 4rpx;
						font-weight: bold;
					}

					.marketPrice {
						margin-left: 6rpx;
						font-size: 24rpx;
						color: #999;
						text-decoration: line-through;
					}

					.spec {
						font-size: 24rpx;
					}
				}

				.comment {
					margin-top: 6rpx;
					padding-left: 16rpx;
					font-size: 22rpx;
					color: #999;

					text {
						margin-right: 12rpx;
					}
				}
			}
		}

		.goodslist-list {
			padding: 0 20rpx;
			margin-top: 140rpx;
			background-color: #fff;
			border-radius: 24rpx 24rpx 0 0;
			overflow: hidden;

			.item {
				margin: 30rpx 0;
				font-size: 28rpx;


				.content {
					height: 252rpx;
					padding: 4rpx 0 2rpx 16rpx;
				}

				.title,
				.subtitle {
					width: 440rpx;
				}

				.title {
					font-size: 28rpx;
					color: #333;
					line-height: 42rpx;
				}

				.subtitle {
					font-size: 24rpx;
					color: rgb(153, 153, 153);
					margin-top: 4rpx;
					line-height: 36rpx;
				}

				.selling-point {
					text {
						display: inline-block;
						margin-right: 8rpx;
						padding: 0 12rpx;
						font-size: 22rpx;
						color: #999;
						border-radius: 36rpx;
						background-color: rgb(248, 248, 248);
					}
				}

				.price {
					margin-top: auto;
					color: rgb(227, 13, 13);
					font-size: 26rpx;
					height: 40rpx;
					font-family: 'AllAndNone';

					.priceMin {
						font-size: 34rpx;
						margin-right: 4rpx;
						font-weight: bold;
					}

					.marketPrice {
						margin-left: 6rpx;
						font-size: 24rpx;
						color: #999;
						text-decoration: line-through;
					}

					.spec {
						font-size: 24rpx;
					}
				}

				.labelbox {
					text {
						display: inline-block;
						border-radius: 4rpx;
						color: #ffffff;
						margin-right: 10rpx;
						text-align: center;
						height: 32rpx;
						padding: 0 10rpx;
						line-height: 32rpx;
						font-size: 24rpx;
					}
				}

				.comment {
					margin-top: 6rpx;
					font-size: 22rpx;
					color: #999;

					text {
						margin-right: 12rpx;
					}
				}
			}
		}
	}
</style>

 

到了这里,关于uni-app商城中的搜索功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【uni-app】uni-app实现聊天页面功能——功能篇(上)

    上一篇讲到了如何布局,这一篇将讲一下如何用uni-app实现小程序聊天页面的最主要的功能——发消息后页面滚动到最底部(参考过很多文章最后找到比较适合的方法)。 其他的功能(参考微信),之后的文章会讲述到具体实现方法 点击聊天框的时候,聊天框随键盘抬起且聊

    2024年02月11日
    浏览(64)
  • 【uni-app】uni-app实现聊天页面功能(小程序)——布局篇

    在工作中使用uni-app参与开发一个小程序,其中要写一个简单的聊天页面,虽然功能不多(只有一个发送文字的功能),但是其中的细节比较多,也踩过很多坑,特此记录下来。要实现的页面如图所示,该篇主要讲讲如何布局(参考了很多文章之后根据页面需求进行一个整合)

    2024年02月05日
    浏览(91)
  • 基于uni-app的网购商城小程序设计与实现 毕业设计开题报告

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年02月04日
    浏览(46)
  • uni-app实现图片上传功能

    效果 代码  

    2024年02月13日
    浏览(66)
  • uni-app小程序分享功能实现

    通过onShareAppMessage(OBJECT) 将小程序到分享微信聊天,onShareTimeline()将小程序分享到朋友圈。 api中的参数配置参考文档:https://uniapp.dcloud.net.cn/api/plugins/share.html#onshareappmessage 分为全局引入、单页面引两种方式 全局引入只需要在小程序main.js中引入一次,可以复用,便于维护; 单

    2024年02月05日
    浏览(96)
  • uni-app小程序实现音频播放,uniapp播放录音,uniapp简单实现播放录音

    复制到.vue文件即可预览效果 问题 :开发者工具中.onTimeUpdate方法可能会失效! 官方参考:https://uniapp.dcloud.net.cn/api/media/audio-context.html# 其他博客参考:https://blog.csdn.net/weixin_45328705/article/details/114091301 录音实现参考 :https://blog.csdn.net/weixin_43992507/article/details/129857780

    2024年02月12日
    浏览(73)
  • 【uni-app】通过uni-app基础组件picker实现选择日期、时间的功能示例(完整代码+图文)

    一、获取日期(基础) 二、获取日期和时间(改进)  

    2024年02月11日
    浏览(54)
  • 【uni-app微信小程序】实现支付功能

    实现微信支付功能需要在小程序后台配置支付相关信息,并且在前端代码中调用微信支付API进行支付操作。好的, uni-app微信小程序实现支付功能整体流程 大致如下: 注册微信公众平台,并完成开发者资质认证; 在微信商户平台注册商户账号,并完成商户资质认证; 在商户

    2024年02月13日
    浏览(95)
  • 【uni-app2.0】实现登录页记住密码功能

    使用uni-app的 uni.setStorageSync() 和 uni.getStorageSync() 方法来存储和读取密码 在登录页中添加一个记住密码的 u-checkbox 选项,并在data里面添加一个 rememberPwd 的布尔值,在每次点击记住密码 change 的时候来记录用户的选择 在点击登录按钮执行的事件中,使用 uni.setStorageSync() 方法将【

    2024年02月15日
    浏览(54)
  • uni-app实现 app 小程序 手机端H5扫码功能

    首先 扫码这个功能小程序和App都是有现成的方法 但是H5是不行的 我们可以看这样一段代码 这里 我们用了条件编译 App和小程序中的代码是 一样的 他们都可以正常执行scanCode进行扫码 至于H5手机端界面 我用web-view套了个百度的链接进来 其实 大家可以参考我的文章 vue实现二维

    2024年02月11日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包