全栈实现搜索功能,前后端连载
解决搜索中文乱码问题:
1、使用encodeURI2次编码
var url=encodeURI(encodeURI(this.seachModel));
window.location.href ="/Search?query="+url;复制代码
2、定义全局方法解码,调用
//获取url中"?"符后的字串,使用两次decodeRUI解码
Vue.prototype.GetRequest = () =>{
var url =decodeURI(decodeURI(location.search));
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
var strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
return theRequest;
}
}
复制代码
3、接收参数页,encodeURI 2次解码
var url=encodeURI("/Search?query="+decodeURI(decodeURI(this.$route.query.query)))
history.pushState('', '', url)
this.goPage(this.num)
this.scroll()复制代码
实现效果:
1、搜索事件和按钮
基于element-ui 组件 开发的vue.js项目, 实现回车键发起搜索,和原生的input 标签使用方法不一样:
el-input 监听键盘按下状态 得用@keyup.enter.native,如果是非el-input 组件,可以直接用@keyup.enter
<el-input placeholder="请输入内容" @keyup.enter.native="seachModelFun" v-model="seachModel" class="input-with-select">
<el-button icon="el-icon-search" slot="append" @click="seachModelFun"></el-button>
</el-input>复制代码
方法,传参数去 Search 页
methods: {
seachModelFun(){
window.location.href="/Search?query="+this.seachModel
}
},
复制代码
search页
<template>
<div class="Search">
<div class="container">
<ListScroll :resData="resData" :total="total" @goPage="goPage"/>
</div>
</div>
</template>
<script>
import ListScroll from '@/components/common/ListScroll'
import common from '@/utils/common'
export default {
name: "Search",
components: {
ListScroll
},
data() {
return {
flag: true,
resData:[],
total:0,
num: 1 , //页码
pageNum:13, //记录数
count_page: '', // 数据总页数
}
},
created() {
this.goPage(this.num)
this.scroll()
},
methods:{
async goPage(x){
// 0,3 /3,3
let params={}
params.num = Number((x-1)*this.pageNum)
params.pageNum =this.pageNum
params.query = this.getUrl('query')
this.$axios.post("/api/ideas/Search",params)
.then(res=>{
if(res.data.code==1000){
if(Object.keys(res.data.data).length==0){
this.$message({message: '暂无数据!'})
this.flag = false
return false
}
this.count_page = (res.data.total % this.pageNum) == 0 ? parseInt(res.data.total / this.pageNum) : parseInt(res.data.total / this.pageNum + 1);
this.resData = [...this.resData,...res.data.data]
this.total = res.data.total
}else if(res.status===400){
this.dialog('查询出错了')
return false
}
})
},
scroll (){
common.scroll(()=>{
if(this.flag){
if(this.num > this.count_page){
return
}else{
this.num++
this.goPage(this.num)
}
}
});
}
}
};
</script>
<style scoped>
</style>
复制代码
服务端接口:搜索高亮显示,正则 gi (全局g,i不区分大小写)
let keyWords = document.getElementById('seachModels').value
res.data.data.forEach(v=>{
let replaceReg = new RegExp(keyWords, 'gi');
// 高亮替换v-html值
let replaceString = '<span class="searchText">' + keyWords + '</span>';
// 开始替换
v.title = v.title.replace(replaceReg, replaceString);
})
复制代码
数据展示组件就不放出来了
接下来是nodejs 处理后端数据
正则处理模糊查询
let reg = new RegExp(req.body.query,'i'),mtotal,num=Number(req.body.num),pageNum=Number(req.body.pageNum);
x.find({title:{$regex : reg},checkT:true}).count().then(data=>{
mtotal = data
})
复制代码