300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > JS实现拼音(字母)匹配(搜索)汉字(姓名)

JS实现拼音(字母)匹配(搜索)汉字(姓名)

时间:2022-07-06 05:00:51

相关推荐

JS实现拼音(字母)匹配(搜索)汉字(姓名)

这就是个模糊查询,我们平常做的都是直接输入汉字去把对应的值过滤出来,但我还真是第一次通过拼音去查询(当然不只是拼音,汉字也是可以的),以前还真没注意这个。唉,这可咋搞,我怎么知道某个汉字(字符串)的拼音的首字母是什么呢?正当我愁眉苦脸的时候,哎,一个库被我发现了,hhhhh~。就是pinyin-match。下面介绍该包的使用,这个包也不大,四百多kb。蛮高效的。下面介绍一下该库的使用

npm官方:/package/pinyin-match

1. 首先说下功能:

它能够使用拼音快速检索目标。当然也可以使用汉字

简体版27KB (gzip ≈ 19KB),繁体版86KB (gzip ≈ 60KB)支持多音字、繁体字、拼音首字母匹配,具备分词功能返回位置信息,可用于高亮匹配字符在长多音字串下依然有高性能

在线演示:http://laosep.top/pinyin-match/

2. 安装:

npm install pinyin-match --save

3. 引入:

简体版:

import PinyinMatch from 'pinyin-match'; // es const PinyinMatch = require('pinyin-match'); // commonjs

繁体版:

import PinyinMatch from 'pinyin-match/es/traditional.js'; // es const PinyinMatch = require('pinyin-match/lib/traditional.js'); // commonjs

当然也可以script引入

// 简体:<script src="pinyin-match/dist/main.js"></script>// 繁体:<script src="pinyin-match/dist/traditional.js"></script>

4. API:

.match(input, keyword) //查询匹配拼音的数据。

只向外提供暴露了这么一个方法,这一个方法足够我们使用了,也很方便

参数:

input{string}目标字符串keyword{string}输入的拼音或其他关键词

返回:

Array | Boolen

5. 简单使用测试示例:

let test = '123曾经沧海难为水除却巫山不是云'PinyinMatch.match(test, '23曾'); // [1, 3]PinyinMatch.match(test, 'cjc') // [3, 5]PinyinMatch.match(test, 'cengjingcanghai') // [3, 6]PinyinMatch.match(test, 'cengjingcangha') // [3, 6]PinyinMatch.match(test, 'engjingcanghai') // falsePinyinMatch.match(test, 'zengjingcang') // [3, 5]PinyinMatch.match(test, 'sdjkelwqf') // falsePinyinMatch.match(test, 'zengji ng cang') // [3, 5]PinyinMatch.match(test, 'zengji ng cangsdjfkl') // falsePinyinMatch.match(' 我 爱你 中 国 ', 'nzg') // [6, 12]PinyinMatch.match(' 我 爱你 中 国 ', '爱你中') // [5, 8]PinyinMatch.match('發', 'fa') // [0, 0]

6.具体案例:

就是平常的列表展示加模糊搜索。所用的人员列表测试数据都是下面这种格式,章末会把完整测试数据附上。

// 模拟后端返回的数据export default [{name: '管理员',no: 'FT00000'},//...]

其实很简单的了,主要是实现拼音的搜索过滤的功能,所以我案例里面样式也没调,主要是功能

闲话不说了,直接上完整代码,大家看下里面的逻辑都明白了,就这么一个组件:

<template><div class="main"><input type="text" v-model="serchValue" placeholder="输入搜索"><div class="user" v-for="(user, index) in users" :key="user.no">{{ index }}# : {{ user.name }}</div></div></template><script>import userList from './data/user'import PinyinMatch from 'pinyin-match'let timer = nullexport default {data() {return {serchValue: '',userListAll: [], // 所有数据users: [] // 展示的数据}},watch: {serchValue() {this.debounce(this.selectUser, 200)}},mounted(){this.getUserList()},methods:{// 模拟请求getUserList() {setTimeout(() => {this.userListAll = userListthis.selectUser()}, 100)},// 防抖debounce(fn, wait) {if(timer) clearTimeout(timer)timer = setTimeout(() => {fn.call(this)timer = null}, wait)},// 模糊查询条件selectUser() {this.users = []// 如果搜索框有值的话再去过滤,因为PinyinMatch.match第二个参数是空字符串的话会匹配不到,返回false,这不符合我们的预期// 搜索框没有值,我们要展示所有数据if(this.serchValue) {this.userListAll.forEach(user => {let matchIndexs = PinyinMatch.match(user.name, this.serchValue) // 如果匹配到返回 首尾的索引数组,如果匹配不到则返回falseif(matchIndexs) {this.users.push(user)}})} else {this.users = this.userListAll}}}}</script><style scoped>.main {width: 100vw;height: 100vh;padding: 200px 0 0 200px;box-sizing: border-box;}.main input {margin-bottom: 5px;}</style>

接下来看下效果:

接下来!我们可以把上面的示例再提高点儿难度,因为让我想起了通讯录,所以在展示的时候我们就像通讯录那样展示

首先将拿到的人员列表进行分组,根据什么分呢?就是根据字母,a、b、c...这样,难道我们要把26个英文字母全都列出来吗?当然这个也分需求,但如果是通讯录的话,我们只需要百家姓中所有的拼音的首字母就可以了,也就是:abcdefghjklmnopqrstwxyz 这些。

在上面示例的基础上进行修改,在拿到人员数据之后,先处理一下,然后再进行过滤模糊查询

完整代码:

<template><div class="main"><input type="text" v-model="serchValue" placeholder="输入搜索"><div class="users" v-for="user in users" :key="user.key"><div>{{ user.key }}</div><div class="user-name" v-for="o in user.data" :key="o.no">{{ o.name }}</div></div></div></template><script>import userList from './data/user'import PinyinMatch from 'pinyin-match'let timer = nullexport default {data() {return {serchValue: '',userListAll: [], // 所有数据users: [] // 展示的数据}},watch: {serchValue() {this.debounce(this.selectUser, 200)}},mounted(){this.getUserList()},methods:{// 模拟请求getUserList() {setTimeout(() => {this.userListAll = this.handlerData(userList)this.selectUser()}, 100)},// 处理数据handlerData(userList) {// 这是百家姓中所有的拼音的首字母const surnameLetters = 'abcdefghjklmnopqrstwxyz'.split('')const userListAll = []surnameLetters.forEach(letter => {let o = { key: letter, data: [] }userList.forEach(user => {let matchIndexs = PinyinMatch.match(user.name.slice(0, 1), letter) // 匹配姓氏的拼音的首字母if(matchIndexs) {o.data.push(user)}})if(o.data.length) {userListAll.push(o)}})return userListAll},// 防抖debounce(fn, wait) {if(timer) clearTimeout(timer)timer = setTimeout(() => {fn.call(this)timer = null}, wait)},// 模糊查询条件selectUser() {this.users = []if(this.serchValue) {this.userListAll.forEach(user => {let o = { key: user.key, data: [] }user.data.forEach(item => {let matchIndexs = PinyinMatch.match(item.name, this.serchValue)if(matchIndexs) {o.data.push(item)}})if(o.data.length) {this.users.push(o)}})} else {this.users = this.userListAll}}}}</script><style scoped>.main {width: 100%;height: 100%;padding: 0 0 0 200px;box-sizing: border-box;}.main input {margin-bottom: 5px;}.user-name {padding-left: 10px;}</style>

最后看下修改后的效果:

接下来是上面测试用的数据

export default [{"name": "管理员","no": "FT00000"},{"name": "朱大锤","no": "FT00001"},{"name": "郝大锤","no": "FT00002"},{"name": "宋大锤","no": "FT00003"},{"name": "杨大锤","no": "FT00004"},{"name": "石大锤","no": "FT00005"},{"name": "郑大锤","no": "FT00006"},{"name": "刘大锤","no": "FT00007"},{"name": "赵大锤","no": "FT00008"},{"name": "李大锤","no": "FT00009"},{"name": "牛二","no": "FT00010"},{"name": "张大锤","no": "FT00011"},{"name": "王大锤","no": "FT00012"},{"name": "冯大锤","no": "FT00013"},{"name": "李大锤","no": "FT00014"},{"name": "邓大锤","no": "FT00015"},{"name": "孙大锤","no": "FT00016"},{"name": "袁大锤","no": "FT00017"},{"name": "康大锤","no": "FT00018"},{"name": "武大锤","no": "FT00019"},{"name": "蔡大锤","no": "FT00020"},{"name": "戴大锤","no": "FT00021"},{"name": "鄂大锤","no": "FT00022"},{"name": "封大锤","no": "FT00023"},{"name": "盖大锤","no": "FT00024"},{"name": "景大锤","no": "FT00025"},{"name": "麻大锤","no": "FT00026"},{"name": "那大锤","no": "FT00027"}]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。