Closed sailei1 closed 5 years ago
模拟json
{ "com":"<template> <div class='test-cls' @click='change'> 列表页 {{a}} <my-component-name></my-component-name> </div> </template> <style lang=\"scss\" scoped> .test-cls{color:red;} </style> <script> export default{ data(){ return { a:1} }, props:{ }, components:{}, methods:{change(){this.a++;}}, } </script>", "com1":" <div> 列表页 </div>" }
实现 一种 computed 动态组件 另外一种 异步组件 开发不太方便 放弃
const compiler = require('vue-template-compiler') const parsed = compiler.parseComponent(res.data.com, { pad: 'line'}); const template = parsed.template ? parsed.template.content : ''; let script = parsed.script ? parsed.script.content : ''; const style = parsed.style ? parsed.style.content : ''; 样式有问题, 放弃 推荐 computed 方式
<template> <div class="remote"> <!--<com></com>--> <component :is="currentView" v-bind="$props"/> </div> </template> <script> import Axios from 'axios'; import Vue from 'vue'; import '../util/less.min'; Vue.component('my-component-name', { template:'<div>组件</div>', }) export default { props:{ url:{ type:String, default(){ return null; } } }, data(){ return { resData:null, cssId:null, } }, components:{ }, computed:{ currentView(){ if(!this.resData)return {template:"<div class='remoteInfo'>正在加载中。。。</div>"}; const tplData = this.resolveStr(this.resData); let ponentObj = new Function(`return ${tplData.sctipts.slice(tplData.sctipts.indexOf('{'),tplData.sctipts.lastIndexOf('}')+1)}`)(); ponentObj.template = tplData.templates; this.$el.setAttribute('class',`remote css${this.cssId}`); if(!document.querySelector(`style[id=css${this.cssId}]`)){//防止重复创建 let cssStr = ` .css${this.cssId}{ ${tplData.styles} } `; this.resolveCss(cssStr); } return ponentObj; } }, watch:{ url(){ this.getData(); } }, mounted(){ this.getData(); }, methods:{ getId() { var d = new Date().getTime(); var uid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (d + Math.random()*16)%16 | 0; d = Math.floor(d/16); return (c=='x' ? r : (r&0x3|0x8)).toString(16); }); return uid; }, resolveCss(lessInput){ less.render(lessInput).then(function(output) { let style = document.createElement("style"); style.setAttribute("type", "text/css"); style.setAttribute("id",'css' + this.cssId); if(style.styleSheet)// IE style.styleSheet.cssText = output.css; else {// w3c var cssText = document.createTextNode(output.css); style.appendChild(cssText); } var heads = document.getElementsByTagName("head"); if(heads.length) heads[0].appendChild(style); else document.documentElement.appendChild(style); }.bind(this)); }, resolveStr(str){ return { templates:str.match(/<template>([\s\S]*)<\/template>/)[1], sctipts:str.match(/<script.*>([\s\S]*)<\/script>/)[1], styles:str.match(/<style.*>([\s\S]*)<\/style>/)[1], } }, async getData(){ let url='http://127.0.0.1:9999/tpl'; const res = await Axios.get(url); this.cssId = this.getId(); this.resData = res.data.com; } } } // import Axios from 'axios'; // import Vue from 'vue' // import '../util/less.min'; // Vue.component('my-component-name', { // template:'<div>组件</div>', // }) // let me=this; // export default { // components: { // com: resolve => { // let url = 'http://127.0.0.1:9999/tpl'; // // Axios.get(url).then(res => { // // // // let resolveStr= function (str){ // return { // templates:str.match(/<template>([\s\S]*)<\/template>/)[1], // sctipts:str.match(/<script.*>([\s\S]*)<\/script>/)[1], // styles:str.match(/<style.*>([\s\S]*)<\/style>/)[1], // } // }; // // let tplData=resolveStr(res.data.com); // let ponentObj = new Function(`return ${tplData.sctipts.slice(tplData.sctipts.indexOf('{'),tplData.sctipts.lastIndexOf('}')+1)}`)(); // ponentObj.template = tplData.templates; // // // debugger;//远程组件的方式 不太方便 放弃 // // less.render(tplData.styles).then(function(output) { // let style = document.createElement("style"); // style.setAttribute("type", "text/css"); // let css_text=`.remote-v { ${output.css}}`; // if(style.styleSheet)// IE // style.styleSheet.cssText = css_text; // else {// w3c // var cssText = document.createTextNode(css_text); // style.appendChild(cssText); // } // var heads = document.getElementsByTagName("head"); // if(heads.length) // heads[0].appendChild(style); // else // document.documentElement.appendChild(style); // }.bind(this)); // // resolve(ponentObj); // }); // // // require(['../components/ad.vue'],resolve) // }, // }, // } </script>
模拟json
实现 一种 computed 动态组件 另外一种 异步组件 开发不太方便 放弃
const compiler = require('vue-template-compiler') const parsed = compiler.parseComponent(res.data.com, { pad: 'line'}); const template = parsed.template ? parsed.template.content : ''; let script = parsed.script ? parsed.script.content : ''; const style = parsed.style ? parsed.style.content : ''; 样式有问题, 放弃 推荐 computed 方式