mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
refactor: beforeRender迁移到router创建后
This commit is contained in:
parent
773082f8e1
commit
cc20923e07
@ -1,12 +1,15 @@
|
||||
import { winPath } from '@fesjs/utils';
|
||||
import { readdirSync, statSync } from 'fs';
|
||||
import { readdirSync, statSync, existsSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { winPath } from '@fesjs/utils';
|
||||
|
||||
/**
|
||||
* 获取文件夹所有JS文件路径
|
||||
* @param {string} dir
|
||||
*/
|
||||
function getDirFilePaths(dir) {
|
||||
if (!existsSync(dir)) {
|
||||
return [];
|
||||
}
|
||||
const dirs = readdirSync(dir);
|
||||
let pathList = [];
|
||||
for (const name of dirs) {
|
||||
@ -26,13 +29,13 @@ function getDirFilePaths(dir) {
|
||||
* @param {*} path
|
||||
*/
|
||||
function pathToHump(path, root) {
|
||||
return path.replace(root, '')
|
||||
return path
|
||||
.replace(root, '')
|
||||
.replace('.js', '')
|
||||
.replace(RegExp('(/|\\.|-|_)\\S', 'g'), text => text[1].toUpperCase())
|
||||
.replace(/\S/, text => text.toLowerCase());
|
||||
.replace(RegExp('(/|\\.|-|_)\\S', 'g'), (text) => text[1].toUpperCase())
|
||||
.replace(/\S/, (text) => text.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
function parsePlugin(paths = [], root) {
|
||||
const plugins = [];
|
||||
const importPlugins = [];
|
||||
@ -53,6 +56,6 @@ export function parseStore(root) {
|
||||
}
|
||||
});
|
||||
return {
|
||||
...parsePlugin(pluginPaths, root)
|
||||
...parsePlugin(pluginPaths, root),
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { winPath } from '@fesjs/utils';
|
||||
import { parseStore } from './helper';
|
||||
import { name } from '../package.json';
|
||||
import { parseStore } from './helper';
|
||||
|
||||
const namespace = 'plugin-pinia';
|
||||
|
||||
|
@ -16,8 +16,6 @@ export default function (api) {
|
||||
key: 'addRuntimePluginKey',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [
|
||||
// 初始化数据
|
||||
'beforeRender',
|
||||
// modify渲染工具
|
||||
'modifyClientRenderOpts',
|
||||
'rootContainer',
|
||||
@ -31,6 +29,8 @@ export default function (api) {
|
||||
'modifyCreateHistory',
|
||||
// 修改路由配置
|
||||
'modifyRoute',
|
||||
// 初始化数据
|
||||
'beforeRender',
|
||||
// 生成router时触发
|
||||
'onRouterCreated',
|
||||
],
|
||||
|
@ -1,13 +1,11 @@
|
||||
{{{ importsAhead }}}
|
||||
import {
|
||||
createApp,
|
||||
reactive,
|
||||
} from 'vue';
|
||||
import { plugin } from './core/plugin';
|
||||
import './core/pluginRegister';
|
||||
import { ApplyPluginsType } from '{{{ runtimePath }}}';
|
||||
import { getRoutes } from './core/routes/routes';
|
||||
import { updateInitialState } from './initialState';
|
||||
import DefaultContainer from './defaultContainer.jsx';
|
||||
|
||||
{{{ imports }}}
|
||||
@ -40,34 +38,10 @@ const renderClient = (opts = {}) => {
|
||||
return app;
|
||||
}
|
||||
|
||||
const beforeRender = async ({rootElement}) => {
|
||||
const beforeRenderConfig = plugin.applyPlugins({
|
||||
key: "beforeRender",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
loading: null,
|
||||
action: null
|
||||
},
|
||||
});
|
||||
if (typeof beforeRenderConfig.action === "function") {
|
||||
const app = createApp(beforeRenderConfig.loading);
|
||||
app.mount(rootElement);
|
||||
try {
|
||||
const initialState = await beforeRenderConfig.action();
|
||||
updateInitialState(initialState || {})
|
||||
} catch(e){
|
||||
console.error(`[fes] beforeRender执行出现异常:`);
|
||||
console.error(e);
|
||||
}
|
||||
app.unmount();
|
||||
app._container.innerHTML = '';
|
||||
}
|
||||
};
|
||||
|
||||
const getClientRender = (args = {}) => plugin.applyPlugins({
|
||||
key: 'render',
|
||||
type: ApplyPluginsType.compose,
|
||||
initialValue: async () => {
|
||||
initialValue: () => {
|
||||
const opts = plugin.applyPlugins({
|
||||
key: 'modifyClientRenderOpts',
|
||||
type: ApplyPluginsType.modify,
|
||||
@ -80,7 +54,6 @@ const getClientRender = (args = {}) => plugin.applyPlugins({
|
||||
{{/enableTitle}}
|
||||
},
|
||||
});
|
||||
await beforeRender(opts);
|
||||
return renderClient(opts);
|
||||
},
|
||||
args,
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { createApp } from 'vue';
|
||||
import { createRouter as createVueRouter, {{{ CREATE_HISTORY }}}, ApplyPluginsType } from '{{{ runtimePath }}}';
|
||||
import { plugin } from '../plugin';
|
||||
import { updateInitialState } from '../../initialState';
|
||||
|
||||
const ROUTER_BASE = '{{{ routerBase }}}';
|
||||
let router = null;
|
||||
@ -28,12 +30,45 @@ export const createRouter = (routes) => {
|
||||
createHistory: createHistory
|
||||
},
|
||||
});
|
||||
|
||||
history = route['createHistory']?.(route.base);
|
||||
router = createVueRouter({
|
||||
history,
|
||||
routes: route.routes
|
||||
});
|
||||
|
||||
let isInit = false
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
if(!isInit) {
|
||||
isInit = true
|
||||
const beforeRenderConfig = plugin.applyPlugins({
|
||||
key: "beforeRender",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
loading: null,
|
||||
action: null
|
||||
},
|
||||
});
|
||||
if (typeof beforeRenderConfig.action === "function") {
|
||||
const rootElement = document.createElement('div');
|
||||
document.body.appendChild(rootElement)
|
||||
const app = createApp(beforeRenderConfig.loading);
|
||||
app.mount(rootElement);
|
||||
try {
|
||||
const initialState = await beforeRenderConfig.action({router, history});
|
||||
updateInitialState(initialState || {})
|
||||
} catch(e){
|
||||
console.error(`[fes] beforeRender执行出现异常:`);
|
||||
console.error(e);
|
||||
}
|
||||
app.unmount();
|
||||
app._container.innerHTML = '';
|
||||
document.body.removeChild(rootElement);
|
||||
}
|
||||
}
|
||||
next();
|
||||
})
|
||||
|
||||
plugin.applyPlugins({
|
||||
key: 'onRouterCreated',
|
||||
type: ApplyPluginsType.event,
|
||||
|
@ -20,7 +20,7 @@ function isPromiseLike(obj) {
|
||||
export const ApplyPluginsType = {
|
||||
compose: 'compose',
|
||||
event: 'event',
|
||||
modify: 'modify'
|
||||
modify: 'modify',
|
||||
};
|
||||
|
||||
export default class Plugin {
|
||||
@ -44,10 +44,7 @@ export default class Plugin {
|
||||
assert(!!plugin.apply, 'register failed, plugin.apply must supplied');
|
||||
assert(!!plugin.path, 'register failed, plugin.path must supplied');
|
||||
Object.keys(plugin.apply).forEach((key) => {
|
||||
assert(
|
||||
this.validKeys.indexOf(key) > -1,
|
||||
`register failed, invalid key ${key} from plugin ${plugin.path}.`
|
||||
);
|
||||
assert(this.validKeys.indexOf(key) > -1, `register failed, invalid key ${key} from plugin ${plugin.path}.`);
|
||||
if (!this.hooks[key]) this.hooks[key] = [];
|
||||
this.hooks[key] = this.hooks[key].concat(plugin.apply[key]);
|
||||
});
|
||||
@ -74,20 +71,11 @@ export default class Plugin {
|
||||
return hooks;
|
||||
}
|
||||
|
||||
applyPlugins({
|
||||
key,
|
||||
type,
|
||||
initialValue,
|
||||
args,
|
||||
async
|
||||
}) {
|
||||
applyPlugins({ key, type, initialValue, args, async }) {
|
||||
const hooks = this.getHooks(key) || [];
|
||||
|
||||
if (args) {
|
||||
assert(
|
||||
typeof args === 'object',
|
||||
'applyPlugins failed, args must be plain object.'
|
||||
);
|
||||
assert(typeof args === 'object', 'applyPlugins failed, args must be plain object.');
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
@ -95,8 +83,10 @@ export default class Plugin {
|
||||
if (async) {
|
||||
return hooks.reduce(
|
||||
async (memo, hook) => {
|
||||
assert(typeof hook === 'function' || typeof hook === 'object' || isPromiseLike(hook),
|
||||
`applyPlugins failed, all hooks for key ${key} must be function, plain object or Promise.`);
|
||||
assert(
|
||||
typeof hook === 'function' || typeof hook === 'object' || isPromiseLike(hook),
|
||||
`applyPlugins failed, all hooks for key ${key} must be function, plain object or Promise.`,
|
||||
);
|
||||
if (isPromiseLike(memo)) {
|
||||
memo = await memo;
|
||||
}
|
||||
@ -112,15 +102,13 @@ export default class Plugin {
|
||||
}
|
||||
return { ...memo, ...hook };
|
||||
},
|
||||
isPromiseLike(initialValue)
|
||||
? initialValue
|
||||
: Promise.resolve(initialValue)
|
||||
isPromiseLike(initialValue) ? initialValue : Promise.resolve(initialValue),
|
||||
);
|
||||
}
|
||||
return hooks.reduce((memo, hook) => {
|
||||
assert(
|
||||
typeof hook === 'function' || typeof hook === 'object',
|
||||
`applyPlugins failed, all hooks for key ${key} must be function or plain object.`
|
||||
`applyPlugins failed, all hooks for key ${key} must be function or plain object.`,
|
||||
);
|
||||
if (typeof hook === 'function') {
|
||||
return hook(memo, args);
|
||||
@ -128,21 +116,18 @@ export default class Plugin {
|
||||
return { ...memo, ...hook };
|
||||
}, initialValue);
|
||||
|
||||
|
||||
case ApplyPluginsType.event:
|
||||
return hooks.forEach((hook) => {
|
||||
assert(
|
||||
typeof hook === 'function',
|
||||
`applyPlugins failed, all hooks for key ${key} must be function.`
|
||||
);
|
||||
assert(typeof hook === 'function', `applyPlugins failed, all hooks for key ${key} must be function.`);
|
||||
hook(args);
|
||||
});
|
||||
|
||||
case ApplyPluginsType.compose:
|
||||
return () => _compose({
|
||||
fns: hooks.concat(initialValue),
|
||||
args
|
||||
})();
|
||||
return () =>
|
||||
_compose({
|
||||
fns: hooks.concat(initialValue),
|
||||
args,
|
||||
})();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -36,9 +36,6 @@ export default defineBuildConfig({
|
||||
icon: '/wine-outline.svg',
|
||||
match: ['/route/*'],
|
||||
},
|
||||
{
|
||||
name: 'store',
|
||||
},
|
||||
{
|
||||
name: 'editor',
|
||||
icon: '/wine-outline.svg',
|
||||
@ -74,9 +71,6 @@ export default defineBuildConfig({
|
||||
['1', '有效的'],
|
||||
],
|
||||
},
|
||||
vuex: {
|
||||
strict: true,
|
||||
},
|
||||
dynamicImport: true,
|
||||
monacoEditor: {
|
||||
languages: ['javascript', 'typescript', 'html', 'json'],
|
||||
|
@ -58,7 +58,6 @@
|
||||
"@fesjs/plugin-pinia": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-request": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-sass": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-vuex": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-windicss": "^3.0.0-rc.0",
|
||||
"core-js": "^3.27.0",
|
||||
"cssnano": "^5.1.12",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { access as accessApi, pinia } from '@fesjs/fes';
|
||||
import { access as accessApi } from '@fesjs/fes';
|
||||
import PageLoading from '@/components/pageLoading.vue';
|
||||
import UserCenter from '@/components/userCenter.vue';
|
||||
import { useStore } from '@/store/main';
|
||||
@ -9,7 +9,7 @@ export const beforeRender = {
|
||||
const { setRole } = accessApi;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const store = useStore(pinia);
|
||||
const store = useStore();
|
||||
store.$patch({
|
||||
userName: '李雷',
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>{{store.counter}}</div>
|
||||
<div>{{ store.counter }} {{ store.userName }}</div>
|
||||
<FButton class="m-2" @click="store.increment">Button</FButton>
|
||||
</template>
|
||||
<config>
|
||||
@ -9,23 +9,21 @@
|
||||
}
|
||||
</config>
|
||||
<script>
|
||||
import { useStore } from '@/store/main';
|
||||
import { FButton } from '@fesjs/fes-design';
|
||||
import { useStore } from '@/store/main';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FButton
|
||||
FButton,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
console.log(store);
|
||||
return {
|
||||
store
|
||||
store,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h4>Vuex</h4>
|
||||
<div>
|
||||
<button @click="increment">click me:{{doubleCount}}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button :disabled="disabled" @click="login">async login</button>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="fooBarIncrement">
|
||||
foo/bar:{{fooBarDoubleCount}}
|
||||
</button>
|
||||
</div>
|
||||
<div>{{address}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<config>
|
||||
{
|
||||
"name": "store",
|
||||
"title": "$store"
|
||||
}
|
||||
</config>
|
||||
<script>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
import { MUTATION_TYPES, GETTER_TYPES, ACTION_TYPES } from '@fesjs/fes';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const store = useStore();
|
||||
console.log('store==>', store);
|
||||
const disabled = ref(false);
|
||||
return {
|
||||
address: computed(() => store.getters[GETTER_TYPES.user.address]),
|
||||
doubleCount: computed(
|
||||
() => store.getters[GETTER_TYPES.counter.doubleCount]
|
||||
),
|
||||
disabled,
|
||||
increment: () => store.commit(MUTATION_TYPES.counter.increment),
|
||||
login: () => {
|
||||
disabled.value = true;
|
||||
store.dispatch(ACTION_TYPES.user.login).then((res) => {
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(res);
|
||||
disabled.value = false;
|
||||
});
|
||||
},
|
||||
fooBarIncrement: () => store.commit(MUTATION_TYPES.fooBar.increment),
|
||||
fooBarDoubleCount: computed(
|
||||
() => store.getters[GETTER_TYPES.fooBar.doubleCount]
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.page {
|
||||
}
|
||||
</style>
|
@ -7,8 +7,8 @@ export const useStore = defineStore('main', {
|
||||
state: () => ({
|
||||
// all these properties will have their type inferred automatically
|
||||
counter: 0,
|
||||
name: 'Eduardo',
|
||||
isAdmin: true
|
||||
userName: 'Eduardo',
|
||||
isAdmin: true,
|
||||
}),
|
||||
actions: {
|
||||
increment() {
|
||||
@ -16,6 +16,6 @@ export const useStore = defineStore('main', {
|
||||
},
|
||||
randomizeCounter() {
|
||||
this.counter = Math.round(100 * Math.random());
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,23 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: () => ({
|
||||
count: 0
|
||||
}),
|
||||
mutations: {
|
||||
increment(state) {
|
||||
state.count++;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
doubleCount(state) {
|
||||
return state.count * 2;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
asyncIncrement({ commit }) {
|
||||
setTimeout(() => {
|
||||
commit('increment');
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: () => ({
|
||||
count: 0
|
||||
}),
|
||||
mutations: {
|
||||
increment(state) {
|
||||
state.count++;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
doubleCount(state) {
|
||||
return state.count * 2;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
asyncIncrement({ commit }) {
|
||||
setTimeout(() => {
|
||||
commit('increment');
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
import { createLogger } from 'vuex';
|
||||
|
||||
export default createLogger();
|
@ -1,54 +0,0 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: () => ({
|
||||
name: 'aring',
|
||||
age: 20,
|
||||
count: 0
|
||||
}),
|
||||
mutations: {
|
||||
increment(state) {
|
||||
state.count++;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
doubleCount(state) {
|
||||
return state.count * 2;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
asyncIncrement({ commit }) {
|
||||
setTimeout(() => {
|
||||
commit('increment');
|
||||
}, 2000);
|
||||
},
|
||||
login() {
|
||||
return new Promise((reslove) => {
|
||||
setTimeout(() => {
|
||||
console.log('login');
|
||||
reslove('OK');
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
address: {
|
||||
state: () => ({
|
||||
province: '广东省',
|
||||
city: '深圳市',
|
||||
zone: '南山区'
|
||||
}),
|
||||
getters: {
|
||||
address(state) {
|
||||
return state.province + state.city + state.zone;
|
||||
}
|
||||
}
|
||||
},
|
||||
posts: {
|
||||
namespaced: true,
|
||||
state: () => ({}),
|
||||
mutations: {
|
||||
doSomething() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -84,9 +84,6 @@ export default defineBuildConfig({
|
||||
['1', '有效的'],
|
||||
],
|
||||
},
|
||||
vuex: {
|
||||
strict: true,
|
||||
},
|
||||
dynamicImport: true,
|
||||
monacoEditor: {
|
||||
languages: ['javascript', 'typescript', 'html', 'json'],
|
||||
|
@ -57,7 +57,6 @@
|
||||
"@fesjs/plugin-sass": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-monaco-editor": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-windicss": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-pinia": "^3.0.0-rc.0",
|
||||
"@fesjs/plugin-watermark": "^3.0.0-rc.0",
|
||||
"@fesjs/fes-design": "^0.7.0",
|
||||
"core-js": "^3.27.0",
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { access as accessApi, pinia, createWatermark } from '@fesjs/fes';
|
||||
import { access as accessApi, createWatermark } from '@fesjs/fes';
|
||||
import { ref, watch } from 'vue';
|
||||
import PageLoading from '@/components/pageLoading.vue';
|
||||
import UserCenter from '@/components/userCenter.vue';
|
||||
import { useStore } from '@/store/main';
|
||||
|
||||
export const beforeRender = {
|
||||
loading: <PageLoading />,
|
||||
@ -10,11 +9,7 @@ export const beforeRender = {
|
||||
const { setRole } = accessApi;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const store = useStore(pinia);
|
||||
store.$patch({
|
||||
userName: '李雷',
|
||||
});
|
||||
setRole('menuTest');
|
||||
setRole('admin');
|
||||
resolve({
|
||||
userName: '李雷',
|
||||
});
|
||||
@ -24,11 +19,11 @@ export const beforeRender = {
|
||||
},
|
||||
};
|
||||
|
||||
export const login = {
|
||||
hasLogin() {
|
||||
return !!sessionStorage.getItem('login');
|
||||
},
|
||||
};
|
||||
// export const login = {
|
||||
// hasLogin() {
|
||||
// return !!sessionStorage.getItem('login');
|
||||
// },
|
||||
// };
|
||||
|
||||
export const layout = (layoutConfig, { initialState }) => ({
|
||||
...layoutConfig,
|
||||
|
@ -8,7 +8,7 @@ export const useStore = defineStore('main', {
|
||||
// all these properties will have their type inferred automatically
|
||||
counter: 0,
|
||||
name: 'Eduardo',
|
||||
isAdmin: true
|
||||
isAdmin: true,
|
||||
}),
|
||||
actions: {
|
||||
increment() {
|
||||
@ -16,6 +16,6 @@ export const useStore = defineStore('main', {
|
||||
},
|
||||
randomizeCounter() {
|
||||
this.counter = Math.round(100 * Math.random());
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user