效果
使用实例
// 使用实例
<span :title="item.name" class="name" v-highlight="{style: { color: '#0084FE', backgoundColor: 'yellow' }, text: search}">{{item.name}}</span>
v-highlight源码
// v-highlight源码
import { objectAssign, camelToKebab } from '../util' // 见下文
const numberDirective = {
install(Vue) {
Vue.directive('highlight', {
bind(el, binding) {
const defaultOption = {
global: true, // 是否全局匹配
class: '',
style: 'color: #0084FF;', // 支持字符串和对象形式
text: '', // 需要高亮的关键字
tag: 'span',
ignoreCase: true // 是否忽略大小写
}
const option = objectAssign(defaultOption, binding.value || {})
const { text } = option
let { tag, style } = option
tag = tag || 'span'
if (Object.prototype.toString.call(style) === '[object Object]') {
style = Object.entries(style).reduce((prev, next) => `${prev}${prev === '' ? '' : ';'}${camelToKebab(next[0])}:${next[1]}`, '')
}
if (typeof text === 'string' && text.trim() !== '' && el) {
const reg = new RegExp(text, `${option.ignoreCase ? 'i' : ''}${option.global ? 'g' : ''}`)
el.innerHTML = el.innerHTML.replace(reg, `<${tag} class="${option.class}" style="${style}">${text}</${tag}>`)
}
},
})
}
}
export default numberDirective
// util.js
export function objectAssign(target, ...args) {
for (let i = 0, j = args.length; i < j; i++) {
const source = args[i] || {}
// eslint-disable-next-line no-restricted-syntax
for (const prop in source) {
// eslint-disable-next-line no-prototype-builtins
if (source.hasOwnProperty(prop)) {
const value = source[prop]
if (value !== undefined) {
target[prop] = value
}
}
}
}
return target
}
export function camelToKebab(name) {
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
}
export default {
objectAssign,
camelToKebab
}