最终效果
<template>
<div class="filterBox">
<input type="text" v-model="searchText" />
<ul>
<li v-for="item in filteredItems" :key="item.id">
<span v-html="highlightText(item.text)"></span>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
// 输入
searchText: "",
// 参数
items: [
{ id: 1, text: "张三" },
{ id: 2, text: "张三丰" },
{ id: 3, text: "赵云伟" },
{ id: 4, text: "王伟" },
{ id: 5, text: "楚云飞" },
],
};
},
computed: {
// 计算属性
filteredItems() {
// 为空 直接返回原数组
if (!this.searchText.trim()) {
return this.items;
}
// 不为空 返回符合条件item
return this.items.filter((item) => item.text.includes(this.searchText));
},
},
methods: {
// 渲染回调函数
highlightText(value) {
// g:全局,i:不区分大小写
const regex = new RegExp(this.searchText, "gi");
// 把需要渲染的参数,转换输入的关键字。增加类名形成高亮效果!
return value.replace(
regex,
`<span class="highlight">${this.searchText}</span>`
);
},
},
};
</script>
<style scoped>
.highlight {
color: red;
}
</style>
<style >
/* 一定要注意这里!!!!!!!!
如果你使用了一个<style>标签,并且增加了scoped属性,你会发现你写的代码死活就是不起效。
用v-html生成的html代码,在样式中的定义不会生效,查资料如下:
在单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被Vue 的模板编译器处理。
如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局<style>元素手动设置类似 BEM 的作用域策略。
解决方法最简单的样式穿透
*/
.highlight {
color: red;
}
</style>