vue3 通过fuse.js 实现前端模糊查询

发布时间 2023-05-08 15:30:50作者: kitty20180903suzhou

在项目中写好多个查询组件:

举个栗子:

<template>
    <!-- 获取客户下拉数据,type 0 有限公司 -->
    <el-select v-model="current" :multiple="multiple" remote :remote-method="querySearch" :suffix-icon="loading ? '' :''" :loading="loading" loading-text="数据加载中..." filterable clearable placeholder="搜索客户名称/法人、负责人姓名/手机号" :style="{'width':width || '300px'}">
        <template #empty>
            <div style="font-size:14px;padding:30px">
                未找到相关客户信息,请前往 <el-button link type="primary" @click="router.push('/customer/index')">客户管理</el-button> 中添加
            </div>
        </template>
        <el-option
            v-for="option in options"
            :key="option.item.customerId"
            :label="option.item.name"
            :value="option.item[searchBy || 'customerId']">
        </el-option>
    </el-select>
</template>

<script setup>
import {getList as getAllCustomers} from "@/api/customer";
import Fuse from 'fuse.js'
const { proxy } = getCurrentInstance()
const props = defineProps(['value','searchBy','multiple','width'])
const emits = defineEmits(['update:value','selected'])
// 使用路由
const router = useRouter()
const fuse = ref(undefined); // 模糊查询插件
const list = ref([])
const loading = ref(false)
const options = ref([])
const current = computed({
  get: () => props.value,
  set: (val) => {
    emits('update:value', val)
  }
});
watch([()=>current.value, ()=>list.value],([newVal, newList])=>{
    if(!props.multiple){
        const selected = newList.find(z=>z[props.searchBy || 'customerId'] == newVal)
        emits('selected',selected)
        if(fuse.value){
            querySearch(newVal || '')
        }
    }else{
        const selected = newList.filter(z=>newVal.includes(z[props.searchBy || 'customerId']))
        emits('selected',selected)
    }
})
// 获取数据
const getList =(value)=>{
    const queryParams= {
        status: "0", // 正常
        checkStatus:"1", // 审核通过
        customerType: '0', //0 有限公司 1 个体户
        customerName:value // 搜索名字
    }
    loading.value = true
    getAllCustomers(queryParams).then(res=>{
        if (res.code = 200){
            list.value = res.data || []
            initFuse()
            querySearch(current.value || '')
        }else{
            proxy.$modal.msgError(res.msg || "请求发生错误,请稍后重试")
        }
    }).finally(()=>{
        loading.value = false
    })
}
// 初始化模糊查询插件
const initFuse =()=> {
    fuse.value = new Fuse(list.value, {
        shouldSort: true,
        threshold: 0.4, // 匹配算法阈值。阈值为0.0需要完全匹配(字母和位置),阈值为1.0将匹配任何内容。
        /**
         * 确定匹配与模糊位置(由位置指定)的距离。一个精确的字母匹配,即距离模糊位置很远的字符将被视为完全不匹配。
         *  距离为0要求匹配位于指定的准确位置,距离为1000则要求完全匹配位于使用阈值0.8找到的位置的800个字符以内。
         */
        location: 0,// 确定文本中预期找到的模式的大致位置。
        distance: 100,
        minMatchCharLength: 1,
        // 查询字段
        keys: ['customerId','customerName','clientContacts','clientPhones','legalName','legalPerson','legalTel']
    })
}
const querySearch =(query)=> {
  if (query !== '') {
    options.value = fuse.value.search(query)
  } else {
    options.value = []
  }
}
onMounted(()=>{
    getList()
})
</script>

<style>

</style>