先导入js-pinyin的包
npm i js-pinyin
接着在需要使用的页面引入
<div class="searchBox">
<form action="" class="searchNav">
<input type="text" :placeholder="`${holderTitle}`" v-model="searchTerm" @focus="showSearchRes = true"
@input="handleQueryChange" />
<i :class="`icon-${searchLog}`"></i>
</form>
<!-- 搜索结果 -->
<div class="search-answer-box" v-if="showSearchRes">
<div class="search-answer-info" v-for="(result,i) in abilityRes" :key="i" @click="goSearchMod(result)">
{{ result }}</div>
</div>
</div>
import pinyin from 'js-pinyin'
data(){
return{
showSearchRes: false,
boardAbility: ['人员档案', '评价系统', '物联网', '校园监控', '选课系统', '信息发布', '录播系统', '校园广播', '接送系统', '教育局', '阳光校园平台', '总览面板',
'数据面板', '自定义面板'
],
abilityRes: [],
searchTerm: '',
}
mounted() {
const pinyin = require('js-pinyin');
pinyin.setOptions({
checkPolyphone: false,
charCase: 0
});
},
接着实现查询逻辑
handleQueryChange() {
const searchLowercase = this.searchTerm.toLowerCase();
const pinyinSearch = pinyin.getFullChars(this.searchTerm).toLowerCase();
this.abilityRes = this.boardAbility.filter(item => {
const pinyinResult = pinyin.getFullChars(item).toLowerCase();
const similarity = this.calculateSimilarity(pinyinResult, pinyinSearch);
return (
similarity >= 0.3 ||
pinyinResult.includes(searchLowercase) ||
item.includes(this.searchTerm)
)
})
this.showSearchRes = true
if (this.searchTerm == '') {
this.showSearchRes = false
this.abilityRes = []
}
},
calculateSimilarity(str1, str2) {
const len1 = str1.length
const len2 = str2.length
if (len1 === 0) return len2
if (len2 === 0) return len1
const dp = Array.from(Array(len1 + 1), () => Array(len2 + 1).fill(0));
for (let i = 0; i <= len1; i++) dp[i][0] = i
for (let j = 0; j <= len2; j++) dp[0][j] = j
for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1
dp[i][j] = Math.min(
dp[i - 1][j] + 1,
dp[i][j - 1] + 1,
dp[i - 1][j - 1] + cost
);
}
}
return 1 - dp[len1][len2] / Math.max(len1, len2)
},