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

Vue2 v-for循环渲染v-html时v-model更新内容不同步问题

问题原因

渲染不更新的核心是响应式关联断裂:

  • 组件初始化执行data()函数时,statements数组中每个项的text属性是直接用当时的this.name值拼接出的静态字符串,初始化完成后,这个字符串和name属性就没有任何绑定关系了
  • 后续name被v-model更新时,statements里的text不会自动重新计算,v-html绑定的是固定不变的静态字符串,自然不会同步更新
  • 额外说明:示例代码把name定义在props里,却直接通过v-model修改,违反Vue单向数据流规则,会抛出控制台警告,组件内部状态应该定义在data中。
解决方案

最简洁的实现方式是用计算属性动态生成渲染列表,计算属性会自动收集依赖的响应式变量,变量变化时自动重算返回值,完全适配当前场景:

  1. 把数组里的HTML内容改成带占位符的静态模板,初始化时不要拼接动态值
  2. 新增计算属性,遍历模板列表,把当前最新的动态变量替换到占位符位置,生成最终要渲染的HTML字符串
  3. v-for直接遍历计算属性返回的列表即可

修正后的完整代码如下:

模板部分

<div id="app">
  <h2>Testing</h2>
  <ul>
    <!-- 遍历计算属性返回的渲染列表,记得加唯一key -->
    <li v-for="statement in renderedStatements" v-html="statement.text" :key="statement.id"></li>
  </ul>
  
  <input v-model="name" placeholder="edit name">
  <p>Name is: {{ name }}</p>
  
  <p class="italic">Outside loop: <b>{{name}}</b> likes dogs.</p>
</div>

实例代码

new Vue({
  el: "#app",
  data: function() {
    return {
      // 内部状态移到data中,避免直接修改props
      name: 'Bob',
      statements: [
        {
          id: 'food',
          // 用{name}作为动态值的占位符,多变量同理加不同占位符即可
          template: '<b>{name}</b> likes to eat ice cream.'
        },
        {
          id: 'fun',
          template: 'Running is the favorite activity of <b>{name}</b>'
        }
      ]
    }
  },
  computed: {
    renderedStatements() {
      // 自动依赖name,name变化时自动重跑该逻辑
      return this.statements.map(item => ({
        id: item.id,
        text: item.template.replaceAll('{name}', this.name)
        // 多变量替换就在这里链式调用replaceAll,替换对应占位符即可
      }))
    }
  }
})
注意事项
  • v-html渲染的内容不会经过Vue模板编译,不要在传入的HTML字符串里写{{ }}插值、v-model等Vue语法,写了也不会生效,所有动态内容必须提前在JS侧替换为最终文本
  • 由于项目同时使用Laravel Blade模板,注意Blade默认的{{ }}插值和Vue插值语法冲突,Vue相关的插值前面加@前缀写成@{{ name }},Blade编译时会自动跳过带@的插值,交给Vue处理
  • v-html存在XSS风险,确保渲染的HTML字符串来自可信来源,不要直接渲染未经过滤的用户提交内容

内容的提问来源于stack exchange,提问作者jumki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:01:01