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

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

1. 基本思路:
【Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)】当搜索框输入内容的时候,请求加载联想建议的数据
将请求得到的结果绑定到模板中
2. 基本功能
一、将父组件中搜索框输入的内容传给联想建议子组件
Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)
文章图片

二、在子组件中监视搜索框输入内容的变化,如果变化则请求获取联想建议数据
Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)
文章图片

三、将获取到的联想建议数据展示到列表中
Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)
文章图片

父组件完整代码:

> 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() } } } scoped>

子组件完整代码:
> 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 // 该回调将会在侦听开始之后被立即调用 } } } scoped>

3. 防抖优化
loadsh官网
https://www.lodashjs.com/docs/lodash.debounce
Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)
文章图片

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.searchContent if (!searchContent) { return }// 1. 请求获取数据 const { data } = await getSuggestions(searchContent)// 2. 将数据添加到组件实例中 this.suggestions = data.data.options// 3. 模板绑定 }, 200),

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

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

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

联想建议优化——高亮搜索关键字 Vue.js|Vue移动端项目——搜索联想建议功能的实现(结合watch属性和使用lodash防抖节流)
文章图片

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

将需要高亮的字符包裹 HTML 标签,为其单独设置颜色。
"Hello : red">World"

在 Vue 中如何渲染带有 HTML 标签的字符串?
data () { return { htmlStr: 'Hello World' } }

{{ htmlStr }}

如何把字符串中指定字符统一替换为高亮(包裹了 HTML)的字符?
const str = "Hello World"// 结果:Hello World "Hello World".replace('Hello', 'Hello')// 需要注意的是,replace 方法的字符串匹配只能替换第1个满足的字符 // Hello World Hello abc "Hello World Hello abc".replace('Hello', 'Hello')// 如果想要全文替换,使用正则表达式 // g 全局 // i 忽略大小写 // Hello World Hello abc "Hello World Hello abc".replace(/Hello/gi, 'Hello')

一个小扩展:使用字符串的 split 结合数组的 join 方法实现高亮
var str = "hello world 你好 hello"; // ["", " world 你好 ", ""] const arr = str.split("hello"); // "hello world 你好 hello" arr.join("hello");

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

下面是具体的处理。
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, `${keyword}`) },

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

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

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

完整代码:
> 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, `${this.searchText}`) } } } >

    推荐阅读