搜索联想建议

1. 基本思路:

当搜索框输入内容的时候,请求加载联想建议的数据
将请求得到的结果绑定到模板中

2. 基本功能

一、将父组件中搜索框输入的内容传给联想建议子组件

二、在子组件中监视搜索框输入内容的变化,如果变化则请求获取联想建议数据

三、将获取到的联想建议数据展示到列表中

父组件完整代码:

<template><div class="search-container"><!--搜索栏--><form action="/"><van-search v-model="searchText"  @search="onSearch"@focus="isResultShow = false" @cancel="onCancel" show-action placeholder="请输入搜索关键词" /></form><!--搜索结果--><search-results v-if="isResultShow" /><!--联想建议--><search-suggestion v-else-if="searchText" :search-text="searchText"/><!--历史记录--><search-history v-else /></div>
</template><script>
import SearchSuggestion from './components/search-suggestion.vue'
import SearchHistory from './components/search-history.vue'
import SearchResults from './components/search-results.vue'
export default {name: 'SearchIndex',data () {return {searchText: '', // 输入搜索框的内容isResultShow: false // 控制搜索结果的显示状态}},components: {SearchSuggestion,SearchHistory,SearchResults},methods: {onSearch (val) {// 展示搜索结果this.isResultShow = true},onCancel () {this.$router.back()}}
}
</script><style scoped></style>

子组件完整代码:

<template><div class="search-suggestion"><van-cell v-for="(str, index) in suggestions":key="index" icon="search" :title="str"></van-cell></div>
</template>
<script>
import { getSearchSuggestions } from '../../../api/search.js'
import { debounce } from 'lodash'
// /*// 函数防抖
// const fn = _.debounce(function () {//   console.log('hello')
// }, 1000)
//
// fn()
// fn()
// setTimeout(() => {//   fn()
// }, 1200)
// fn()*/
export default {name: 'SearchSuggestion',data () {return {suggestions: [] // 联想建议数据列表}},props: {searchText: {type: String,required: true}},watch: {// 属性名:要监视的数据的名称// searchText () {//   console.log('je')// }// 监视的完整写法searchText: {// 当数据发生变化则会执行 handler处理函数handler: debounce(async function () {// 发请求const { data } = await getSearchSuggestions(this.searchText)this.suggestions = data.data.options}, 200),// async handler () {//   // 发请求//   const { data } = await getSearchSuggestions(this.searchText)//   this.suggestions = data.data.options// },immediate: true // 该回调将会在侦听开始之后被立即调用}}
}
</script><style scoped></style>

3. 防抖优化

loadsh官网
https://www.lodashjs.com/docs/lodash.debounce

1、安装 lodash

# yarn add lodash
npm i lodash

2、防抖处理

// lodash 支持按需加载,有利于打包结果优化
import { debounce } from "lodash"

不建议下面这样使用,因为这样会加载整个模块。

import _ from 'lodash'
_.debounce()
// debounce 函数
// 参数1:函数
// 参数2:防抖时间
// 返回值:防抖之后的函数,和参数1功能是一样的
onSearchInput: debounce(async function () {const searchContent = this.searchContentif (!searchContent) {return}// 1. 请求获取数据const { data } = await getSuggestions(searchContent)// 2. 将数据添加到组件实例中this.suggestions = data.data.options// 3. 模板绑定
}, 200),


联想建议优化——高亮搜索关键字

如何将字符串中的指定字符在网页中高亮展示?

"Hello World";

将需要高亮的字符包裹 HTML 标签,为其单独设置颜色。

"Hello <span style="color: red">World</span>"

在 Vue 中如何渲染带有 HTML 标签的字符串?

data () {return {htmlStr: 'Hello <span style="color: red">World</span>'}
}
<div>{{ htmlStr }}</div>
<div v-html="htmlStr"></div>

如何把字符串中指定字符统一替换为高亮(包裹了 HTML)的字符?

const str = "Hello World"// 结果:<span style="color: red">Hello</span> World
"Hello World".replace('Hello', '<span style="color: red">Hello</span>')// 需要注意的是,replace 方法的字符串匹配只能替换第1个满足的字符
// <span style="color: red">Hello</span> World Hello abc
"Hello World Hello abc".replace('Hello', '<span style="color: red">Hello</span>')// 如果想要全文替换,使用正则表达式
// g 全局
// i 忽略大小写
// <span style="color: red">Hello</span> World <span style="color: red">Hello</span> abc
"Hello World Hello abc".replace(/Hello/gi, '<span style="color: red">Hello</span>')

一个小扩展:使用字符串的 split 结合数组的 join 方法实现高亮

var str = "hello world 你好 hello";// ["", " world 你好 ", ""]
const arr = str.split("hello");// "<span>hello</span> world 你好 <span>hello</span>"
arr.join("<span>hello</span>");

下面是具体的处理。

1、在 methods 中添加一个方法处理高亮

// 参数 source: 原始字符串
// 参数 keyword: 需要高亮的关键词
// 返回值:替换之后的高亮字符串
highlight (source, keyword) {// /searchContent/ 正则表达式中的一切内容都会当做字符串使用// 这里可以 new RegExp 方式根据字符串创建一个正则表达式// RegExp 是原生 JavaScript 的内置构造函数// 参数1:字符串,注意,这里不要加 //// 参数2:匹配模式,g 全局,i 忽略大小写const reg = new RegExp(keyword, 'gi')return source.replace(reg, `<span style="color: #3296fa">${keyword}</span>`)
},

2、然后在联想建议列表项中绑定调用

<!-- 联想建议 -->
<van-cell-group v-else-if="searchContent"><van-cellicon="search"v-for="(item, index) in suggestions":key="index"@click="onSearch(item)"><div slot="title" v-html="highlight(item, searchContent)"></div></van-cell>
</van-cell-group>
<!-- /联想建议 -->


完整代码:

<template><div class="search-suggestion"><van-cell v-for="(str, index) in suggestions":key="index" icon="search" ><div slot="title" v-html="hightlight(str)"></div></van-cell></div>
</template>
<script>
import { getSearchSuggestions } from '../../../api/search.js'
import { debounce } from 'lodash'
// /*// 函数防抖
// const fn = _.debounce(function () {//   console.log('hello')
// }, 1000)
//
// fn()
// fn()
// setTimeout(() => {//   fn()
// }, 1200)
// fn()*/
export default {name: 'SearchSuggestion',data () {return {suggestions: [] // 联想建议数据列表}},props: {searchText: {type: String,required: true}},watch: {// 属性名:要监视的数据的名称// searchText () {//   console.log('je')// }// 监视的完整写法searchText: {// 当数据发生变化则会执行 handler处理函数handler: debounce(async function () {// 发请求const { data } = await getSearchSuggestions(this.searchText)this.suggestions = data.data.options}, 200),// async handler () {//   // 发请求//   const { data } = await getSearchSuggestions(this.searchText)//   this.suggestions = data.data.options// },immediate: true // 该回调将会在侦听开始之后被立即调用}},methods: {hightlight (str) {// RegExp()是正则表达式的构造函数// 参数1: 字符串// 参数2: 匹配模式// 返回值: 正则对象const regStr = new RegExp(this.searchText, 'gi')return str.replace(regStr, `<span style="color: red">${this.searchText}</span>`)}}
}
</script><style scoped></style>

Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)相关推荐

  1. Vue移动端项目(二)

    五.首页-频道编辑 处理页面弹出层 Vant 中内置了 Popup 弹出层 组件. 1.在 data中添加一个数据用来控制弹层的显示和隐藏 data () {return {...isChannelE ...

  2. Vue移动端项目---尚硅谷外卖

    文章目录 Vue移动端项目--尚硅谷外卖 项目目录结构介绍 移动端适配 头部和底部导航 登录注册页面 密码登录 短信登录 Profile页面 未登录 已登录 Msite页面 首页导航 ShopList ...

  3. vue移动端项目日历组件,月周切换,点击进入上/下一个月

    项目场景: Vue移动端项目的日历组件,移动端如果没有别的特别要求,一般用vant中的日历组件就OK,这里用的另一个.组件是网上找的,原网址:vue-hash-calendar,需要的请自行去看. 我 ...

  4. vue移动端项目缓存问题实践

    最近在做一个vue移动端项目,被缓存问题搞得头都大了,积累了一些经验,特此记录总结下,权当是最近项目问题的一个回顾吧! 先描述下问题场景:A页面->B页面->C页面.假设A页面是列表页面, ...

  5. Vue 移动端项目创建

    前言 移动端我们一般通过Vue脚手架手动自定义创建项目, 只需要Node环境我们就可以通过npm下载Vue脚手架,通过命令创建项目. npm下载脚手架 npm install -g @vue/cli ...

  6. vue移动端项目实现真机调试

    在vue移动端项目中,我们可以通过真机调试来更好的看到项目实际运行在移动端的效果. 下面就来介绍一下实现的方法: 1.使手机与电脑连接在同一个wifi下 2.修改vue.config.js文件配置 将 ...

  7. vue移动端项目实现定位

    vue移动端项目实现定位 腾讯地图官方地址 <template><div><!-- 定义地图显示容器 --><div id="container&q ...

  8. vue移动端项目基础框架搭建

    本文章,主要提供vue移动端项目基础框架搭建思路,每个独立的模块网上有很多相关的文档. 移动端vue项目基础框架搭建,主要包括6个步骤 项目使用的脚手架vue-cli搭建模板,2.使用淘宝lib-fl ...

  9. 极客日报:百度网盘青春版将不限速;Bing在中国内地暂停“搜索自动建议”功能30天;新款iPhone SE将支持5G

    一分钟速览新闻点! 腾讯公司旗下App开始恢复更新 雷军生日米粉祝早日退休 百度网盘青春版即将内测:不限速,数据可互转 金山办公发布全新品牌Logo:一面迎风飘扬的旗帜 首次!龙芯处理器成功运行开源鸿 ...

最新文章

  1. AlexeyAB DarkNet YOLOv3框架解析与应用实践(六)
  2. 为EditText输入框加上提示信息
  3. Gartner重磅发布近40页PPT,详解2017年十大战略技术趋势
  4. 【Spring框架家族】Spring Cloud Eureka 之常用配置解析(转载)
  5. Wijmo 2016年蓝图
  6. java 图片压缩100k_java实现图片压缩
  7. Linux学习资源汇总
  8. windows下的IO模型之完成端口
  9. cisco failover 概念
  10. 华为荣耀9手机通过在Fastboot模式写ramdisk.img来获取ROOT权限 | 华为荣耀9怎么获取ROOT权限 | 华为荣耀9怎么用面具Magisk做ROOT权限
  11. 执行python manage.py celery -A HttpRunnerManager worker --loglevel=info 报错问题集锦
  12. 解决Untracked Files Prevent Checkout问题
  13. 如何创建(设置)一个可以开发微信小游戏的appid
  14. 信号的扩展是因果_信号与系统 怎么判断e(1-t)的时不变和因果性?
  15. 苹果自带输入法怎么换行_iPhone输入无法换行?这些办法解决你的问题
  16. 计算机组装慕课平台,计算机组装与维修
  17. 华为OD机试(A、B卷)、机考,200分的题目整理如下,冲满分必备
  18. FP Tree算法原理
  19. c语言中“函数的定义不可以嵌套,但函数的调用可以嵌套
  20. 一文搞懂文本识别、银行卡识别、通用卡证识别、身份证识别

热门文章

  1. ubuntu java classpath 设置_在Ubuntu中正确设置java classpath和java_home
  2. Flask 第三方组件之 Migrate
  3. patator mysql 字典_利用patator进行子域名爆破
  4. celery 学习笔记定时任务和异步任务
  5. Codeblocks和gdb调试 (转)
  6. xcode左侧不显示工程文件目录,提示NO Filter Results
  7. linux select shell,linux之shell编程select和case用法
  8. citespace安装如何配置JAVA_citespace超详细安装教程
  9. 怎么卸载apowerrec_如何删除windows10自带应用
  10. scp和sftp常用操作