You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js/JavaScript:如何将文本引用转为应用内链接并避免转义?

这个问题我之前做项目时也踩过坑!本质是你用的渲染环境(不管是原生JS还是React/Vue这类框架)默认会对插入的文本做转义处理,防止XSS攻击,但这就导致你生成的锚点HTML代码被当成纯文本显示出来了。下面分几种常见场景给你靠谱的解决方案:

原生JavaScript场景

如果是纯前端原生开发,直接用innerHTML来插入处理后的HTML内容,而不是textContent或者innerText——后两者会把所有内容当成纯文本解析。

示例代码:

// 从数据库获取的原始文本
const rawText = "查看[用户中心]了解更多,或者访问[设置页面]修改偏好";

// 正则替换[xxx]为应用内链接
const processedHtml = rawText.replace(/\[([^\]]+)\]/g, (match, linkText) => {
  // 这里根据链接文本映射到对应的应用内路由,你可以根据实际需求扩展这个映射表
  const routeMap = {
    "用户中心": "/user-profile",
    "设置页面": "/app-settings"
  };
  const targetUrl = routeMap[linkText] || "#"; // 找不到对应路由就跳转到锚点
  return `<a href="${targetUrl}">${linkText}</a>`;
});

// 把处理后的HTML插入到页面元素中
document.getElementById("content-container").innerHTML = processedHtml;

React场景

React默认会转义JSX中的字符串内容,所以直接把HTML字符串丢进去会被转义。这里有两种处理方式:

方式一:使用dangerouslySetInnerHTML

虽然名字看起来有点吓人,但只要你的内容是可信的(比如来自自己数据库的可控内容,不是用户提交的未知内容),就可以安全使用:

function ContentDisplay() {
  const rawText = "查看[用户中心]了解更多,或者访问[设置页面]修改偏好";
  
  const processedHtml = rawText.replace(/\[([^\]]+)\]/g, (match, linkText) => {
    const routeMap = {
      "用户中心": "/user-profile",
      "设置页面": "/app-settings"
    };
    const targetUrl = routeMap[linkText] || "#";
    return `<a href="${targetUrl}">${linkText}</a>`;
  });

  // 通过dangerouslySetInnerHTML直接渲染HTML
  return <div dangerouslySetInnerHTML={{ __html: processedHtml }} />;
}

方式二:拆分文本为React元素(推荐)

如果用React Router做路由,更推荐用<Link>组件代替原生<a>标签,这时候可以把原始文本拆分成普通文本和链接节点的数组,再逐个渲染:

import { Link } from 'react-router-dom';

function ContentDisplay() {
  const rawText = "查看[用户中心]了解更多,或者访问[设置页面]修改偏好";
  const routeMap = {
    "用户中心": "/user-profile",
    "设置页面": "/app-settings"
  };

  // 拆分文本,把[xxx]作为单独的部分提取出来
  const textParts = rawText.split(/(\[[^\]]+\])/);

  // 把每个部分转换成React元素
  const renderedElements = textParts.map((part, index) => {
    if (part.startsWith('[') && part.endsWith(']')) {
      const linkText = part.slice(1, -1);
      const targetRoute = routeMap[linkText] || "#";
      return <Link key={index} to={targetRoute}>{linkText}</Link>;
    }
    return <span key={index}>{part}</span>;
  });

  return <div>{renderedElements}</div>;
}

这种方式更符合React的组件化思想,也避免了使用dangerouslySetInnerHTML。

Vue场景

Vue的{{ }}插值语法默认会转义内容,所以需要用v-html指令来渲染HTML:

方式一:使用v-html

<template>
  <div v-html="processedHtml"></div>
</template>

<script>
export default {
  data() {
    return {
      rawText: "查看[用户中心]了解更多,或者访问[设置页面]修改偏好",
      routeMap: {
        "用户中心": "/user-profile",
        "设置页面": "/app-settings"
      }
    };
  },
  computed: {
    processedHtml() {
      return this.rawText.replace(/\[([^\]]+)\]/g, (match, linkText) => {
        const targetUrl = this.routeMap[linkText] || "#";
        return `<a href="${targetUrl}">${linkText}</a>`;
      });
    }
  }
};
</script>

方式二:拆分文本为Vue节点(推荐)

如果用Vue Router,同样推荐用<router-link>组件,拆分文本后渲染:

<template>
  <div>
    <template v-for="(part, index) in processedParts" :key="index">
      <router-link v-if="part.isLink" :to="part.url">{{ part.text }}</router-link>
      <span v-else>{{ part.text }}</span>
    </template>
  </div>
</template>

<script>
export default {
  data() {
    return {
      rawText: "查看[用户中心]了解更多,或者访问[设置页面]修改偏好",
      routeMap: {
        "用户中心": "/user-profile",
        "设置页面": "/app-settings"
      }
    };
  },
  computed: {
    processedParts() {
      const textParts = this.rawText.split(/(\[[^\]]+\])/);
      return textParts.map(part => {
        if (part.startsWith('[') && part.endsWith(']')) {
          const linkText = part.slice(1, -1);
          return {
            isLink: true,
            text: linkText,
            url: this.routeMap[linkText] || "#"
          };
        }
        return {
          isLink: false,
          text: part
        };
      });
    }
  }
};
</script>

总结

核心思路就是:不要让渲染环境把你生成的链接代码当成纯文本处理。如果是原生环境就用innerHTML;如果是框架环境,要么用框架提供的HTML渲染指令(比如React的dangerouslySetInnerHTML、Vue的v-html),要么更优雅地拆分文本为框架支持的组件/节点,后者在框架开发中更推荐,也更安全。

内容的提问来源于stack exchange,提问作者Tomás Ferreira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:21:10