全局注册 动态组件

This commit is contained in:
吕金泽 2022-03-05 11:29:26 +08:00
parent 54a2f86ab6
commit b630ed3828
8 changed files with 56 additions and 92 deletions

View File

@ -5,7 +5,7 @@
"groupId" : "67b2ce258e24491194b74992958c74aa",
"name" : "当前用户菜单",
"createTime" : null,
"updateTime" : 1646400991044,
"updateTime" : 1646450734459,
"lock" : "0",
"method" : "POST",
"path" : "/current/menus",
@ -551,7 +551,6 @@ var menus = db.select("""
sm.sort,
sm.icon,
sm.keep_alive,
sc.code,
sc.name component_name
from sys_menu sm
left join sys_component sc on sm.component_id = sc.id where 1=1

View File

@ -15,6 +15,7 @@ import App from './App.vue'
import router from './scripts/router'
import components from '@/components/index'
import globalProperties from './scripts/globalProperties'
import dynamicComponent from './scripts/dynamicComponent'
import hasPermission from './scripts/hasPermission'
import '@/permission'
@ -28,6 +29,7 @@ router.beforeEach((to, from) => {
return true
})
app.use(globalProperties)
app.use(dynamicComponent)
app.use(hasPermission)
app.use(components)
app.use(ElementPlus, {

View File

@ -0,0 +1,36 @@
import { babelParse } from '@vue/compiler-sfc'
import { compileFile } from '@/compiler/sfc-compiler.js'
function appComponent(app, item){
var compiled = {}
compileFile('TestCode.vue', item.code, compiled)
var code = compiled.js
var ast = babelParse(code, {
sourceType: 'module'
})
var replaceCode = (node, subCode) => code.substring(0, node.start) + subCode + code.substring(node.end);
for(var i = ast.program.body.length - 1; i>=0; i--){
var node = ast.program.body[i]
if(node.type === 'ImportDeclaration'){
code = replaceCode(node, node.specifiers.map(it => `const ${it.local?.name || it.imported?.name || '*'} = ___magic__import__('${node.source.value}', '${it.imported?.name || '*'}');`).join('\r\n'));
} else if (node.type === 'ExportDefaultDeclaration'){
code = replaceCode(node, `return ${node.declaration.name}`)
}
}
code = `(function(){
${code}
})()`
var componentStyle = document.createElement("style");
componentStyle.innerHTML = compiled.css
document.head.appendChild(componentStyle);
app.component(item.name, eval(code))
}
const install = (app) => {
app.config.globalProperties.$get('/component/list', { size: 999999 }).then((res) => {
res.data.list.forEach(it => {
appComponent(app, it)
})
})
}
export default install

View File

@ -27,4 +27,4 @@ const install = (app) => {
}
app.use(VueUeditorWrap)
}
export default install
export default install

View File

@ -7,11 +7,8 @@ export const filterAsyncRouter = (routers, level) => {
const accessedRouters = routers.filter(router => {
if (router.isShow === 1) {
if (router.componentName) {
router.component = loadView(`/common/parse-component`)
router.props = {
name: router.componentName,
code: router.code
}
router.component = loadView(`/common/show-component`)
router.props = { name: router.componentName }
} else if (router.component) {
const component = router.component
if (component === 'Layout') {
@ -52,4 +49,4 @@ export function generateRoutes(){
resolve(asyncRouter)
})
})
}
}

View File

@ -1,49 +0,0 @@
<script setup>
import { babelParse } from '@vue/compiler-sfc'
import { compileFile } from '@/compiler/sfc-compiler.js'
import { getCurrentInstance } from '@vue/runtime-core'
import { ref } from 'vue'
const props = defineProps({
code: {
type: String,
default: ''
},
name: {
type: String,
default: ''
}
})
var compiled = {}
compileFile('TestCode.vue', props.code, compiled)
var code = compiled.js
// console.log(code)
var ast = babelParse(code, {
sourceType: 'module'
})
var replaceCode = (node, subCode) => code.substring(0, node.start) + subCode + code.substring(node.end);
for(var i = ast.program.body.length - 1; i>=0; i--){
var node = ast.program.body[i]
if(node.type === 'ImportDeclaration'){
code = replaceCode(node, node.specifiers.map(it => `const ${it.local?.name || it.imported?.name || '*'} = ___magic__import__('${node.source.value}', '${it.imported?.name || '*'}');`).join('\r\n'));
} else if (node.type === 'ExportDefaultDeclaration'){
code = replaceCode(node, `return ${node.declaration.name}`)
}
}
code = `(function(){
${code}
})()`
var componentStyle = document.createElement("style");
componentStyle.innerHTML = compiled.css
document.head.appendChild(componentStyle);
console.log(getCurrentInstance())
getCurrentInstance().appContext.app.component(props.name, eval(code))
</script>
<template>
<component :is="props.name"></component>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,12 @@
<script setup>
const props = defineProps({
name: {
type: String,
default: ''
}
})
</script>
<template>
<component :is="props.name"></component>
</template>

View File

@ -1,41 +1,8 @@
<script setup>
import { babelParse } from '@vue/compiler-sfc'
import { compileFile } from '@/compiler/sfc-compiler.js'
import { testCode } from '@/compiler/testCode.js'
import { getCurrentInstance } from '@vue/runtime-core'
import {ref} from 'vue'
var compiled = {}
compileFile('TestCode.vue', testCode, compiled)
var code = compiled.js
// console.log(code)
var ast = babelParse(code, {
sourceType: 'module'
})
var replaceCode = (node, subCode) => code.substring(0, node.start) + subCode + code.substring(node.end);
for(var i = ast.program.body.length - 1; i>=0; i--){
var node = ast.program.body[i]
if(node.type === 'ImportDeclaration'){
code = replaceCode(node, node.specifiers.map(it => `const ${it.local?.name || it.imported?.name || '*'} = ___magic__import__('${node.source.value}', '${it.imported?.name || '*'}');`).join('\r\n'));
} else if (node.type === 'ExportDefaultDeclaration'){
code = replaceCode(node, `return ${node.declaration.name}`)
}
}
code = `(function(){
${code}
})()`
var componentStyle = document.createElement("style");
componentStyle.innerHTML = compiled.css
document.head.appendChild(componentStyle);
console.log(getCurrentInstance())
getCurrentInstance().appContext.app.component('TestComp', eval(code))
const xxClick = () => {
console.log('click')
}
</script>
<template>
<component :is="'TestComp'"></component>
<!-- <TestComp aaaaaa="666" @xxClick="xxClick"/> -->
home
</template>
<style scoped>