2

需求是这样的:
后台传参传过来一个 html 文本,需要渲染在页面上

那按照通常的做法,是利用 vue 的 v-html 指令,直接渲染
像这样: <span v-html="rawHtml"></span>

但问题是,后台传过来的 html 文本是带有插值的字符串
像这样: <div style="color:#67C23A">{{str.name}}</div>

我们知道 v-html 只能渲染静态html,所以我们需要使用 Vue.component来注册全局组件,在 template 属性中插入带有插值的 html

html:

<component
      :is="mytemplate"
      :str="showdata"
      ref="printitem"
    ></component>

js:
添加测试数据:

 data() {
    return {
     showdata:{
        id:0,
        name:'小明'
     }
    };
  },

注册模板

var mstr = '<div style="color:#67C23A">{{str.name}}</div>';
Vue.component("mytemplate", {
    props: ["str"],
    template: mstr
});

注意: html组件里的传参名称,添加的 dom 节点中的对象名,注册模板时的 props 名称,这三者一定要一致

这里插播一个开发时遇到的另一个问题,后台接口传过来的是一个 html 文件,而不是通常我们接收到的 json 对象,所以我们无法使用封装好的请求函数,需要另外写

 axios
      .post(
        "/university-facade/file/download.shtml?id=" + this.queryObj.template,
        {
          headers: {
            "Content-Type": "text/html"
          }
        }
      )
      .then(response=> {
      },
        err => { 
      }
);

像这样把请求头改成"text/html"就可以了
如果传的是别的类型的文件,可以参考下图修改器请求头的参数
C212ACF460F7CEF257F06A198D839757.png

那如果我们需要加载很多组模板的时候应该怎么办呢
首先我们循环注册多个组件

list.map((item, index) => {
    var str = '<div style="color:#67C23A">{{item.htmlstr}}</div>';
    Vue.component(`cmp-${index}`, {
    props: ["row"],
    template: str
    });
});

在 html 中循环渲染注册的这些组件

 <component
      v-for="(row,index) in list"
      :key="index"
      :is="getComponentName(index)"
      :row="row"
    ></component>

在 getComponentName 函数中绑定is 属性,从而确定应该渲染哪一个模板

 getComponentName(index) {
      return `cmp-${index}`;
    }

无锡肖奈
186 声望7 粉丝

十八线野生程序猿 前端开发