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

Vue递归组件字符串模板插值失效问题求助

问题描述

我有两个通过键关联的JSON,其中一个包含递归渲染的结构,数据会传入组件的data()中。但当我尝试把包含变量名的字符串模板插入组件模板时,变量插值完全没生效。试过<div v-html="content"></div>、v-text以及this.$refs.component.innerHTML这些方法都不行。

解决方案

问题根源

v-html、innerHTML这类方法只会把字符串当作普通HTML插入页面,不会解析Vue的模板插值语法,所以{{ properties.text }}这种写法只会原样输出,不会被替换成对应变量的值。

实现方案

利用Vue的Vue.compile方法编译字符串模板,生成可渲染的组件,再通过动态组件<component :is="...">渲染出来,这样就能让模板中的变量被正确插值。

修改后的递归组件代码

<template>
  <div class="component">
    <!-- 动态渲染编译后的组件 -->
    <component :is="compiledComponent" v-if="compiledComponent" />
    <!-- 递归渲染子组件 -->
    <div v-if="midle_json.type === 'group'">
      <jsonvuecomponent
        v-for="js in midle_json.content"
        :key="js.index"
        :midle_json="js"
        :low_json="low_json"
      />
    </div>
  </div>
</template>

<script>
import Vue from 'vue'

export default {
  name: "jsonvuecomponent",
  props: {
    midle_json: {
      type: Object,
      default: {},
      required: true,
    },
    low_json: {
      type: Object,
      default: {},
      required: true,
    },
  },
  computed: {
    compiledComponent() {
      const componentKey = this.midle_json.component
      if (!this.low_json[componentKey]) return null

      // 获取对应组件的模板字符串
      const template = this.low_json[componentKey].template
      // 编译模板生成渲染函数
      const compiled = Vue.compile(template)

      // 返回动态组件配置,注入当前的properties作为组件数据
      return {
        data() {
          return {
            properties: this.midle_json.properties
          }
        },
        render: compiled.render,
        staticRenderFns: compiled.staticRenderFns
      }
    }
  }
};
</script>

<style scoped></style>

额外修正点

  1. 修正模板变量路径:原low_json中component3的模板变量写错了,{{stal}}应该改为{{properties.stal}},因为stal是properties对象下的属性:
component3: {
  template: "<input type='{{properties.stal}}'>{{properties.placeholder}}"
}
  1. 容器组件支持子内容:原container_component1的模板是空div,递归子组件会渲染在容器外面,修改模板添加插槽,让子组件能渲染到容器内部:
container_component1: {
  template: "<div style='background-color: {{properties.color}}; padding: 10px;'> <slot></slot> </div>"
}

修正后效果

修正后模板中的变量会被正确插值,比如hello nekit会正常显示,输入框的placeholder也会正确加载对应内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:02:51