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

搜索联想建议

在这里插入图片描述

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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net get set 初始化_.NET项目升级:可为空引用

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;波多尔斯基cnblogs.com/podolski/p/12692888.html前言C#8引入了新特性&#xff1a;可为空引用https://docs.microsoft.com/zh-cn/dotnet/csharp/nullable-references这个功能个人觉得挺好的&#xff0c;能够非常明确的…

用GDB排查Python程序故障

某Team在用Python开发一些代码&#xff0c;涉及子进程以及设法消除僵尸进程的需求。实践中他们碰上Python程序非预期退出的现象。最初他们决定用GDB调试Python解释器&#xff0c;查看exit()的源头。我听了之后&#xff0c;觉得这个问题应该用别的调试思路。帮他们排查这次程序故…

解决后端返回数据中的大数字问题(使用第三方包json-bigint )

JavaScript 能够准确表示的整数范围在-2^53到2^53之间&#xff08;不含两个端点&#xff09;&#xff0c;超过这个范围&#xff0c;无法精确表示这个值&#xff0c;这使得 JavaScript 不适合进行科学和金融方面的精确计算。 Math.pow(2, 53) // 90071992547409929007199254740…

java 静态代码块_关于Java你不知道的那些事之代码块

前言普通代码块&#xff1a;在方法或语句中出现的{}&#xff0c;就被称为代码块静态代码块&#xff1a;静态代码块有且仅加载一次&#xff0c;也就是在这个类被加载至内存的时候普通代码块和一般语句执行顺序由他们在代码中出现的次序决定&#xff0c;先出现先执行代码一/**对于…

Vue项目开发过程中解决跨域问题(vue.config.js结合axios)

一、问题描述 在本地开发过程中&#xff0c;调用后端提供的接口获取数据将获取的数据渲染到页面中&#xff0c;但是浏览器报错&#xff1a; // 控制台报错信息 Access to XMLHttpRequest at http://x.x.x.x/app/v1_0/user/followings from origin http://localhost:8080 has…

WebSocket实现实时通信

WebSocket 是一种数据通信协议&#xff0c;也是用于客户端和服务端数据通信&#xff0c;类似于我们常见的 http 既然有 http&#xff0c;为啥还要 WebSocket http 通信是单向的 请求 响应 没有请求也就没有响应 初次接触 WebSocket 的人&#xff0c;都会问同样的问题&#xf…

使用socket.io搭建一个实时聊天机器人

一、安装socket.io npm i socket.io --save二、使用 第一种&#xff1a;服务端使用原生node // 创建http服务器 const http require(http) var fs require(fs) const app http.createServer()app.on(request, (req, res) > {fs.readFile(__dirname /index.html, funct…

真随机和伪随机区别_用骰子DIY真随机助记词 | 火星号精选

免责声明&#xff1a;本文旨在传递更多市场信息&#xff0c;不构成任何投资建议。文章仅代表作者观点&#xff0c;不代表火星财经官方立场。小编&#xff1a;记得关注哦

EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计

EasyDarwin现有架构介绍 EasyDarwin的现有架构对网络事件的处理是这样的&#xff0c;每一个Socket连接在EasyDarwin内部的对应存在形式就是一个Session&#xff0c;不论是RTSP服务对应的RTSPSession&#xff0c;还是HTTP服务对应的HTTPSession&#xff0c;都是一个继承自Task类…

Vue 中的组件缓存

一、介绍 先来看一个问题&#xff1f; 从首页的区块链模块切换到文章详情页面&#xff0c;再从文章详情页面回到首页&#xff0c;我们发现首页重新渲染原来的状态没有了&#xff0c;又回到了推荐模块。 首先&#xff0c;这是正常的状态&#xff0c;并非问题&#xff0c;路由…

SQLlite 分页

如果我要去11-20的Account表的数据 Select * From Account Limit 9 Offset 10; 以上语句表示从Account表获取数据&#xff0c;跳过10行&#xff0c;取9行 嗯&#xff0c;我觉得这个特性足够让很多的web中型网站使用这个了。 也可以这样写 select * from account limit10,9和上面…

thief book怎么用_战略管理工具箱--30个好用的战略管理好工具

-原创转载请告知-十年多年前&#xff0c;在上海做咨询的时候&#xff0c;曾经在书店买了一本《战略管理工具箱》的Poket小书&#xff0c;一直看一直看&#xff0c;里面包含常用的战略管理工具&#xff08;30个&#xff09;&#xff0c;虽然不用都用上&#xff0c;用其中几个常用…

Vue中使用axios的响应拦截器处理请求失败的情况(处理token过期问题)以及 登录成功跳转回原来页面问题

参考axios官方文档 // 响应拦截器 // Add a response interceptor request.interceptors.response.use(// 在2xx范围内的任何状态代码都会触发此函数&#xff0c;这里主要用于处理响应数据response > {return response},// 任何超出2xx范围的状态码都会触发此函数&#xff0…

cocoapods 命令

1.使用CocoaPods a 新建一个项目&#xff0c;名字cocoapods b 终端中&#xff0c;cd到项目总目录&#xff08;直接拖过来&#xff09; [objc] copy? cd /Users/pengjian/Desktop/cocoapodsc 建立Podfile&#xff08;配置文件&#xff09; 接着上一步&#xff0c;终端输入 v…

Vue项目中使用 路由导航守卫 处理页面的访问权限

参考Vue-Router官方文档 Vue-Router导航守卫 效果展示 1、给需要登录状态才能访问的页面路由对象的 meta 中添加配置属性 { // 小智同学name: user-chat,path: /user/chat,component: () > import(/views/user-chat),meta: { requiresAuth: true } },2、通过路由拦截器…

失败,因为你其实太过傲慢

因为你太过傲慢&#xff0c;不肯放低姿态去向他人学习&#xff0c;勤加练习&#xff0c;所以失败。转载于:https://www.cnblogs.com/panie2015/p/5667464.html

Uniapp学习笔记(数据展示、数据循环、条件编译、计算属性、组件的使用、组件插槽、生命周期)

1.项目准备 1.1开发方式 uni-app为我们提供2种开发方式&#xff1a; 使用DCloud公司提供HBuilderX工具来快速开发&#xff1b; 使用脚手架来快速开发&#xff08;我们这次项目使用此方式&#xff09;&#xff1b; 1.2脚手架搭建项目 全局安装&#xff0c;如果你以前安装过…

word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...

Hello&#xff0c;最近正值着手写毕业论文的初期&#xff0c;趁着这个时间点&#xff0c;我做了一个简易的&#xff0c;简单的&#xff0c;0基础的Word论文排版教学&#xff0c;帮助你在撰写论文的时候不再花费大量的时间浪费在调整格式里。初次做视频&#xff0c;难免有错误&a…

云计算三种服务模式SaaS、PaaS和IaaS及其之间关系(顺带CaaS、MaaS)

云计算架构图 很明显&#xff0c;这五者之间主要的区别在于第一个单词&#xff0c;而aaS都是as-a-service&#xff08;即服务&#xff09;的意思&#xff0c;这五个模式都是近年来兴起的&#xff0c;且这五者都是云计算的落地产品&#xff0c;所以我们先来了解一下云计算是什么…

uni-ui介绍uni-api

一、uni-ui介绍 安装 二、uni-api 解决uni-app中的跨域问题&#xff1a; "h5" : {"router" : {"mode" : "hash"},"devServer": {"https": false,"proxy": {"/web": {"target": …