fuse.js
Bootstrap3:Typeahead.js或者magicsuggest.jsJQuery 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>
