fuse.js
Bootstrap3:Typeahead.js或者magicsuggest.js
JQuery autocomplete和Select2
模糊匹配选项
includeMatches
- 类型:boolean
- 默认值:false 是否应该将匹配包含在结果集中。当为true时,结果集中的每条记录都将包含匹配字符的索引。因此,这些可以用于突出显示的目的。
minMatchCharLength
- 类型:number
- 默认值:1只有长度超过该值的匹配才会返回。(例如,如果您想忽略结果中的单个字符匹配,请将其设置为2)
location
- 类型:数字
- 默认值:0确定文本中期望找到的模式的大约位置。
threshold
- 个人实验为 精确度
- Type:
number
- Default:
0.6
- 匹配算法在什么点放弃。阈值为0.0需要完全匹配(字母和位置),阈值为1.0可以匹配任何东西。
- 字母和位置: 是否需要模糊匹配,
- 0.5:中人 --》 中农过人 or 中国人民 都会匹配
- 0.1:中人 --》 中人bai or 中人大学 精确到位置完全的精度
- 字母和位置: 是否需要模糊匹配,
distance
- 字符的长度 个人实验为 threshold * distance
- Type:
number
- Default:
100
- 确定匹配必须与模糊位置有多近(由 location 指定)。一个精确的字母匹配,即字符与模糊位置的距离,将得分为完全不匹配。0的距离要求匹配在指定的精确位置。1000的距离需要完美匹配,使用0.8的阈值在800个字符内找到位置。
ignoreLocation
- Type:
boolean
- Default:
false
- 当为true时,搜索将忽略位置和距离,因此模式出现在字符串中的哪个位置并不重要。
- 提示默认选项只搜索前60个字符。如果合理地预期匹配在这个范围内,这就足够了。要修改此行为,请设置适当的
location
,threshold
,distance
(orignoreLocation
)
100 * 0.6
Determines how close the match must be to the fuzzy location (specified by location
). An exact letter match which is distance
characters away from the fuzzy location would score as a complete mismatch. A distance
of 0
requires the match be at the exact location
specified. A distance of 1000
would require a perfect match to be within 800
characters of the location
to be found using a threshold
of 0.8
.
https://fusejs.io/api/options.html#threshold
new Fuse(list, {
shouldSort: true, // 是否按分数对结果列表排序
includeScore:true, // 是否应将分数包含在结果集中。0分表示完全匹配,1分表示完全不匹配。
threshold: 0.1, // 匹配算法阈值。阈值为0.0需要完全匹配(字母和位置),阈值为1.0将匹配任何内容。
location: 0, // 确定文本中预期找到的模式的大致位置。
distance: 100,
maxPatternLength: 32, // 模式的最大长度
minMatchCharLength: 1, // 模式的最小字符长度
keys: [
{
name: "title",
weight: 0.7,
},
{
name: "path",
weight: 0.3,
},
], // 搜索标题与路径
});
// 初始化
init() {
var options = {
shouldSort: true, // 是否按分数对结果列表排序
includeScore: true, // 是否应将分数包含在结果集中。0分表示完全匹配,1分表示完全不匹配。
threshold: 0.6, // 匹配算法阈值。阈值为0.0需要完全匹配(字母和位置),阈值为1.0将匹配任何内容。
/**
* 确定匹配与模糊位置(由位置指定)的距离。
* 一个精确的字母匹配,即距离模糊位置很远的字符将被视为完全不匹配。
* 距离 (字符的长度) 为0要求匹配位于指定的准确位置,
* 距离 (字符的长度) 为1000则要求
* 完全匹配 位于使用阈值0.8 找到 的 位置的800个字符以内
*/
location: 0, // 确定文本中预期找到的模式的大致位置。
distance: 100,
maxPatternLength: 32, // 模式的最大长度
minMatchCharLength: 1, // 模式的最小字符长度
// 搜索标题与作者名
keys: ["title", "author.firstName"]
};
// 设置数据与参数
this.fuse = new Fuse(this.books, options);
}
}
配置项 | 描述 | 默认值 | 说明 |
---|---|---|---|
isCaseSensitive | 大小写敏感 | FALSE | |
includeScore | 结果包含匹配度 | FALSE | 结果值:0表示完全匹配,1表示完全不匹配 |
includeMatches | 结果包含匹配字符的索引值 | FALSE | 可用于高亮显示搜索字符的场景 |
minMatchCharLength | 最小匹配长度 | 1 | 可用于需要至少几个字符才执行搜索的场景 |
shouldSort | 结果集排序 | TRUE | 结果集按照匹配度排序 |
findAllMatches | 查找所有项目 | FALSE | 即使找到了完全匹配项目也继续查找完其他所有项目 |
keys | 查找字段配置 | 被查字段的路径(支持嵌套查找),权重(默认权重值为1),例如:[‘name.first’,{name:‘name.last’,weight:0.5}] | |
location | 匹配的字符预期的位置 | 0 | 匹配到的字符距离指定位置越近分数越高 |
threshold | 匹配度阈值 | 0.6 | 0.0表示完全匹配(字符和位置);1.0将会匹配所有值 |
distance | l匹配的字符在location指定位置的范围 | 100 | 0表示必须正好在location指定的位置 |
ignoreLocation | 忽略location配置参数 | FALSE | location和distance都会被忽略 |
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../bootstrap/css/bootstrap.min.css">
<script src="../assets/jquery.js"></script>
<script src="../bootstrap/js/bootstrap.bundle.js"></script>
<script src="../assets/vue.js"></script>
<script src="../assets/search/fuse.js"></script>
<style>
.aa {
background-color: #edeede;
}
.sear {
height: 300px;
}
.st {
background-color: rgb(113, 182, 171);
}
.dropdown-menu {
position: relative;
top: 0;
}
.pmu {
display: flex;
flex-direction: column;
}
.uili {
/* border: 1px solid black; */
margin: 3px;
}
.uili:hover {
cursor: pointer;
transform: scale(0.99);
background-color: #ededed;
border-radius: 3px;
}
.searchipt {
background-color: rgb(140, 222, 216);
outline: none;
border: none;
}
</style>
</head>
<body>
<div id="vapp" class="container-fluid aa">
<div class="row">
<div class="col-md-12 st"> </div>
</div>
<div class="row sear" style="background-color:#ededed ;">
<div class="col-md-2 st"> </div>
<div class="col-md-8">
<input type="text" @focus="onFocus($event)" v-model:value="menuName"
class="form-control col-md-4 searchipt" placeholder="Username" aria-label="Username">
<ul class="dropdown-menu pmu col-md-4">
<li class="uili" v-for="item in uls" @click='casUrl(item)' :key="item.id">
{{ item.name}}
</li>
</ul>
</div>
<div class="col-md-2 st">22
</div>
<div>
</div>
</div>
</div>
</body>
<script>
new Vue({
el: '#vapp',
data() {
return {
msg: 'hello world',
menuName: '',
uls: [{
id: 1,
name: 'aaa'
},
{
id: 2,
name: 'bbb'
},
{
id: 3,
name: 'ccc'
}
]
}
},
methods: {
onFocus(e) {
console.log(this)
console.log((this.menuName))
console.log(e)
},
casUrl(item) {
const {
id,
name
} = item
console.log(id, name)
}
},
watch: {
'menuName'(newValue, oldValue) {
console.log(oldValue, '<===原来 to 新===>', newValue)
if (newValue == '') {
$('.dropdown-menu').hide()
} else {
const list = [{
"title": "申天暗室逢灯",
"author": {
"firstName": "John",
"lastName": "Scalzi"
}
}, {
"title": "提哈德发大发天",
"author": {
"firstName": "John",
"lastName": "Scalzi"
}
}, {
"title": "三个月后单位",
"author": {
"firstName": "John",
"lastName": "Scalzi"
}
}, {
"title": "他说的感动",
"author": {
"firstName": "John",
"lastName": "Scalzi"
}
},
{
"title": "赵agag大幅度发给的天",
"author": {
"firstName": "Steve",
"lastName": "Hamilton"
}
},
{
"title": "申庄人",
"author": {
"firstName": "Remy",
"lastName": "Sharp"
}
},
{
"title": "李白白",
"author": {
"firstName": "P.D",
"lastName": "Woodhouse"
}
},
{
"title": "白天和黑夜",
"author": {
"firstName": "P.D",
"lastName": "Woodhouse"
}
},
{
"title": "韩申",
"author": {
"firstName": "P.D",
"lastName": "Woodhouse"
}
}
]
const fuse = new Fuse(list, {
// isCaseSensitive: false,
// includeScore: false,
shouldSort: true,
// includeMatches: false,
// findAllMatches: false,
// minMatchCharLength: 1,
// location: 0,
threshold: 0.3,
// distance: 100,
// useExtendedSearch: false,
// ignoreLocation: false,
// ignoreFieldNorm: false,
// fieldNormWeight: 1,
keys: [{
name: "title",
weight: 0.5,
}, ]
});
console.log('search /// / ', fuse.search(newValue))
let rls = fuse.search(newValue)
let varr = []
for (let {
item,
refIndex
} of rls) {
console.log(item.title)
varr.push({
id: refIndex,
name: item.title
})
}
this.uls = varr
$('.dropdown-menu').show()
}
}
},
mounted() {
$('.dropdown-menu').show()
console.log('init app')
}
})
</script>
</html>
输入框自动补全
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<script>
$(function () {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$("#tags").autocomplete({
source: availableTags
});
});
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>