【Vue】v-html 功能加强

v-html 的功能是替换元素的 innerHTML,在大部分场景下都够用,但是因为是直接替换 innerHTML 所以无法用 Vue 的事件监听方法。下面引入一个需求,来实现这个功能。

需求

  1. 后端传来一串文本,我们需要把该文本中特定的字符替换成链接元素
  2. 在链接元素后面,加个搜索icon,用户点击该icon的时候执行某个预先定义的方法

第一个需求很容易搞定,思路如下:

  1. 用正则替换所有关键字位 a 元素
  2. v-html 把获取到的结果直接放到 DOM 里
    .
    但是前面说了,用 v-html 无法实现事件监听,解决方法是使用渲染函数

实现功能

在线预览

<script setup>
import { h, ref } from 'vue'
function searchText(text) {
  alert(text)
}
  
function textWithLink({ text = '' }) {
  const splitWord = '*#@$@#)()'
  const patterns = [/(sm\d+)/g, /(av\d+|BV\w+)/g]
  
  for(const reg of patterns) {
    text = text.replace(reg, splitWord + '$1' + splitWord)
  }
  
  const words = text.split(splitWord).filter(word => word != '')
  
  const children = []
  for(const word of words) {
    const isTarget = patterns.filter(pattern => pattern.test(word)).length > 0
    if(isTarget) {
       children.push(h('span', null, [
         h('a', {href: 'https://t.me'}, word),
         h('span', {
        	onclick: () => searchText(word)
         }, 'search')
       ]))
    } else {
      children.push(word)
    }
  }
  
  return h('pre', children)
}
  
const  text = `
	hello world
  av1234
  sm0000
  BV0000
`
</script>
	
<template>
	<textWithLink class="text" :text="text"/>
</template>

<style scoped>
  .text{
    white-space: pre-line;
  }
</style>

思路是拆分关键字,然后对关键字的类型进行判断,如果是要转成链接的关键字,则用 h('a') 包裹,否则直接传入 h 函数作为文本元素。

补充

渲染函数和函数式组件
函数式组件实际类似 react 中的同名概念,这个组件没有 this,是无状态的(不会更改函数外部的状态,同样的输入,同样的输出)。

渲染函数就是 h 函数(?)。

VNode 可以直接在 template 中当组件使用。

如果你是 Vue2 版本,则渲染函数还有所不同,具体表现在

  • 导入方式 - Vue2 h 是作为 render 函数的参数传入
  • VNode 的属性设置 h('a', {onclick: xxx}, 'text') 在 vue3 中是可以直接使用的,而 vue2 中需要写成这样: h('a', {on: {onclick: xxx}}, 'text') ,具体规则可见官方文档
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值