37 lines
1.2 KiB
Vue
37 lines
1.2 KiB
Vue
<script setup lang="ts">
|
|
// 变更后单元格蓝色高亮
|
|
import { computed } from "vue";
|
|
import { useThemeStore } from '@/store/modules/theme';
|
|
|
|
const themeStore = useThemeStore();
|
|
const props = defineProps<{ text: string; hl?: string[] }>();
|
|
interface Seg { t: string; hit: boolean }
|
|
const segs = computed<Seg[]>(() => {
|
|
const text = props.text;
|
|
if (!props.hl || props.hl.length === 0) return [{ t: text, hit: false }];
|
|
const out: Seg[] = [];
|
|
let rest = text;
|
|
const hls = [...props.hl].sort((a, b) => b.length - a.length);
|
|
while (rest.length) {
|
|
let idx = -1, kw = "";
|
|
for (const h of hls) {
|
|
const i = rest.indexOf(h);
|
|
if (i >= 0 && (idx < 0 || i < idx)) { idx = i; kw = h; }
|
|
}
|
|
if (idx < 0) { out.push({ t: rest, hit: false }); break; }
|
|
if (idx > 0) out.push({ t: rest.slice(0, idx), hit: false });
|
|
out.push({ t: kw, hit: true });
|
|
rest = rest.slice(idx + kw.length);
|
|
}
|
|
return out;
|
|
});
|
|
</script>
|
|
<template>
|
|
<span class="whitespace-pre-line"><template v-for="(s, i) in segs" :key="i">
|
|
<mark
|
|
v-if="s.hit" class="rounded bg-blue-100 px-0.5"
|
|
:style="{color: themeStore.themeColor}"
|
|
>{{ s.t }}</mark>
|
|
<template v-else>{{ s.t }}</template></template></span>
|
|
</template>
|