导读:本期聚焦于沈清秋创作的《Vue 3 字符串处理怎么做?模板拼接、HTML 转义与格式化实用指南》,敬请观看详情。在 Vue 3 项目里处理字符串时,插值表达式和 v-html 的区别往往决定了页面的安全性:前者默认转义能有效防御 XSS 攻击,后者则可能把恶意脚本直接渲染进 DOM。本文围绕模板拼接、转义与格式化三个核心场景展开,先讲解模板字符串与插值的正确用法,再分析 v-html 的风险边界和过滤方案,最后介绍数字、日期、金额等常见格式化的实现方式,并对比 computed、工具函数和第三方库的适用场景,帮你写出既安全又易维护的字符串处理逻辑。

字符串处理是前端开发中频率极高的操作,Vue 3 在模板层面提供了插值表达式、指令绑定等机制,而具体业务中的拼接、转义、格式化则需要开发者自己把控。不少 XSS 漏洞的根源就是字符串没经过转义就被当作 HTML 渲染,同样,混乱的拼接方式也会让模板变得难以维护。本文从模板、转义、格式化三个角度出发,梳理 Vue 3 中字符串处理的正确姿势。

Vue 3 字符串处理怎么做?模板拼接、HTML 转义与格式化实用指南

模板中的字符串:插值表达式与模板字符串的正确用法

Vue 3 的插值表达式使用双花括号语法,渲染时会自动将内容作为纯文本处理。这一点非常关键:即使数据里包含 <script> 这样的标签,页面上也只会显示原始文字,浏览器不会执行它。这种默认转义机制是 Vue 防御 XSS 的第一道防线,日常展示动态文本时应优先使用插值而不是 v-html。

在拼接字符串时,推荐使用 ES6 的模板字符串配合插值表达式,而不是用加号在模板里硬拼。对比下面两种写法:

<!-- 不推荐:加号拼接,可读性差 -->
<span>{{ user.lastName + ' ' + user.firstName }}</span>

<!-- 推荐:模板字符串,结构清晰 -->
<span>{{ `${user.lastName} ${user.firstName}` }}</span>

当拼接逻辑变复杂时,更好的做法是把逻辑收进 computed 计算属性,让模板只负责展示。这样既便于单元测试,也避免了模板里塞满表达式。例如拼接一个带前缀的状态文案:

import { computed, ref } from 'vue'

const status = ref('pending')
const statusText = computed(() => {
  const map = {
    pending: '待处理',
    done: '已完成',
    error: '发生错误'
  }
  return `[${new Date().toLocaleDateString()}] ${map[status.value] ?? '未知状态'}`
})

另一个细节是属性绑定。如果要动态绑定类名或标题等属性,插值表达式不能用在属性位置,必须使用 v-bind 的缩写写法,例如 :title="`点击查看${name}的详情`"。这里同样遵循自动转义规则,属性值中出现的引号或尖括号都会被正确编码,不会破坏标签结构。

转义与安全:v-html 的风险边界和替代方案

v-html 指令会把字符串当作原始 HTML 插入 DOM,Vue 不会对它做任何转义。官方文档明确警告:永远不要对用户提供的内容使用 v-html。一旦用户输入中混入了 <img onerror=...> 之类的 payload,就会直接执行,造成 XSS 攻击。

实际项目中确实存在需要渲染富文本的场景,比如后台管理系统展示管理员配置的公告。这时有两类处理思路。第一类是后端预过滤:在入库前用白名单方式清洗 HTML,只保留允许的标签和属性。第二类是前端兜底,引入 DOMPurify 这类成熟库做净化:

import DOMPurify from 'dompurify'
import { computed, ref } from 'vue'

const rawHtml = ref('<img src=x onerror=alert(1)><p>公告内容</p>')

const safeHtml = computed(() => DOMPurify.sanitize(rawHtml.value, {
  ALLOWED_TAGS: ['p', 'strong', 'em', 'a', 'br'],
  ALLOWED_ATTR: ['href']
}))

然后在模板中使用 v-html="safeHtml",即便原始数据被污染,危险节点也会被剥离。需要注意 DOMPurify 的配置项要按业务最小化开放,比如不允许 scriptiframe、事件属性,链接协议仅允许 http 和 https。

如果只是想把用户输入原样显示出来(比如评论区展示代码片段),完全不需要 v-html,插值表达式就够了。某些特殊需求下需要手动转义时,可以封装一个简单的工具函数:

function escapeHtml(str) {
  const map = {
    '&': '&',
    '<': '<',
    '>': '>',
    '"': '"',
    "'": '''
  }
  return String(str).replace(/[<>&"']/g, ch => map[ch])
}

这个函数把五个关键的 HTML 字符替换成实体,返回的字符串再交给插值表达式渲染即可,双层保险。此外,在拼接 URL 时也要警惕注入问题,动态参数务必经过 encodeURIComponent 处理,而不是直接拼进查询串。

格式化实践:数字、日期与金额的统一处理

格式化是工具库里最常见的一类字符串函数。数字千分位、金额补零、日期本地化这些需求几乎每个项目都有,建议统一封装成纯函数或组合式函数,而不是散落在各个组件里。

先看千分位格式化。除了手写正则,更可靠的方式是直接使用 Intl.NumberFormat,它是浏览器原生 API,支持多语言环境:

// 千分位格式化,保留两位小数
const money = new Intl.NumberFormat('zh-CN', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
})

money.format(1234567.8)   // '1,234,567.80'
money.format(0.5)         // '0.50'

日期格式化同样可以基于 Intl.DateTimeFormat 实现,避免引入体积较大的日期库。如果项目对日期操作要求复杂(时区换算、相对时间等),再考虑引入 Day.js,它的体积只有几 KB,API 也足够简洁:

import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'

dayjs.extend(relativeTime)
dayjs.locale('zh-cn')

dayjs().format('YYYY-MM-DD HH:mm:ss')  // '2024-06-01 09:30:00'
dayjs('2024-05-01').fromNow()          // '一个月前'

在组件层面使用格式化函数时,把结果放进 computed 而不是 methods,可以利用缓存避免每次渲染都重新计算。还有一种全局方案是自定义插件,把格式化函数挂载到全局属性上:

// formatters.js
export default {
  install(app) {
    app.config.globalProperties.$fmt = {
      money: v => new Intl.NumberFormat('zh-CN', {
        style: 'currency', currency: 'CNY'
      }).format(v)
    }
  }
}

// 组件中使用
// {{ $fmt.money(998) }} 输出 ¥998.00

这种方式的优点是调用方便,缺点是失去了 TypeScript 的类型提示,且不利于追踪数据流。更现代的做法是直接以具名导出的工具函数配合按需引入,打包工具会自动做 tree-shaking,未用到的格式化函数不会进入产物。

总结一下:展示层优先插值表达式,享受自动转义的安全保障;确需渲染 HTML 时必须经过 DOMPurify 净化;格式化逻辑统一封装为纯函数,配合 computed 使用。把这三条原则落地到工具库中,Vue 3 项目的字符串处理就能兼顾安全、性能和可维护性。

Vue 3字符串处理HTML转义修改时间:2026-09-12 03:42:35

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260912/55089.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。