<template>
<span v-if="theme.showSearch">
<vab-icon icon="search-line" @click="openDialog" />
<!-- 模态框 -->
<el-dialog v-model="state.dialogVisible" :width="'40%'">
<el-form :model="state.queryForm" @submit.prevent>
<el-form-item label-width="0">
<!-- <el-autocomplete
v-model="state.queryForm.searchWord"
v-focus
:fetch-suggestions="querySearchAsync"
select-when-unmatched
@select="handleSelect"
>
<template #prefix><vab-icon icon="search-line" /></template> -->
<!-- 快速搜索 -->
<el-input
v-model="state.queryForm.searchWord"
v-focus
placeholder="快速搜索"
style="width: 100%"
>
<template #prepend>
<el-select v-model="select">
<el-option label="部件" :value="1" />
<el-option label="文档" :value="2" />
<el-option label="CAD文档" :value="3" />
<el-option label="申请单" :value="4" />
<el-option label="ECN" :value="5" />
</el-select>
</template>
<template #append>
<el-button icon="Search" @click="quickSearch" />
</template>
</el-input>
<!-- </el-autocomplete> -->
</el-form-item>
</el-form>
</el-dialog>
</span>
</template>
<script>
import { computed, defineComponent, onMounted, reactive, toRefs } from 'vue'
import { useStore } from 'vuex'
import { getList } from '@/api/search'
export default defineComponent({
name: 'VabSearch',
directives: {
focus: {
mounted(el) {
el.querySelector('input').focus()
},
},
},
setup() {
const store = useStore()
const theme = computed(() => store.getters['settings/theme'])
// let timeout = null
const state = reactive({
input1: '',
input2: '',
input3: '',
input4: '',
input5: '',
input6: '',
input7: '',
input8: '',
input9: '',
select: 1,
dialogVisible: false,
queryForm: {
searchWord: '',
},
restaurants: [],
})
const loadAll = async () => {
const {
data: { list },
} = await getList()
state.restaurants = list
}
onMounted(() => {
if (theme.value.showSearch) loadAll()
})
const openDialog = () => {
state.queryForm.searchWord = ''
state.dialogVisible = true
}
// 模糊查询
const quickSearch = () => {
console.log(quickSearch)
}
// const querySearchAsync = (queryString, cb) => {
// const restaurants = state.restaurants
// const results = queryString
// ? restaurants.filter(createFilter(queryString))
// : restaurants
// clearTimeout(timeout)
// timeout = setTimeout(() => {
// cb(results)
// }, 500)
// }
// const createFilter = (queryString) => (state) =>
// state.value.includes(queryString.toLowerCase())
// const handleSelect = (item) => {
// if (item.url) {
// window.open(item.url)
// } else {
// window.open(`https://www.baidu.com/s?wd=${item.value}`)
// }
// }
return {
theme,
state,
...toRefs(state),
openDialog,
quickSearch,
// createFilter,
// handleSelect,
// querySearchAsync,
}
},
})
</script>
<style lang="scss" scoped>
:deep() {
.el-input {
width: 180px;
&:first-child {
margin-right: 10px;
margin-bottom: 10px;
}
& + .el-input {
margin-right: 10px;
margin-bottom: 10px;
margin-left: 0;
}
}
.el-textarea {
width: 180px;
}
.el-select {
.el-input {
width: 100px;
margin-bottom: 0;
}
}
}
</style>
目前没什么思路
希望可以贴代码的时候,多写点注释,或者提供思路
下拉框选择选项,然后进行相应查询。实现快速搜索并且关键字高亮
查询出来的数据,点击后跳转相应页面关键字所在地。
由于没有后台数据,一切都是模拟,所以数据随意
用element-ui-plus的自动补全输入框,然后自定义建议内容插槽,就能实现关键词高亮了
你可以用关键词分割字符串然后显示
这里的arr是你远程获取到的快速搜索推荐项
<template v-for="(content,contentIndex) in arr.split(keyWord)" :key="contentIndex">
<span class="keyword" v-if="contentIndex !== 0">{{ keyWord }}</span>
<span>{{ content }}</span>
</template>
如有帮助,麻烦点个【采纳此答案】 谢谢啦~
拿官网远程搜索例子稍改了一下
主要思路就是搜索的数据,匹配关键字替换成包裹span标签,再v-html渲染
<template>
<div>
<h1>test</h1>
<el-autocomplete
v-model="state"
:fetch-suggestions="querySearchAsync"
placeholder="Please input"
@select="handleSelect">
<template #default="{ item }">
<div class="value" v-html="item.value"></div>
</template>
</el-autocomplete>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue'
export default defineComponent({
setup() {
const links = ref([])
const loadAll = () => {
return [
{ value: 'vue', link: 'https://github.com/vuejs/vue' },
{ value: 'element', link: 'https://github.com/ElemeFE/element' },
{ value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
{ value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
{ value: 'vuex', link: 'https://github.com/vuejs/vuex' },
{ value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
{ value: 'babel', link: 'https://github.com/babel/babel' },
]
}
let timeout
const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
const list = JSON.parse(JSON.stringify(links.value))
const results = queryString
? list.filter(createFilter(queryString))
: list
console.log(queryString)
if (queryString) {
// 匹配关键字
let replaceReg = new RegExp(queryString, 'g')
results.forEach(item => {
// 替换html
let replaceString = `<span class="search-text">${queryString}</span>`
// 开始替换
item.value = item.value.replace(replaceReg, replaceString);
})
}
clearTimeout(timeout)
timeout = setTimeout(() => {
cb(results)
}, 1000 * Math.random())
}
const createFilter = (queryString: string) => {
return (restaurant) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
)
}
}
const handleSelect = (item) => {
console.log(item)
}
onMounted(() => {
links.value = loadAll()
})
return {
links,
state: ref(''),
querySearchAsync,
createFilter,
loadAll,
handleSelect,
}
},
})
</script>
<style>
.search-text {
color: red;
font-weight: 700;
}
</style>
html也在学习
用element-ui-plus的自动补全输入框,自定义内容插槽
可以watch箭筒 select,select改变了,发起请求查询数据
书写相关css渲染和即时处理输入即可完成
我也遇到这个问题了,查了好多没解决
element UI 有相应功能解决