前言:
这段时间突然发现很少写博客了,平时都在平衡工作和休息的时间,周末也没动过笔,而且更重要的是我找不到写的内容了,在经历的初始的新知识的学习阶段后,目前的阶段更加转入对于业务的理解,很多模块在不同项目中都是可以复用的。
而且工作中发现开发并不强求特别酷炫的界面效果,更多的是实用的数据展示,因此button,form,table可以说是最常用的,因此后面可能会用更多的篇幅去说这块内容的知识。
一、组件介绍
autocomplete是input组件的一个分支,专门用来处理模糊匹配的相关知识,很多时候用户希望输入一个单词就可以自动匹配到相关的内容,这时候就是这个组件发挥作用的地方了。
在这里也能看到官网的相关介绍
二、基本原理
将输入的名称与字典库进行匹配,然后输出成功字段。
这里的匹配时存在两种情况,一种是通过后端接口进行匹配,一种是前端进行匹配,我的感觉是如果是少量的数据可以交给前端,如果数据量过大可能后端匹配完了再输出比较好。
三、具体实现
- 【后端实现法】
因为涉及到接口所以只会说一下流程,重点介绍前端实现。
后端匹配不需要获取字典,你只需要把前端输入字符传给后端,等后端匹配好后把结果给你,然后你再将结果返回到页面就好了。
(querySearch, cb)
是固定格式,前者代表输入的字段,后者是个方法,代表输出的结果
- 【前端实现法】
前端实现的页面样式与后端一样,这里请求的@Select
是为了处理选择后的结果
因为是前端自己处理,所以需要先获取总字典序,将其存储在一个变量里面
这样可以一进入页面就处理好总字典的内容。
具体要讲一下这个
querySearch
方法中可实现的内容
if--else
判断是看你想不想要用户不输入内容也进行匹配,如果默认用户输入内容才开始匹配,就只要if
内的内容就好(我这里是不输入也会匹配)
- 上文以及提到
cb()
中输出返回的结果,这里results
变量就是你想返回的结果,具体如何根据你的匹配方法决定,一般都是输入一个字符返回匹配到的结果,但是也可以不这么匹配.
实现原理是之前定义的list
里面有label
和name
字段,你可以处理用户输入的时候按name
字段,输出的是label
字段,这样就实现了中英文匹配的情况.- 需要注意的是匹配的结果
results
中的value
字段才会在页面上展示,如果你最后返回的list没有这个字段,页面上是不会展示内容的,这也让前端可以实现自定义展示.
- 最后想说明的是匹配的方法,有首字母的匹配以及模糊匹配,首字母的就是从头开始,如果第一个字符不匹配就放弃,模糊的是如果整个字符串有能匹配的字段都会输出,具体情况可以看演示.
首字母匹配
模糊匹配
具体方法我已经封装了,这里忽略大小写
handleSelect
主要用来处理选中后的结果,如果不处理默认就是list表中的内容
四、源码
<template>
<div class="autoComplete">
<el-form style="margin:30px" label-width="180px" label-position="right">
<el-form-item label="后端进行搜索并匹配:">
<el-autocomplete placeholder="请输入匹配内容" v-model="matchName" :fetch-suggestions="querySearchAsync"></el-autocomplete>
</el-form-item>
<el-form-item label="前端自行匹配:">
<el-autocomplete placeholder="请输入匹配内容" v-model="searchName" :fetch-suggestions="querySearch" @select="handleSelect"></el-autocomplete>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getCurrentInstance, onMounted, reactive, ref } from 'vue'
export default {
setup () {
const { proxy } = getCurrentInstance()
const searchName = ref('')
const matchName = ref('')
const totalData = ref([])
let timeOut = reactive()
/**获取总查询表信息 */
const getList = () => {
try {
// 这里应该请求接口
totalData.value = list
} catch (error) {
proxy.$message.error(error.message)
}
}
/**搜索结果 */
const querySearch = (querySearch, cb) => {
let results = []
if (querySearch) {
const findout = totalData.value.filter((x) => nameFilter(x, querySearch))
results = findout.map(x => ({ ...x, value: x.label }))
} else {
results = totalData.value.map(x => ({ ...x, value: x.label }))
}
console.log(results, '结果')
clearTimeout(timeOut)
timeOut = setTimeout(() => {
cb(results)
}, 1000);
}
/**选择的结果 */
const handleSelect = (item) => {
console.log(item, '选择结果')
searchName.value = "[label:" + item.label + "; name:" + item.name + "]"
}
/**模糊匹配方法 */
const nameFilter = (item, querySearch) => {
return item.label.toLowerCase().match(querySearch.toLowerCase()) ? true : false
}
/**首字母匹配法 */
const firstCharFilter = (item, querySearch) =>
item.label.toLowerCase().indexOf(querySearch.toLowerCase()) === 0
/**请求后端接口检索 */
const querySearchAsync = (querySearch, cb) => {
let results = []
if (querySearch === '') {
cb(results)
} else {
try {
// 请求接口
const res = []
results = res
cb(results)
} catch (error) {
proxy.$message.error(error.message)
}
}
}
onMounted(() => {
getList()
})
const list = [
{ id: 101, label: "angle", name: "角;角度" },
{ id: 102, label: "ant", name: "蚂蚁" },
{ id: 103, label: "apple", name: "苹果" },
{ id: 104, label: "arch", name: "拱形;弧形" },
{ id: 105, label: "arm", name: "臂" },
{ id: 106, label: "army", name: "军队" },
{ id: 107, label: "baby", name: "婴儿" },
{ id: 108, label: "bag", name: "袋" },
{ id: 109, label: "ball", name: "球" },
{ id: 122, label: "bone", name: "骨" },
{ id: 123, label: "book", name: "书" },
{ id: 124, label: "boot", name: "靴" },
{ id: 125, label: "bottle", name: "瓶子" },
{ id: 126, label: "box", name: "箱;盒" },
{ id: 127, label: "boy", name: "男孩" },
{ id: 128, label: "brain", name: "脑" },
{ id: 129, label: "brake", name: "煞车" },
{ id: 130, label: "branch", name: "树枝" },
{ id: 131, label: "brick", name: "砖" },
{ id: 132, label: "bridge", name: "桥" },
{ id: 133, label: "brush", name: "刷子" },
{ id: 134, label: "bucket", name: "水桶" },
{ id: 135, label: "bulb", name: "球茎;灯泡" },
{ id: 136, label: "button", name: "纽扣" },
{ id: 150, label: "clock", name: "时钟" },
{ id: 151, label: "cloud", name: "云" },
{ id: 152, label: "coat", name: "外套,大衣" },
{ id: 153, label: "collar", name: "衣领" },
{ id: 154, label: "comb", name: "梳子" },
{ id: 155, label: "cord", name: "绳子" },
{ id: 156, label: "cow", name: "母牛" },
{ id: 157, label: "cup", name: "杯子" },
{ id: 158, label: "curtain", name: "帘;幕" },
{ id: 159, label: "cushion", name: "垫子" },
{ id: 160, label: "dog", name: "狗" },
{ id: 169, label: "eye", name: "眼睛" },
]
return {
searchName,
matchName,
querySearch,
handleSelect,
querySearchAsync
}
}
}
</script>