场景:项目要开发一个功能–打印模板设计器,前期忽略生成模板的过程,先直接把模板预置到数据库,后面的动态渲染就是个大难题了,直接渲染html可以用v-html,但是要求是还要渲染html里面的变量。
如图
项目用的vue框架,变量展示如下图,按照vue的语法来展示
这里用到了vue的extend犯法(挂载)
直接上代码
因为模板是html的页面,这里就需要去掉一些vue不能翻译的标签
这里需要将style跟div里面的代码分离开来,这里百度的往上的方法
getSource (source, type) {
const regex = new RegExp(`<${type}[^>]*>`);
let openingTag = source.match(regex);
if (!openingTag) return '';
else openingTag = openingTag[0];
return source.slice(source.indexOf(openingTag) + openingTag.length, source.lastIndexOf(`</${type}>`));
},
splitCode () {
const script = this.getSource(this.modelInfo.htmlInfo, 'script').replace(/export default/, 'return ');
const style = this.getSource(this.modelInfo.htmlInfo, 'style');
const template = '<div class="print-cont">' + this.getSource(this.modelInfo.htmlInfo, 'div') + '</div>';
this.js = script;
this.css = style;
this.html = template;
},
在这里this.js没有用
核心代码
readerDom(){
let _this=this;
this.getData().then(()=>{
this.getOrderDetail().then(()=>{
//假设此字符串是在后端获取的
let str = this.html
// 创建构造器
var Profile = Vue.extend({
template: str,
data: function() {
return {
modelInfo:{},
orderInfo:{..._this.orderData},
}
},
created(){
console.log('orderInfo',this.orderInfo)
},
methods:{
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
if (this.css !== '') {
const style = document.createElement('style');
style.type = 'text/css';
style.id = 'ddddd';
style.innerHTML = this.css;
document.getElementsByTagName('head')[0].appendChild(style);
}
})
})
},
在这里还有个问题,在这里挂载的模板渲染这块封装成一个组件放到调用的地方,作为一个子组件,父组件传过来的要渲染的数据orderInfo,数据有延迟,没找到解决方式,所以我又在这个组件调了一遍接口,这样就会出现这个页面调用了两次接口,有思路的宝子欢迎留言