vue中用v-html插入元素,绑定事件失效了?一招搞定~

2,365 阅读2分钟

前言:最近在做一个需求,识别字符串中的链接,并加入点击事件,看起来非常简单,但是踩了不小的坑,完成了顺便写篇文章记录一下!

后端返回的字符串中,可能会包含换行符等特殊字符,为了能正确识别,使用了v-html,但是发现绑定的方法不执行,原来是因为 v-html 更新元素的 innerHTML,内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。如果功能很简单,使用组件就有些大材小用了,废话不多说,看下代码:
```const str = res.result.body;
   let regexp = /https?:\/\/[^ \n:,;)([\]:、,;()【】「」。@#]+/g; // 识别链接的正则
   const linkArr = str.match(regexp); // 匹配到链接后会返回链接字符串的数据,匹配不到返回null
   if(linkArr) { // 如果有链接
     const newLinkArr = [];
     linkArr.forEach(item => {
       newLinkArr.push(`<span onclick="openURL('${item}')" style="color: #356DBA">${item}</span>`);
     });
     let newStr = str;
     linkArr.forEach((item, index) => {
       newStr = newStr.replace(item, newLinkArr[index]); // 通过replace方法将拼接的模板字符串放回原字符串原来的位置上
     });
     this.optionsPostData.body = newStr;
   }


重点一:绑定方法要用 onclick,不是@click

然后在template中用v-html写上

<div class="content" v-html="optionsPostData.body" v-if="optionsPostData.body"></div>

重点二!!! 此时绑定的方法写在methods中是没用的,要写在mounted中,把方法挂载window上

```mounted() {
    window.openURL = function(url) {
      // 你的处理方式
    }
  }
我通过这种方式成功了,但是不知道适不适合你的代码

后序: 我用百度和谷歌搜了一天,总结了三种最为大家常用的解决办法,但是在我的代码里没有生效:

  1. 跟我上面差不多,只是他们把方法还是写在了methods中,然后在mounted中这样写window.函数 = this.函数。我这样写,没有触发函数;
  2. 用Vue.component自定义子组件,然后把拼好的字符串传进去并绑定,在子组件中触发方法,我也没实现;
  3. 通过事件代理,在父级元素上绑定方法,触发后判断event.target看看点击了哪个子元素,可惜我没有拿到任何打印信息。

以上就是我实现这个需求所做的工作,希望能解决大家的问题。