vue远程加载sfc组件思路详解

更新时间:2023-05-22 13:30:08 阅读: 评论:0

vue远程加载sfc组件思路详解
问题
在我们的 vue 项⽬中(特别是后台系统),总会出现⼀些需要多业务线共同开发同⼀个项⽬的场景,如果各业务团队向项⽬中提供⼀些公共业务组件,但是这些组件并不能和项⽬⼀起打包,因为项⽬中不能因为某个私有模块的频繁变更⽽重复构建发布。
^_^不建议在⽣产环境使⽤,代码包含eval
思路
在这种场景下我们需要将公共的业务组件部署到服务端,由客户端请求并渲染组件。
服务端解析.vue⽂件
使⽤vue-template-compiler 模板解析器,解析SFC(单⽂件组件)
const compile = require('vue-template-compiler')
// 获取sfc组件的源码
const str = fs.solve(__dirname, `../components/sfc.vue`), 'utf-8')
// vue-loader内置,现在⽤来解析SFC(单⽂件组件)
let sfc = compile.parComponent(str)
// 获取sfc组件配置
let sfcOptions = getComponentOption(sfc)
getComponentOption 获取sfc组件配置
import { uuid } from 'utilscore'
import stylus from 'stylus'
import sass from 'sass'
import less from 'less'
const getComponentOption = sfc => {
/
/ ⽣成data-u-id
const componentId = uuid(8, 16).toLocaleLowerCa()
jacobs
// 标签添加data-u-id属性thresholding
const template = plate ? t, componentId) : ''
// 转化style(less、sass、stylus)
let styles = []
sfc.styles.forEach(sty => {
switch (sty.lang) {
ca 'stylus':
break;
ca 'sass':
ca 'scss':
styles.push(formatStyl(sty, derSync({ data: t }).String(), componentId))
break;
ca 'less':
break;
}
})
let options = {
script: sfc.script ? $require(null, t) : {},
styles,
template
}
return JSON.stringify(options, (k, v) => {
if(typeof(v) === 'function') {
let _fn = v.toString()
return /^function()/.test(_fn) ? _fn : fn.replace(/^/,'function ')
}
return v
})
}
tagToUuid  给template 中的标签追加data-u-id
const tagToUuid = (tpl, id) => {
var pattern = /<[^\/]("[^"]*"|'[^']*'|[^'">])*>/g
place(pattern, $1 => {
return $1.replace(/<([\w\-]+)/i, ($2, $3) => `<${$3} data-u-${id}`)
})
}
formatStyl 处理样式的scoped
const formatStyl = (sty, css, componentId) => {
let cssText = css
if (sty.scoped) {
cssText = place(/[\.\w\>\s]+{/g, $1 => {
if (/>>>/.test($1)) return $1.replace(/\s+>>>/, `[data-u-${componentId}]`)
return $1.replace(/\s+{/g, $2 => `[data-u-${componentId}]${$2}`)
})
}
return cssText
}
$require 执⾏其中的的 JavaScript 代码,并返回值
const $require = (filepath, scriptContext) => {
const filename = solve(__dirname, `../${filepath}`);
const module = { exports: {} }
let code = scriptContext ? scriptContext : fs.readFileSync(filename, 'utf-8')
let exports = ports
code = `(function($require,module,exports,__dirname,filename){$[code]})($require,module,exports,__dirname,filename)`    eval(code)
ports
}
客户端请求组件并渲染
封装前端远程组件-remote.vue
<template>
<component :is="remote" v-bind="$attrs" v-on="$listeners"></component>
</template>
<script>
import Vue from "vue";
export default {
data() {
return {
remote: null
}
},
props: {
tagName: {
type: String,
defualt: "componentName"
}
},
created() {
fetch("localhost:3000/getComponent/"+this.tagName)
.then(res => res.json())
.then(sfc => {
let options = this.parObj(sfc);
options.styles.forEach(css => this.appendSty(css));
< = d({
...options.script,marinetraffic
name: options.script.name || this.tagName,
template: plate
});
});
},
methods: {
isObject(v) {
return String.call(v).includes("Object");
},
parObj(data) {
if (Array.isArray(data)) return data.map(row => this.parObj(row));
if (this.isObject(data)) {
英语音标发音学习let ret = {};
for (let k in data) {
ret[k] = this.parObj(data[k]);
}    return ret;
}
try {
let pattern = /function ([\w]+)\(\) \{ \[native code\] \}/;
if (st(data)) {
return (data)[1]];
mcfarlane} el {
let evalData = eval(`(${data})`);
return typeof evalData == "function" ? evalData : data;
}
} catch (err) {
return data;
}
collap什么意思
},
appendSty(css) { // ⽣成组件样式
let style = ateElement("style");
style.tAttribute("type", "text/css");
var cssText = ateTextNode(css);
style.appendChild(cssText);
脸部皮肤保养步骤var head = document.querySelector("head");
head.appendChild(style);
miz}
}};
重庆涪陵在线
</script>
远程组件实践
服务端sfc组件,注意javascript块要使⽤ports导出,引⼊脚本使⽤$require <template>
<div class="test">
<div>
<p @click='$emit("handleClick",'点我')'>远程组件--{{msg}}--{{text}}</p>
</div>
</div>
</template>
<script>
// 加载js脚本
let {a} = $require('utils/test.js')
data: function() {
return {
msg: "remote component",
...a,
}
},
props: {thirty
text: {
type: Boolean,
default: true
}
},
mounted:function(){
console.log('prop text is',)
}
};
</script>
<style lang="stylus" scoped>
.test {
.test2 {
color: red;
}
p{
color:red
}
}
</style>
客户端渲染
// temolate
<remote text='123456' @handleClick='handleClick'/>
// script
methods:{
handleClick(v){
console.log(v) // 点我 }
}
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

本文发布于:2023-05-22 13:30:08,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/118379.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:组件   业务   代码   服务端   远程   学习   标签
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图