Vue关键字搜索功能实战小案例
这里介绍两种方法:1、使用watch侦听方法 2、computed计算属性方法
页面结果:
第一种
<body> <div id="app"> <!-- 搜索框 --> <input type="text" v-model:value="keyword"> <!-- 数据,遍历filPerson--> <ul> <li v-for="p in filPerson" :key="p.id">{{p.name}}-{{p.age}}</li> </ul> </div> <script> var vm=new Vue({ el:'#app', data:{ keyword:'', persons:[ {id:1,name:'知花实央',age:20}, {id:2,name:'虎杖悠仁',age:18}, {id:3,name:'切嗣',age:16}, {id:4,name:'卫宫切嗣',age:33} ], filPerson:[] }, //第一种写法 watch:{ keyword:{ //初始化,在生成vue时,先执行一遍handler immediate:true,//作用:刚开始filPerson为空,所以要先给filPerson赋一次值 handler(val){ //person中包含val数据,赋值给filPerson this.filPerson=this.persons.filter((p)=>{ return p.name.indexOf(val)!=-1 }) } } } //第二种写法 // computed:{ // filPerson(){ // return this.persons.filter((p)=>{ // return p.name.indexOf(this.keyword)!=-1 // }) // } // } }) </script> </body>
第二种
相较于watch写法,computed写法看上去更加简洁,比如:
1、computed自身就是一种计算属性,不必再去data中新建一个属性。
2、计算属性实时更新,不用像watch方法,新建的filPerson初始值为空,还需要手动开启设置immediate=true初始化,令handler在vue实例创建后先运行一次,赋予初始值。
<body> <div id="app"> <!-- 搜索框 --> <input type="text" v-model:value="keyword"> <!-- 数据 --> <ul> <li v-for="p in filPerson" :key="p.id">{{p.name}}-{{p.age}}</li> </ul> </div> <script> var vm=new Vue({ el:'#app', data:{ keyword:'', persons:[ {id:1,name:'知花实央',age:20}, {id:2,name:'虎杖悠仁',age:18}, {id:3,name:'切嗣',age:16}, {id:4,name:'卫宫切嗣',age:33} ], // filPerson:[] }, //第一种写法 // watch:{ // keyword:{ // //初始化,在生成vue时,先执行一遍handler // immediate:true,//作用:刚开始filPerson为空,所以要先给filPerson赋一次值 // handler(val){ // //过滤掉不包含keyword数据,再赋值给filPerson // this.filPerson=this.persons.filter((p)=>{ // return p.name.indexOf(val)!=-1 // }) // } // } // } //第二种写法 computed:{ filPerson(){ return this.persons.filter((p)=>{ return p.name.indexOf(this.keyword)!=-1 }) } } }) </script> </body>
其实watch方法和computed方法各有优劣,computed方法自己就是一种计算属性,很多时候直接给自己赋值,省去很多代码;但是watch方法能够做到跟多的细节操作,甚至computed能实现的,它都能实现,还能实现更多computed实现不了的细节。
补充:vue页面实现文本关键字检索,关键字高亮显示及定位功能
实现原理
- 将相应的关键字用标签包裹,添加相应的样式,
- 使用 dom.scrollIntoView() 方法实现定位功能
代码
html部分
<template> <div class="serach-box"> <el-input placeholder="请输入关键字" prefix-icon="el-icon-search" v-model="inputLogValue" clearable size="small" @keyup.enter.native='clickSearch'> </el-input> <el-button type="primary" size="small" icon="el-icon-search" @click="clickSearch"></el-button> <div class="searchRight"> <span class="item" style='margin-right:5px'>{{curIndex}}/{{matchCount}}</span> <el-tooltip class="item" effect="dark" content="上一个" placement="top"> <el-button @click="searchLast" icon="el-icon-arrow-up" circle type="text" size="mini" :disabled="matchCount==0"></el-button> </el-tooltip> <el-tooltip class="item" effect="dark" content="下一个" placement="top"> <el-button @click="searchNext" icon="el-icon-arrow-down" circle type="text" size="mini" :disabled="matchCount==0"></el-button> </el-tooltip> </div> </div> <div class="log_content" ref='log_content' v-if="searchStatus" v-html="contentShow"></div> <template> <style lang="scss" scoped> .serach-box{ display: flex; .el-input{ width: 300px; .el-input__inner{ border-right: none; } } .el-button{ border-radius: 0; height: 32px; box-sizing: border-box; } .searchRight{ height: 32px; line-height: 32px; padding: 0 10px; background: #eee; font-size: 14px; color: #666; .el-button+.el-button{ margin-left: 0; } } } .log_content{ width: 100%; height: calc(100% - 40px); line-height: 20px; background-color: #333333; color: #f0f0f0; font-size: 13px; overflow: overlay; padding: 0 20px ; overflow-x:hidden; word-wrap: break-word; white-space: pre-wrap; box-sizing: border-box; padding-bottom: 20px; &::-webkit-scrollbar { width: 10px; height: 7px; background-color: rgba(245, 245, 245, 0.1); cursor: pointer; z-index: 10; } &::-webkit-scrollbar-thumb { height: 20px; border-radius: 10px; background-color: #dddee0; cursor: pointer; z-index: 10; } &::-webkit-scrollbar-thumb:hover { cursor: pointer; background-color: #c7c9cc; } } </style>
js部分
data() { return { logMessage:'', inputLogValue:'', lightIndex: 0, curIndex:0, matchCount: 0, highlightStyle:'background: #ffff00;color:red;', currentStyle:'background: #ff9632', } }, watch:{ inputLogValue: { immediate: true, handler (val) { if(val==''){ this.lightIndex=0 this.curIndex=0 this.matchCount=0 this.searchStatus=0 } } }, }, methods:{ scrollTo (index) { this.$nextTick(() => { let list = this.$el.querySelectorAll(`.search-hightlight`) if (list[index]) { this.lightIndex = index list[index].scrollIntoView() } }) }, searchNext () { this.$nextTick(() => { let idx if(this.lightIndex >= this.matchCount-1){ this.lightIndex = 0 idx = 0 }else{ idx = this.lightIndex + 1 } this.scrollTo(idx) }) }, searchLast () { this.$nextTick(() => { let idx if(this.lightIndex <= 0){ idx = this.matchCount - 1 this.lightIndex = this.matchCount - 1 }else{ idx = this.lightIndex - 1 } this.scrollTo(idx) }) }, getMatchCount () { this.$nextTick(() => { let list = this.$el.querySelectorAll(`.search-hightlight`) this.matchCount = list.length }) }, clickSearch(){ let reg = new RegExp(this.inputLogValue, 'ig') let stringList = this.logMessage.split(reg) if (stringList.length) { this.searchStatus = 1 this.contentShow = '' this.lightIndex = 0 for (let i = 0; i < stringList.length - 1; i++) { let style = i === this.lightIndex ? this.currentStyle : this.highlightStyle this.contentShow += `${stringList[i]}<font style="${style}" class='search-hightlight'>${this.inputLogValue}</font>` } this.contentShow += stringList[stringList.length - 1] this.getMatchCount() this.scrollTo(this.lightIndex) } }, }
总结
到此这篇关于Vue关键字搜索功能实战案例的文章就介绍到这了,更多相关Vue关键字搜索内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论