• 基于uniapp的通用搜索组件(历史记录,app语音输入,搜索推荐)解析 zysearch


    基于uni-app的通用搜索组件(历史记录,app语音输入,搜索推荐)解析 zy-search

    一个通用的搜索组件,包含搜索历史记录,语音输入,搜索推荐功能

    插件地址:https://ext.dcloud.net.cn/plugin?id=512

    插件内容:

    
    
    <template name="zy-search">
    	<view>
    		<view class="search">
    			<!-- 运行在app端的代码 -->
    			<!-- #ifdef APP-PLUS --> 
    				<image src="../../static/zy-search/voice.svg" mode="aspectFit" @click="startRecognize()" class="voice-icon"></image>
    			<!-- #endif -->
    			<template v-if="isFocus">
    				<input maxlength="20" focus type="text" value="" confirm-type="search" @confirm="searchStart()" placeholder="请输入关键词搜索" v-model.trim="searchText"/>
    			</template>
    			<template v-else>
    				<input maxlength="20" type="text" value="" confirm-type="search" @confirm="searchStart()" placeholder="请输入关键词搜索" v-model.trim="searchText"/>
    			</template>
    			<image src="../../static/zy-search/search.svg" mode="aspectFit" @click="searchStart()" class="search-icon"></image>
    		</view>
    		<view :class="'s-' + theme" v-if="hList.length > 0">
    			<view class="header">
    				历史记录
    				<image src="../../static/zy-search/delete.svg" mode="aspectFit" @click="delhistory"></image>
    			</view>
    			<view class="list">
    				<view v-for="(item,index) in hList" :key="index" @click="keywordsClick(item)">{{item}}</view>
    			</view>
    		</view>
    		<view :class="'wanted-' + theme" v-if="showWant">
    			<view class="header">猜你想搜的</view>
    			<view class="list">
    				<view v-for="(item,index) in hotList" :key="index" @click="keywordsClick(item)">{{item}}</view>
    			</view>
    		</view>
    	</view>
    </template>
    
    <script>
    	export default{
    		name:"zy-search",
    		props:{
    			isFocus:{	//是否自动获取焦点
    				type: Boolean,
    				default: false
    			},
    			theme:{	//选择块级显示还是圆形显示
    				type: String,
    				default: 'block'
    			},
    			showWant:{	//是否展示推荐菜单
    				type: Boolean,
    				default: false
    			},
    			hotList: { //推荐列表数据
    				type: Array,
    				default () {
    					return []
    				}
    			},
    			speechEngine: { //语音引擎=>讯飞:iFly,百度:'baidu'
    				type: String,
    				default: 'baidu'
    			}
    		},
    		data() {
    			return {
    				searchText:'',								//搜索关键词
    				hList:uni.getStorageSync('search_cache')		//历史记录
    			};
    		},
    		methods: {
    			//触发搜索  并加入历史记录
    			searchStart: function() {	
    				let _this = this;
    				// 判断输入值为空的情况
    				if (_this.searchText == '') {
    					uni.showToast({
    						title: '请输入关键字',
    						icon: 'none',
    						duration: 1000
    					});
    				}else{
    					// 通知父组件进行搜索
    					_this.$emit('getSearchText', _this.searchText);
    					// 从本地缓存中异步获取指定 key 对应的内容。
    					uni.getStorage({
    						key:'search_cache',
    						success(res){
    							let list = res.data;
    							if(list.length > 5){
    							// 如果数组的长度大于5
    								// 循环该数组
    								for(let item of list){
    									// 如果数组中有一项和当前输入框中输入的值相等的话,终止操作流程
    									if(item == _this.searchText){
    										return;
    									}
    								}
    								// 删除数组最后一项
    								list.pop();
    								// 在数组最前面增加一项
    								list.unshift(_this.searchText);
    							}else{
    							// 如果数组的长度小于5
    								// 循环该数组
    								for(let item of list){
    									// 如果数组中有一项和当前输入框中输入的值相等的话,终止操作流程
    									if(item == _this.searchText){
    										return;
    									}
    								}
    								// 在数组最前面增加一项
    								list.unshift(_this.searchText);
    							}
    							// 将当前新数组赋值给列表上显示
    							_this.hList = list;
    							// 向本地缓存中异步存储指定 key 对应的内容。
    							uni.setStorage({
    								key: 'search_cache',
    								data: _this.hList
    							});
    						},
    						fail() {
    							// 如果 从本地缓存中异步获取指定 key 对应的内容   失败
    							// 清空列表上显示的数组
    							_this.hList = [];
    							// 将当前输入的值给列表上显示的数组
    							_this.hList.push(_this.searchText);
    							// 向本地缓存中异步存储指定 key 对应的内容。
    							uni.setStorage({
    								key: 'search_cache',
    								data: _this.hList
    							});
    							// 通知父组件进行搜索  (这里的搜索多余了)
    							_this.$emit('getSearchText', _this.searchText);
    						}
    					})
    				}
    			},
       			// 关键词点击的事件 关键词搜索与历史搜索	
    			keywordsClick (item) {
    				// 将点击的关键词内容赋值给搜索的变量
    				this.searchText = item;
    				//触发搜索事件
    				this.searchStart();
    			},
    			//清空历史记录
    			delhistory () {		
    				this.hList = [];
    				uni.setStorage({
    					key: 'search_cache',
    					data: []
    				});
    			},
    			//语音输入
    			startRecognize: function() {	
    				let _this = this;
    				let options = {};
    				// /语音引擎=>讯飞:iFly,百度:'baidu'  父级传入的 默认baidu
    				options.engine = _this.speechEngine;
    				// 是否需要标点符号 
    				options.punctuation = false; 
    				// 语音识别超时时间
    				options.timeout = 10 * 1000; 
    				// 启动语音识别
    				// 启动语音识别时调用,当语音识别成功后通过successCallback回调返回识别出文本内容,调用语音识别失败则通过errorCallback回调返回。
    				// plus.speech.startRecognize( options, successCB, errorCB );
    				// options: ( SpeechRecognizeOption ) 必选 语音识别参数,用于控制语音引擎的各种技术参数
    				// successCB: ( RecognitionSuccessCallback ) 可选 语音识别成功回调
    				// 当语音识别引擎识别数据成功时的回调函数,并返回识别出的文本内容。
    				// errorCB: ( RecognitionErrorCallback ) 可选 语音识别失败时的回调函数
    				// 当语音识别引擎识别数据失败时的回调函数,并返回失败的错误信息。
    				plus.speech.startRecognize(options, function(s) {
    					// 将语言识别到的内容拼接上输入框中的内容赋值给输入框
    					_this.searchText = _this.searchText + s;
    				});
    			}
    		}
    	}
    </script>
    
    <style lang="less" scoped>
    	.search{
    		 640upx;
    		margin: 30upx auto 0;
    		position: relative;
    		input{
    			background-color: #F7F7F7;
    			padding: 10upx 74upx;
    			font-size: 28upx;
    			border-radius: 50upx;
    		}
    		.voice-icon{
    			 36upx;
    			height: 36upx;
    			padding: 16upx 20upx 16upx 0;
    			position: absolute;
    			left: 16upx;
    			top: 4upx;
    			z-index: 10;
    		}
    		.search-icon{
    			 36upx;
    			height: 36upx;
    			padding: 16upx 20upx 16upx 0;
    			position: absolute;
    			right: 0;
    			top: -2upx;
    			z-index: 10;
    		}
    	}
    	.s-block{
    		margin-top: 30upx;
    		.header{
    			font-size: 32upx;
    			padding: 30upx;
    			position: relative;
    			image{
    				 36upx;
    				height: 36upx;
    				padding: 10upx;
    				position: absolute;
    				right: 40upx;
    				top: 24upx;
    			}
    		}
    		.list{
    			display: flex;
    			flex-wrap: wrap;
    			view{
    				 50%;
    				color: #8A8A8A;
    				font-size: 28upx;
    				box-sizing: border-box;
    				text-align: center;
    				padding: 20upx 0;
    				border-top: 2upx solid #FFF;
        			border-left: 2upx solid #FFF;
    				overflow: hidden;
    				white-space: nowrap;
    				text-overflow: ellipsis;
    				background-color: #F7F7F7;
    			}
    		}
    	}
    	.s-circle{
    		margin-top: 30upx;
    		.header{
    			font-size: 32upx;
    			padding: 30upx;
    			border-bottom: 2upx solid #F9F9F9;
    			position: relative;
    			image{
    				 36upx;
    				height: 36upx;
    				padding: 10upx;
    				position: absolute;
    				right: 40upx;
    				top: 24upx;
    			}
    		}
    		.list{
    			display: flex;
    			flex-wrap: wrap;
    			padding: 0 30upx 20upx;
    			view{
    				padding: 8upx 30upx;
    				margin: 20upx 30upx 0 0;
    				font-size: 28upx;
    				color: #8A8A8A;
    				background-color: #F7F7F7;
    				box-sizing: border-box;
    				text-align: center;
    				border-radius: 20upx;
    			}
    		}
    	}
    	.wanted-block{
    		margin-top: 30upx;
    		.header{
    			font-size: 32upx;
    			padding: 30upx;
    		}
    		.list{
    			display: flex;
    			flex-wrap: wrap;
    			view{
    				 50%;
    				color: #8A8A8A;
    				font-size: 28upx;
    				box-sizing: border-box;
    				text-align: center;
    				padding: 20upx 0;
    				border-top: 2upx solid #FFF;
    				border-left: 2upx solid #FFF;
    				background-color: #F7F7F7;
    				overflow: hidden;
    				white-space: nowrap;
    				text-overflow: ellipsis;
    			}
    		}
    	}
    	.wanted-circle{
    		margin-top: 30upx;
    		.header{
    			font-size: 32upx;
    			padding: 30upx;
    		}
    		.list{
    			display: flex;
    			flex-wrap: wrap;
    			padding: 0 30upx 20upx;
    			view{
    				padding: 8upx 30upx;
    				margin: 20upx 30upx 0 0;
    				font-size: 28upx;
    				color: #8A8A8A;
    				background-color: #F7F7F7;
    				box-sizing: border-box;
    				text-align: center;
    				border-radius: 20upx;
    			}
    		}
    	}
    </style>
    
    

    父组件使用:

    <template>
    	<view>
    		<zy-search :is-focus="true" :theme="themeClass" :show-want="true" :hot-list="hotList" @getSearchText="getSearchText"></zy-search>
    	</view>
    </template>
    
    <script>
    import zySearch from './zy-search/zy-search.vue';
    export default {
    	components: {
    		zySearch
    	},
    	data() {
    		return {
    			themeClass: 'circle',
    			hotList: [] //初始化推荐列表
    		};
    	},
    	onShow() {
    		this.getHotSearch();
    	},
    	methods: {
    		getHotSearch() {
    			this.http('', {}).then(res => {
    				if (res.success) {
    					this.hotList = []
    					res.data.hottest_list.map((item, index) => {
    						this.hotList.push(item.content);
    					});
    				} else {
    				}
    			});
    		},
    		getSearchText(e) {
    			uni.navigateTo({
    				url: '/pagesCourse/index?keyWords=' + e
    			});
    		}
    	}
    };
    </script>
    
    
    

    语音识别相关内容参考:

    https://www.dcloud.io/docs/api/zh_cn/speech.html

  • 相关阅读:
    mysql主从延迟高的原因
    OpenStack云平台网络模式及其工作机制
    maps.reg
    dnion的remap.conf文件
    linux的tar命令
    traffic server文件目录
    records.config文件参数解释
    VNC配置
    KVM详情
    cache.config文件配置模板
  • 原文地址:https://www.cnblogs.com/panghu123/p/15752014.html
Copyright © 2020-2023  润新知