1
0
mirror of https://github.com/sahadev/vue-component-creater-ui.git synced 2025-06-06 21:14:03 +08:00

feat: 支持输出Vue2以及Vue3代码

This commit is contained in:
shangbin 2022-03-16 19:57:21 +08:00
parent 45e13cde40
commit fbac556ed6
4 changed files with 147 additions and 42 deletions

63
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "lcg-vcc",
"name": "lcg-vcc3",
"version": "0.5.3",
"lockfileVersion": 1,
"requires": true,
@ -2621,7 +2621,6 @@
"version": "3.2.1",
"resolved": "https://r.cnpmjs.org/ansi-styles/download/ansi-styles-3.2.1.tgz",
"integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@ -3597,7 +3596,6 @@
"version": "2.4.2",
"resolved": "https://r.cnpmjs.org/chalk/download/chalk-2.4.2.tgz",
"integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@ -4014,7 +4012,6 @@
"version": "1.9.3",
"resolved": "https://r.cnpmjs.org/color-convert/download/color-convert-1.9.3.tgz",
"integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@ -4022,8 +4019,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://r.cnpmjs.org/color-name/download/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.9.0",
@ -5376,10 +5372,12 @@
"dev": true
},
"ejs": {
"version": "2.7.4",
"resolved": "https://r.cnpmjs.org/ejs/download/ejs-2.7.4.tgz",
"integrity": "sha1-SGYSh1c9zFPjZsehrlLDoSDuybo=",
"dev": true
"version": "3.1.6",
"resolved": "https://r2.cnpmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"requires": {
"jake": "^10.6.1"
}
},
"electron-to-chromium": {
"version": "1.4.14",
@ -5694,8 +5692,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://r.cnpmjs.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
"version": "2.0.0",
@ -6542,6 +6539,14 @@
"dev": true,
"optional": true
},
"filelist": {
"version": "1.0.2",
"resolved": "https://r.cnpmjs.org/filelist/-/filelist-1.0.2.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
"requires": {
"minimatch": "^3.0.4"
}
},
"filesize": {
"version": "3.6.1",
"resolved": "https://r.cnpmjs.org/filesize/download/filesize-3.6.1.tgz",
@ -6961,8 +6966,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://r.cnpmjs.org/has-flag/download/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.2",
@ -8122,6 +8126,24 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
"jake": {
"version": "10.8.2",
"resolved": "https://r2.cnpmjs.org/jake/-/jake-10.8.2.tgz",
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
"requires": {
"async": "0.9.x",
"chalk": "^2.4.2",
"filelist": "^1.0.1",
"minimatch": "^3.0.4"
},
"dependencies": {
"async": {
"version": "0.9.2",
"resolved": "https://r2.cnpmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw=="
}
}
},
"javascript-stringify": {
"version": "2.1.0",
"resolved": "https://r.cnpmjs.org/javascript-stringify/download/javascript-stringify-2.1.0.tgz",
@ -9911,8 +9933,8 @@
},
"parse5": {
"version": "5.1.1",
"resolved": "https://r.cnpmjs.org/parse5/download/parse5-5.1.1.tgz",
"integrity": "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg=",
"resolved": "https://r2.cnpmjs.org/parse5/-/parse5-5.1.1.tgz",
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
"dev": true
},
"parse5-htmlparser2-tree-adapter": {
@ -12865,7 +12887,6 @@
"version": "5.5.0",
"resolved": "https://r.cnpmjs.org/supports-color/download/supports-color-5.5.0.tgz",
"integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@ -14135,6 +14156,14 @@
"mkdirp": "^0.5.1",
"opener": "^1.5.1",
"ws": "^6.0.0"
},
"dependencies": {
"ejs": {
"version": "2.7.4",
"resolved": "https://r2.cnpmjs.org/ejs/-/ejs-2.7.4.tgz",
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
"dev": true
}
}
},
"webpack-chain": {

View File

@ -32,6 +32,7 @@
"crypto-random-string": "^3.3.1",
"css": "^3.0.0",
"css-scoped": "^1.0.0",
"ejs": "^3.1.6",
"element-plus": "^1.2.0-beta.3",
"escodegen": "^2.0.0",
"espree": "^7.3.0",

View File

@ -6,7 +6,7 @@
<div style="color: #666; font-size: 12px; text-align:center; margin: 5px;">使用代码前请确认相应的组件库已集成至项目</div>
<div style="text-align:left;">
<el-row>
<el-col :span="6">
<el-col :span="5">
输出形式
<el-radio-group v-model="outputMode" style="display: flex; flex-direction: column;">
<el-radio label="vue">Vue</el-radio>
@ -14,7 +14,7 @@
</el-radio-group>
</el-col>
<el-col :span="6" v-if="outputMode === 'html'">
<el-col :span="5" v-if="outputMode === 'html'">
选择所使用的组件库
<el-checkbox-group v-model="checkList" style="display: flex; flex-direction: column;">
<el-checkbox label="ele">Element UI</el-checkbox>
@ -22,6 +22,13 @@
<el-checkbox label="vant">Vant</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col :span="4" v-if="outputMode === 'html'">
选择Vue版本
<el-radio-group v-model="vueVersion" style="display: flex; flex-direction: column;">
<el-radio label="2">Vue 2</el-radio>
<el-radio label="3">Vue 3</el-radio>
</el-radio-group>
</el-col>
<el-col :span="10" style="display: flex; flex-direction: column;">
代码获取方式
<div style="margin-top: 10px;">
@ -33,7 +40,8 @@
</el-tooltip>
</div>
<div style="margin-top: 10px;" v-if="outputMode === 'html'">
<el-input v-model="fileName" placeholder="部署文件名" style="width: 150px; margin-right: 10px;" size="small"></el-input>
<el-input v-model="fileName" placeholder="部署文件名" style="width: 150px; margin-right: 10px;" size="small">
</el-input>
<el-button size="small" type="danger" :loading="loading" @click="release">
一键部署至VCC静态页面托管服务</el-button>
<div v-if="accessUrl">部署成功:<a :href="accessUrl" target="_blank">{{accessUrl}}</a></div>
@ -71,7 +79,8 @@ export default {
loading: false,
accessUrl: '',
fileName: '',
checkList: ['ele']
checkList: ['ele'],
vueVersion: '3'
};
},
beforeCreate() { },
@ -150,7 +159,7 @@ export default {
},
singleIndex() {
const htmlCode = singleIndexOutput(this.rawCode);
const htmlCode = singleIndexOutput(this.rawCode, this.checkList, this.vueVersion === '3');
try {
return prettier.format(htmlCode, {
parser: "html",

View File

@ -1,39 +1,105 @@
import { parseComponent } from 'vue-template-compiler/browser';
import { parseComponent } from "vue-template-compiler/browser";
import ejs from "ejs";
const outputVue2Template = `<!DOCTYPE html>
const outputVueTemplate = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>VCC预览</title>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style stype="text/css">#styleTemplate</style>
<title>页面预览</title>
<style stype="text/css">
<%= style %>
</style>
<% for(var i = 0; i < cssLibs.length; ++i) { %>
<link href="<%= cssLibs[i] %>" rel="stylesheet"><% } %>
</head>
<body>
<div id="app">
#templateHolder
<%- templateHolder %>
</div>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue(#logicHolder).$mount("#app");
</script>
</html>`
<% for(var i = 0; i < scriptLibs.length; ++i) { %>
<script src="<%= scriptLibs[i] %>"></script><% } %>
<script>
export default function (vueCode) {
<% if(vue3) {%>Vue.createApp(<%-logicHolder%>)<% for(var i = 0; i < vue3UseLib.length; ++i) { %>
.use(<%= vue3UseLib[i] %>)<%}%>
.mount("#app"); %>
<% } else {%>new Vue(<%- logicHolder %>).$mount("#app")<%}%>
</script>
</html>`;
const libAddressMap = {
vue: {
js: ["https://cdn.bootcdn.net/ajax/libs/vue/3.2.31/vue.global.min.js"],
css: "",
},
ele: {
js: ["https://cdn.bootcdn.net/ajax/libs/element-plus/2.1.0/index.full.min.js"],
css: "https://cdn.bootcdn.net/ajax/libs/element-plus/2.1.0/theme-chalk/index.min.css",
libName: "ElementPlus",
},
antd: {
js: [
"https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.8/dayjs.min.js",
"https://cdn.bootcdn.net/ajax/libs/ant-design-vue/3.0.0-alpha.14/antd.min.js",
],
css: "https://cdn.bootcdn.net/ajax/libs/ant-design-vue/3.0.0-alpha.14/antd.min.css",
libName: "antd",
},
vant: {
js: ["https://cdn.bootcdn.net/ajax/libs/vant/3.3.7/vant.min.js"],
css: "https://cdn.bootcdn.net/ajax/libs/vant/3.3.7/index.min.css",
libName: "vant",
},
};
export default function (vueCode, dependenciesLibs, vue3 = true) {
const { template, script, styles, customBlocks } = parseComponent(vueCode);
let newScript = script.content.replace(/\s*export default\s*/, "");
let output = outputVue2Template;
const tempDependenciesLibs = dependenciesLibs.slice();
const tempLibAddressMap = vue3 ? libAddressMap: libAddressMapForVue2
output = output.replace("#templateHolder", template.content);
output = output.replace("#logicHolder", newScript);
output = output.replace("#styleTemplate", styles[0].content);
tempDependenciesLibs.unshift("vue");
const output = ejs.render(outputVueTemplate, {
cssLibs: tempDependenciesLibs.map((item) => tempLibAddressMap[item].css).filter((item) => !!item),
scriptLibs: tempDependenciesLibs
.map((item) => tempLibAddressMap[item].js)
.flat()
.filter((item) => !!item),
vue3,
vue3UseLib: tempDependenciesLibs
.filter((item) => item != "vue")
.map((item) => tempLibAddressMap[item].libName),
style: styles[0].content,
templateHolder: template.content,
logicHolder: newScript,
});
return output;
}
const libAddressMapForVue2 = {
vue: {
js: ["https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"],
css: "",
},
ele: {
js: ["https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/index.min.js"],
css: "https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/theme-chalk/index.min.css",
},
antd: {
js: [
"https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js",
"https://cdn.bootcdn.net/ajax/libs/ant-design-vue/1.7.8/antd.js",
],
css: "https://cdn.bootcdn.net/ajax/libs/ant-design-vue/1.7.8/antd.css",
},
vant: {
js: ["https://cdn.bootcdn.net/ajax/libs/vant/2.12.44/vant.min.js"],
css: "https://cdn.bootcdn.net/ajax/libs/vant/2.12.44/index.min.css",
},
};