github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/components/Highlight/src/Highlight.vue (about) 1 <script lang="tsx"> 2 import { defineComponent, PropType, computed, h, unref } from 'vue' 3 import { propTypes } from '@/utils/propTypes' 4 5 export default defineComponent({ 6 name: 'Highlight', 7 props: { 8 tag: propTypes.string.def('span'), 9 keys: { 10 type: Array as PropType<string[]>, 11 default: () => [] 12 }, 13 color: propTypes.string.def('var(--el-color-primary)') 14 }, 15 emits: ['click'], 16 setup(props, { emit, slots }) { 17 const keyNodes = computed(() => { 18 return props.keys.map((key) => { 19 return h( 20 'span', 21 { 22 onClick: () => { 23 emit('click', key) 24 }, 25 style: { 26 color: props.color, 27 cursor: 'pointer' 28 } 29 }, 30 key 31 ) 32 }) 33 }) 34 35 const parseText = (text: string) => { 36 props.keys.forEach((key, index) => { 37 const regexp = new RegExp(key, 'g') 38 text = text.replace(regexp, `{{${index}}}`) 39 }) 40 return text.split(/{{|}}/) 41 } 42 43 const renderText = () => { 44 if (!slots?.default) return null 45 const node = slots?.default()[0].children 46 47 if (!node) { 48 return slots?.default()[0] 49 } 50 51 const textArray = parseText(node as string) 52 const regexp = /^[0-9]*$/ 53 const nodes = textArray.map((t) => { 54 if (regexp.test(t)) { 55 return unref(keyNodes)[t] || t 56 } 57 return t 58 }) 59 return h(props.tag, nodes) 60 } 61 62 return () => renderText() 63 } 64 }) 65 </script>