5搜索相关功能


一、进入搜索页面

1.1 在pages下创建搜索页面为:search
1.2 在index.vue中点击进入搜素页面

onNavigationBarButtonTap(e){
			if(e.float=='left'){
				uni.navigateTo({
					url:'../search/search'
				})
			}
		},

1.3 在pages.json中配置搜索页面头部

{
            "path" : "pages/search/search",
            "style" : {
				"navigationBarBackgroundColor":"#FFFFFF",
				"app-plus":{
					"scrollIndicator":"none",
					"titleNView":{
						"searchInput":{
							"placeholder":"nike",
							"disabled":false,
							"align":"left",
							"autoFocus":true,
							"borderRadius":"15px",
							"backgroundColor":"#F7F7F7",
							"placeholderColor":"#B3B3B3"
						},
						"buttons":[
							{
								"float":"right",
								"color":"#636263",
								"text":"搜索",
								"fontSize":"16px",
								"width":"60px"
							}
						]
					}
				}
			}
        }

参考uniapp文档
注:api命名不能和默认组件冲突

二、搜索页面内容布局

1.1 页面布局代码:

<template>
	<view class='search'>
		<Lines />
		
		<view class='search-item'>
			<view class='search-title'>
				<view class='f-color'>最近搜索</view>
				<view class='iconfont icon-iconset0213'></view>
			</view>
			<view>
				<view class='search-name f-color'>四件套</view>
				<view class='search-name f-color'>面膜</view>
			</view>
		</view>
		
		<view class='search-item'>
			<view class='search-title'>
				<view class='f-color'>热门搜索</view>
			</view>
			<view>
				<view class='search-name f-color'>四件套</view>
				<view class='search-name f-color'>面膜</view>
			</view>
		</view>
		
	</view>
</template>

<script>
	import Lines from '@/components/common/Lines.vue'
	export default {
		data() {
			return {
				
			}
		},
		components:{
			Lines
		},
		methods: {
			
		}
	}
</script>

<style scoped>
.search-item{
	padding:20rpx;
}
.search-title{
	display: flex;
	justify-content: space-between;
}
.search-name{
	padding:4rpx 24rpx;
	background-color: #E1E1E1;
	display: inline-block;
	border-radius: 26rpx;
	margin:10rpx;
}
</style>

三、进入搜索结果页

1.1 在pages中创建search-list页面
1.2 在search.vue中加入:跳转到search-list页面

onNavigationBarButtonTap(e){
			if(e.float === 'right'){
				uni.navigateTo({
					url:"../search-list/search-list"
				})
			}
		},

1.3 在pages.json中配置搜索结果页面的头部

{
            "path" : "pages/search-list/search-list",
            "style" : {
           	"navigationBarBackgroundColor":"#FFFFFF",
           	"app-plus":{
           		"scrollIndicator":"none",
           		"titleNView":{
           			"searchInput":{
           				"placeholder":"nike",
           				"disabled":false,
           				"align":"left",
           				"borderRadius":"15px",
           				"backgroundColor":"#F7F7F7",
           				"placeholderColor":"#B3B3B3"
           			},
           			"buttons":[
           				{
           					"float":"right",
           					"color":"#636263",
           					"text":"筛选",
           					"fontSize":"16px",
           					"width":"60px"
           				}
           			]
           		}
           	}
           }
        }

四、搜索结果页布局和封装

1.1 在components下的common目录中新建ShopList.vue组件
1.2 上半部分布局,下半部分调用之前引入创建的商品列表组件

1.3 布局代码如下:

<template>
	<view class='shop-list'>
		
		<view class='shop-title f-color'>
			<view class='shop-item'>
				<view>价格</view>
				<view class='shop-icon'>
					<view class='iconfont icon-shangjiantou up'></view>
					<view class='iconfont icon-xiajiantou down'></view>
				</view>
			</view>
			<view class='shop-item'>
				<view>折扣</view>
				<view class='shop-icon'>
					<view class='iconfont icon-shangjiantou up'></view>
					<view class='iconfont icon-xiajiantou down'></view>
				</view>
			</view>
			<view class='shop-item'>
				<view>品牌</view>
				<view class='shop-icon'>
					<view class='iconfont icon-shangjiantou up'></view>
					<view class='iconfont icon-xiajiantou down'></view>
				</view>
			</view>
		</view>
		<Lines />
		<CommodityList :dataList='dataList'></CommodityList>
	</view>
</template>

<script>
import Lines from '@/components/common/Lines.vue'
import CommodityList from './CommodityList.vue'
export default {
		data() {
			return {
				dataList:[
					{
						id:1,
						imgUrl:"../../static/img/commodity1.jpg",
						name:"大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008",
						pprice:"299",
						oprice:"659",
						discount:"5.2"
					},
					{
						id:2,
						imgUrl:"../../static/img/commodity2.jpg",
						name:"大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008",
						pprice:"299",
						oprice:"659",
						discount:"5.2"
					},
					{
						id:3,
						imgUrl:"../../static/img/commodity3.jpg",
						name:"大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008",
						pprice:"299",
						oprice:"659",
						discount:"5.2"
					},
					{
						id:4,
						imgUrl:"../../static/img/commodity4.jpg",
						name:"大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008大姨绒毛大款2020年必须买,不买你就不行了,爆款疯狂GG008",
						pprice:"299",
						oprice:"659",
						discount:"5.2"
					}
				]
			}
		},
		components:{
			Lines,
			CommodityList
		},
		methods: {
			
		}
	}
</script>

<style scoped>
.shop-title{
	display: flex;
}
.shop-item{
	flex:1;
	display: flex;
	justify-content: center;
	align-items: center;
	height: 80rpx;
}
.shop-icon{
	position: relative;
	margin-lef:10rpx;
}
.iconfont{
	width:16rpx;
	height: 8rpx;
	position: absolute;
	left:0;
}
.up{
	top:-34rpx;
}
.down{
	top:-24rpx;
}
</style>

五、搜索结果页排序功能

Shoplist.vue

	<view class='shop-title f-color'>
			<view class='shop-item'
				v-for="(item,index) in shopList.data"
				:key='index'
				@tap='changTab(index)'
			>
				<view :class="  shopList.currentIndex==index?'f-active-color':'' ">{{item.name}}</view>
				<view class='shop-icon'>
					<view class='iconfont icon-shangjiantou up'
						:class=' item.status ===1 ? "f-active-color":"" '
					></view>
					<view class='iconfont icon-xiajiantou down'
						:class=' item.status ===2 ? "f-active-color":"" '
					></view>
				</view>
			</view>
		</view>

选中变色判断方法
0,1 list是否被选择
1,2 上下箭头

shopList:{
				    currentIndex:0,
					data:[
						{name:"价格",status:1},
						{name:"折扣",status:0},
						{name:"品牌",status:0}
					]
methods: {
			changTab(index){
				//索引值
				let idx = this.shopList.currentIndex;//idx
				//具体哪一个对象
				let item = this.shopList.data[idx];
				if( idx == index ){
					return item.status = item.status === 1 ? 2:1; //data的状态值
				}
				//新的值,
				let newItem = this.shopList.data[index];//index
				item.status = 0;
				this.shopList.currentIndex = index;
				newItem.status = 1;
				
			}
		}

六、搜索关键词判断和隐藏键盘

解决问题

1、判断关键词,如果关键词为空需要提示
2、进入搜索结果页需要隐藏键盘
3、点击软键盘的搜索也可以进入到搜索结果页面
4、搜索词
4.1用本地存储记录
4.2搜索词重复判断
4.3最新搜索到词循序前置
5、清除最近搜索记录=》提示无搜索记录
6、搜索词不通过展示的数据不同
7、排序=》链接数据库,sql语句
uniapp 页面生命周期的

<script>
	import Lines from '@/components/common/Lines.vue'
	export default {
		data() {
			return {
				keyword:''
			}
		},
		//监听input输入内容
		onNavigationBarSearchInputChanged(e){
		     this.keyword = e.text;
		},
		//点击顶栏中的搜索按钮
		onNavigationBarButtonTap(e){
			this.search();	
		},
		//监听软键盘的搜索按钮点击的
		onNavigationBarSearchInputConfirmed(){
			this.search();	
		},
		components:{
			Lines
		},
		methods: {
			//判断关键词是否为空和跳转页面的
			search(){
				if( this.keyword ==="" ){
					return uni.showToast({
						title:"关键词不能为空",
						icon:"none"
					})
				}else{
					uni.navigateTo({
						url:"../search-list/search-list"
					})
				}
				uni.hideKeyboard();
				//隐藏键盘
			}
		}
	}
</script>

七、搜索词记录

1用本地存储记录
2搜索词重复判断
3最新搜索到词循序前置

<view v-else class='search-end'>暂无搜索记录</view>

//页面加载的时候
		onLoad(){
			uni.getStorage({
				key:"searchData",
				success: (res) => {
					this.searchData = JSON.parse( res.data );
				}
			})
		},
//记录最近搜索词
			addSearch(){
				
				let idx = this.searchData.indexOf(this.keyword);
				if( idx < 0 ){
					this.searchData.unshift(  this.keyword );
					//直接添加
				}else{
					this.searchData.unshift( this.searchData.splice(idx,1)[0] );
					//删除再添加
				}
				
				//uniapp api 数据缓存
				uni.setStorage({
					key:"searchData",
					data: JSON.stringify(this.searchData)
				}
			)

八、清除最近搜索记录

api: confirmText

//清除搜索记录
			clearHistory(){
				uni.showModal({
					title:"重要提示",
					content:'是否要清除搜索记录',
					cancelText:'取消',
					confirmText:"确定",
					success: (res) => {
						if(res.confirm){
							uni.removeStorage({
								key:"searchData"
							})
							this.searchData=[];
						}
					}
				})
			}

九、搜索词传值

search-list.vue

onLoad(e) {
			
			this.keyword = e.keyword;
			// #ifdef APP-PLUS  uniapp 方法 动态修改原生导航栏
			var webView = this.$mp.page.$getAppWebview();  
			webView.setTitleNViewSearchInputText( e.keyword);

							//接收
			// #endif
			
		},

search.vue
传值

//判断关键词是否为空和跳转页面的
			search(){
				if( this.keyword ==="" ){
					return uni.showToast({
						title:"关键词不能为空",
						icon:"none"
					})
				}else{
					uni.navigateTo({
						url:"../search-list/search-list?keyword="+this.keyword+""
					})
				}
				uni.hideKeyboard();
				this.addSearch();
			},

子传父
search-list.vue

<template>
	<view>
		<ShopList :keyword='keyword'></ShopList>
	</view>
</template>

Shoplist.vue

props:{
			keyword:String
		},

十、搭建数据库表**

接口文档

1.2URL
地址/api/goods/search
1.3支持格式
JSON
1.4 HTTP请求方式
GET
1.5 请求参数

参数必选类型说明
namestring搜索的关键词
pprice或者discountstring排序

1.6 返回字段

返回字段字段类型说明
codestring返回结果状态。0:正常;1:错误。
dataobject搜索到的数据
{
“code”:0,
“data”:[{
		   id:1,
			ImgUrl:"../../static/img/commodity1.jpg",
			name:"大姨绒",
			pprice:"299",
		   oprice:"659",
		  discount:"5.2"
}]
}

npm install mysql

mkdir db
vim sql.js

var mysql = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : 'rootroot',
  database : 'aolai'
});
module.exports = connection;

index.js

var express = require('express');
var router = express.Router();
var connection = require('../db/sql.js');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});


router.get("/api/goods/search",function(req, res, next) {
	//desc降序     asc升序
	//获取对象的key
	let [goodsName,orderName] = Object.keys(req.query);
	//name参数的值
	let name = req.query.name;
	//orderName的key的值
	let order = req.query[orderName];
	
	connection.query("select * from goods_search where name like '%"+name+"%' order by "+orderName+" "+order+"", function (error, results, fields) {
	  if (error) throw error;
	  res.send({
		  code:"0",
		  data:results
	  })
	});
	
});

十一、请求搜索接口

显示不同搜索页
Shoplist.vue

mounted(){
			this.getData();
		},
		methods: {
			//请求数据数据
			getData(){
				$http.request({
					url:"/goods/search",
					data:{
						name:this.keyword,
						pprice:"desc"
					}
				}).then((res)=>{
					this.dataList = res;
				}).catch(()=>{
					uni.showToast({
						title:'请求失败',
						icon:'none'
					})
				})
			},

search-list.vue

<view 
					class='search-name f-color'
					v-for='(item,index) in searchData'
					:key='index'
					@tap='toSearchList(item)'
				>
					{{item}}
				</view>
//点击搜索记录进入页面
			toSearchList(item){
				uni.navigateTo({
					url:"../search-list/search-list?keyword="+item+""
				})
			}
//判断关键词是否为空和跳转页面的
			search(){
				if( this.keyword ==="" ){
					return uni.showToast({
						title:"关键词不能为空",
						icon:"none"
					})
				}else{
					this.toSearchList(this.keyword);
					//use
				}
				uni.hideKeyboard();
				this.addSearch();
			},

十二、商品排序

Shoplist.vue
添加

computed:{
			orderBy(){
				//拿到当前对象
				let obj = this.shopList.data[this.shopList.currentIndex];
				let val = obj.status === "1" ? "asc" : "desc" ;
				return {
					[obj.key]:val
				}
				
			}
		},

修改为动态的排序

//请求数据数据
			getData(){
				$http.request({
					url:"/goods/search",
					data:{
						name:this.keyword,
						...this.orderBy
					}

computed 不能深度检测
加载页面数据多怎么办,limit,分页

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值