需求是这样的:
后台传参传过来一个 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"就可以了
如果传的是别的类型的文件,可以参考下图修改器请求头的参数
那如果我们需要加载很多组模板的时候应该怎么办呢
首先我们循环注册多个组件
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}`;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。