.vue文件也支持defineRouteMeta

This commit is contained in:
wanchun 2022-03-07 16:29:21 +08:00
parent 56bb3842c9
commit dfaea6c108
6 changed files with 66 additions and 35 deletions

View File

@ -2,7 +2,7 @@ import { readdirSync, statSync, readFileSync } from 'fs';
import { import {
join, extname, posix, basename join, extname, posix, basename
} from 'path'; } from 'path';
import { lodash, parser, generator } from '@fesjs/utils'; import { lodash, parser } from '@fesjs/utils';
import { parse } from '@vue/compiler-sfc'; import { parse } from '@vue/compiler-sfc';
import { Logger } from '@fesjs/compiler'; import { Logger } from '@fesjs/compiler';
import { runtimePath } from '../../../utils/constants'; import { runtimePath } from '../../../utils/constants';
@ -102,7 +102,7 @@ const genRoutes = function (parentRoutes, path, parentRoutePath, config) {
const routeName = getRouteName(parentRoutePath, fileName); const routeName = getRouteName(parentRoutePath, fileName);
const componentPath = getComponentPath(parentRoutePath, fileName, config); const componentPath = getComponentPath(parentRoutePath, fileName, config);
const content = readFileSync(component, 'utf-8'); let content = readFileSync(component, 'utf-8');
let routeMeta = {}; let routeMeta = {};
if (ext === '.vue') { if (ext === '.vue') {
const { descriptor } = parse(content); const { descriptor } = parse(content);
@ -111,23 +111,27 @@ const genRoutes = function (parentRoutes, path, parentRoutePath, config) {
); );
routeMeta = routeMetaBlock?.content ? JSON.parse(routeMetaBlock.content) : {}; routeMeta = routeMetaBlock?.content ? JSON.parse(routeMetaBlock.content) : {};
} }
if (ext === '.jsx' || ext === '.tsx') { let importMeta = '';
if (ext === '.vue' || ext === '.jsx' || ext === '.tsx') {
if (ext === '.vue') {
const { descriptor } = parse(content);
content = descriptor.script.content;
}
const ast = parser.parse(content, { const ast = parser.parse(content, {
sourceType: 'module', sourceType: 'module',
plugins: ['jsx', 'typescript'] plugins: ['jsx', 'typescript']
}); });
const defineRouteExpression = ast.program.body.filter(expression => expression.type === 'ExpressionStatement' && expression.expression.type === 'CallExpression' && expression.expression.callee.name === 'defineRoute')[0]; const defineRouteMetaExpression = ast.program.body.filter(expression => expression.type === 'ExportNamedDeclaration' && expression.declaration.type === 'VariableDeclaration' && expression.declaration.declarations[0].id.name === 'meta')[0];
if (defineRouteExpression) { if (defineRouteMetaExpression) {
const argument = generator(defineRouteExpression.expression.arguments[0]); importMeta = `require('${componentPath}').meta`;
routeMeta = JSON.parse(argument.code.replace(/'/g, '"').replace(/(\S+):/g, (global, m1) => `"${m1}":`));
} }
} }
const routeConfig = { const routeConfig = {
path: routePath, path: routePath,
component: componentPath, component: componentPath,
name: routeMeta.name || routeName, name: (importMeta ? `${importMeta}.name` : routeMeta.name) || routeName,
meta: routeMeta meta: importMeta || routeMeta
}; };
if (hasLayout) { if (hasLayout) {
if (fileName === 'layout') { if (fileName === 'layout') {
@ -237,6 +241,14 @@ const getRoutesJSON = function ({ routes, config }) {
/"component": ("(.+?)")/g, /"component": ("(.+?)")/g,
(global, m1, m2) => `"component": ${m2.replace(/\^/g, '"')}` (global, m1, m2) => `"component": ${m2.replace(/\^/g, '"')}`
) )
.replace(
/"name": "require(.+?)"/g,
(global, m1) => `"name": require${m1}`
)
.replace(
/"meta": "require(.+?)"/g,
(global, m1) => `"meta": require${m1}`
)
.replace(/\\r\\n/g, '\r\n') .replace(/\\r\\n/g, '\r\n')
.replace(/\\n/g, '\r\n'); .replace(/\\n/g, '\r\n');
}; };
@ -319,7 +331,7 @@ export default function (api) {
api.addCoreExports(() => [ api.addCoreExports(() => [
{ {
specifiers: ['getRoutes', 'getRouter', 'getHistory', 'destroyRouter', 'defineRoute'], specifiers: ['getRoutes', 'getRouter', 'getHistory', 'destroyRouter', 'defineRouteMeta'],
source: absCoreFilePath source: absCoreFilePath
} }
]); ]);

View File

@ -61,6 +61,6 @@ export const destroyRouter = ()=>{
history = null; history = null;
} }
export const defineRoute = (param)=>{ export const defineRouteMeta = (param)=>{
return param return param
} }

View File

@ -1,26 +1,30 @@
<template> <template>
<div class="onepiece m-10px text-green"> <div class="onepiece m-10px text-green">
fes h5 & 拉夫德鲁<br /> fes h5 & 拉夫德鲁<br />
<fes-icon :spin="true" class="one-icon" type="smile" @click="clickIcon" /> <fes-icon
:spin="true"
class="one-icon"
type="smile"
@click="clickIcon"
/>
<HelloWorld /> <HelloWorld />
<HelloTSX /> <HelloTSX />
<helloTS /> <helloTS />
</div> </div>
</template> </template>
<config>
{
"title": "首页",
"name": "testIndex",
"layout": "false"
}
</config>
<script> <script>
import { ref } from 'vue'; import { ref } from 'vue';
import { request } from '@fesjs/fes'; import { request, defineRouteMeta, useRoute } from '@fesjs/fes';
import HelloWorld from '@/components/helloWorld'; import HelloWorld from '@/components/helloWorld';
import HelloTSX from '@/components/helloTSX'; import HelloTSX from '@/components/helloTSX';
import helloTS from '@/components/helloTS'; import helloTS from '@/components/helloTS';
export const meta = defineRouteMeta({
title: '首页',
name: 'testIndex',
layout: false
});
export default { export default {
components: { components: {
HelloWorld, HelloWorld,
@ -33,6 +37,7 @@ export default {
const clickIcon = () => { const clickIcon = () => {
console.log('click Icon'); console.log('click Icon');
}; };
console.log(useRoute());
// request('/api', null, { // request('/api', null, {
// }).then((res) => { // }).then((res) => {
// console.log(res); // console.log(res);
@ -59,15 +64,23 @@ export default {
// }); // });
const get = (id) => { const get = (id) => {
request('/get/api', { id }, { request(
method: 'get' '/get/api',
}); { id },
{
method: 'get'
}
);
}; };
const post = (id) => { const post = (id) => {
request('/api', { id }, { request(
responseType: 'blob' '/api',
}).then((data) => { { id },
{
responseType: 'blob'
}
).then((data) => {
console.log(data); console.log(data);
}); });
}; };
@ -80,7 +93,6 @@ export default {
// post(2); // post(2);
post(3); post(3);
// setTimeout(() => { // setTimeout(() => {
// request('/api', null, { // request('/api', null, {
// throttle: 3000, // throttle: 3000,
@ -138,8 +150,8 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import "~@/styles/mixins/hairline"; @import '~@/styles/mixins/hairline';
@import "~@/styles/mixins/hover"; @import '~@/styles/mixins/hover';
div { div {
padding: 20px; padding: 20px;
@ -154,6 +166,6 @@ div {
} }
.onepiece { .onepiece {
text-align: center; text-align: center;
.hairline("top"); .hairline('top');
} }
</style> </style>

View File

@ -5,7 +5,7 @@
<config> <config>
{ {
"title": "onepiece", "title": "onepiece",
"layout": "true" "layout": true
} }
</config> </config>
<script> <script>

View File

@ -1,13 +1,15 @@
import { defineRoute } from '@fesjs/fes'; import { defineRouteMeta, useRoute } from '@fesjs/fes';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
defineRoute({ export const meta = defineRouteMeta({
title: 'test', title: 'test',
name: 'test' name: 'test'
}); })
export default defineComponent({ export default defineComponent({
setup() { setup() {
const route = useRoute();
console.log(route)
return () => <div>hello tsx</div>; return () => <div>hello tsx</div>;
} }
}); });

View File

@ -1,5 +1,10 @@
// @ts-ignore // @ts-ignore
export * from '@@/core/coreExports'; export * from '@@/core/coreExports';
// @ts-ignore // @ts-ignore
export * from '@@/core/pluginExports'; export * from '@@/core/pluginExports';
export declare function defineRouteMeta(routeMeta: {
name?: string;
title?: string;
layout?: boolean | { sidebar?: boolean; header?: boolean; logo?: boolean };
});