mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
feat: access and model done
This commit is contained in:
parent
050e4a7b10
commit
8103071168
@ -49,7 +49,7 @@ export default (api) => {
|
||||
}
|
||||
]);
|
||||
|
||||
api.addRuntimePluginKey(() => 'notAllowHandler');
|
||||
api.addRuntimePluginKey(() => 'noAccessHandler');
|
||||
|
||||
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
|
||||
};
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { reactive, computed } from "vue";
|
||||
import { reactive, computed, inject } from "vue";
|
||||
|
||||
const accessKey = Symbol("plugin-access");
|
||||
|
||||
function isPromise(obj) {
|
||||
return (
|
||||
@ -106,32 +108,38 @@ const match = (path, accessIds) => {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasLoading = ()=>{
|
||||
return rolePromiseList.length || accessPromiseList.length
|
||||
}
|
||||
|
||||
const hasAccess = async (path) => {
|
||||
if(!hasLoading()){
|
||||
return match(path, getAllowAccessIds())
|
||||
}
|
||||
await Promise.all(rolePromiseList.concat(accessPromiseList));
|
||||
return match(path, getAllowAccessIds())
|
||||
};
|
||||
|
||||
const allowPageIds = computed(getAllowAccessIds);
|
||||
const hasLoading = () => {
|
||||
return rolePromiseList.length || accessPromiseList.length;
|
||||
};
|
||||
|
||||
const hasAccess = async (path) => {
|
||||
if (!hasLoading()) {
|
||||
return match(path, getAllowAccessIds());
|
||||
}
|
||||
await Promise.all(rolePromiseList.concat(accessPromiseList));
|
||||
return match(path, getAllowAccessIds());
|
||||
};
|
||||
|
||||
export const install = (app) => {
|
||||
const allowPageIds = computed(getAllowAccessIds);
|
||||
const useAccess = (path) => {
|
||||
const result = computed(() => {
|
||||
return match(path, allowPageIds.value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
app.provide(accessKey, useAccess);
|
||||
};
|
||||
|
||||
export const access = {
|
||||
hasAccess,
|
||||
hasLoading,
|
||||
setRole,
|
||||
setAccess
|
||||
}
|
||||
setAccess,
|
||||
};
|
||||
|
||||
export const useAccess = (path) => {
|
||||
const result = computed(() => {
|
||||
return match(path, allowPageIds.value);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return inject(accessKey)(path);
|
||||
};
|
||||
|
@ -1,15 +1,6 @@
|
||||
import { access } from "./core";
|
||||
import { access, install } from "./core";
|
||||
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
|
||||
|
||||
async function getInitialState() {
|
||||
const appGetInitialState = plugin.applyPlugins({
|
||||
key: "getInitialState",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {},
|
||||
});
|
||||
return await appGetInitialState;
|
||||
}
|
||||
|
||||
export function onRouterCreated({ router }) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
let path;
|
||||
@ -18,21 +9,23 @@ export function onRouterCreated({ router }) {
|
||||
} else {
|
||||
path = to.path;
|
||||
}
|
||||
// 等待初始化数据
|
||||
await getInitialState();
|
||||
const canRoute = await access.hasAccess(path);
|
||||
if (canRoute) {
|
||||
next();
|
||||
} else {
|
||||
const notAllowHandler = plugin.applyPlugins({
|
||||
key: "notAllowHandler",
|
||||
const noAccessHandler = plugin.applyPlugins({
|
||||
key: "noAccessHandler",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: null,
|
||||
});
|
||||
if (notAllowHandler && typeof notAllowHandler === "function") {
|
||||
notAllowHandler(router, to, from);
|
||||
if (noAccessHandler && typeof noAccessHandler === "function") {
|
||||
noAccessHandler(router, to, from);
|
||||
}
|
||||
next(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function onAppCreated({ app }) {
|
||||
install(app)
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ export default function (api) {
|
||||
key: 'addRuntimePluginKey',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [
|
||||
// 初始化数据
|
||||
'beforeRender',
|
||||
'modifyClientRenderOpts',
|
||||
'rootContainer',
|
||||
// app生成时触发
|
||||
@ -25,9 +27,7 @@ export default function (api) {
|
||||
// 修改路由
|
||||
'patchRoutes',
|
||||
// 生成router时触发
|
||||
'onRouterCreated',
|
||||
// 初始化数据
|
||||
'getInitialState'
|
||||
'onRouterCreated'
|
||||
]
|
||||
});
|
||||
const plugins = await api.applyPlugins({
|
||||
|
@ -13,7 +13,7 @@ import { getRoutes } from './core/routes/routes';
|
||||
{{{ entryCodeAhead }}}
|
||||
|
||||
const renderClient = (opts = {}) => {
|
||||
const { plugin, routes, rootElement } = opts;
|
||||
const { plugin, routes, rootElement, initialState } = opts;
|
||||
const rootContainer = plugin.applyPlugins({
|
||||
type: ApplyPluginsType.modify,
|
||||
key: 'rootContainer',
|
||||
@ -25,6 +25,7 @@ const renderClient = (opts = {}) => {
|
||||
});
|
||||
|
||||
const app = createApp(rootContainer);
|
||||
app.provide("initialState", initialState);
|
||||
|
||||
plugin.applyPlugins({
|
||||
key: 'onAppCreated',
|
||||
@ -32,7 +33,6 @@ const renderClient = (opts = {}) => {
|
||||
args: { app },
|
||||
});
|
||||
|
||||
// TODO other plugins install
|
||||
if (rootElement) {
|
||||
app.mount(rootElement);
|
||||
}
|
||||
@ -47,6 +47,7 @@ const getClientRender = (args = {}) => plugin.applyPlugins({
|
||||
key: 'modifyClientRenderOpts',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
initialState: args.initialState,
|
||||
routes: args.routes || getRoutes(),
|
||||
plugin,
|
||||
rootElement: '{{{ rootElement }}}',
|
||||
@ -60,8 +61,35 @@ const getClientRender = (args = {}) => plugin.applyPlugins({
|
||||
args,
|
||||
});
|
||||
|
||||
const clientRender = getClientRender();
|
||||
export default clientRender();
|
||||
|
||||
|
||||
const beforeRenderConfig = plugin.applyPlugins({
|
||||
key: "beforeRender",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
loading: defineComponent(() => () => <></>),
|
||||
action: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const beforeRender = async () => {
|
||||
if (typeof beforeRenderConfig.action === "function") {
|
||||
const app = createApp(beforeRenderConfig.loading);
|
||||
app.mount("#app");
|
||||
const initialState = await beforeRenderConfig.action();
|
||||
app.unmount();
|
||||
return initialState;
|
||||
}
|
||||
};
|
||||
|
||||
const render = async () => {
|
||||
const initialState = await beforeRender();
|
||||
const clientRender = getClientRender({initialState});
|
||||
clientRender();
|
||||
};
|
||||
|
||||
render();
|
||||
|
||||
|
||||
{{{ entryCode }}}
|
||||
|
||||
|
@ -83,8 +83,5 @@ export default (api) => {
|
||||
}
|
||||
]);
|
||||
|
||||
// 注册 initialStateConfig 方法
|
||||
api.addRuntimePluginKey(() => 'initialStateConfig');
|
||||
|
||||
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
|
||||
};
|
||||
|
@ -1,34 +1,12 @@
|
||||
import { reactive, toRefs, onMounted } from "vue";
|
||||
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
|
||||
|
||||
async function getInitialState() {
|
||||
const appGetInitialState = plugin.applyPlugins({
|
||||
key: "getInitialState",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {},
|
||||
});
|
||||
return await appGetInitialState;
|
||||
}
|
||||
const initState = reactive({
|
||||
initialState: undefined,
|
||||
loading: true,
|
||||
error: undefined,
|
||||
});
|
||||
import { reactive, toRefs, inject } from "vue";
|
||||
|
||||
export default function initalModel() {
|
||||
const refresh = async () => {
|
||||
initState.loading = true;
|
||||
initState.error = undefined;
|
||||
try {
|
||||
const res = await getInitialState();
|
||||
initState.initialState = res;
|
||||
initState.loading = false;
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
initState.loading = false;
|
||||
initState.error = e;
|
||||
}
|
||||
const initialState = reactive(inject("initialState"));
|
||||
const setInitialState = (obj) => {
|
||||
initState = reactive(obj);
|
||||
};
|
||||
onMounted(refresh);
|
||||
return toRefs(initState);
|
||||
return toRefs({
|
||||
initialState,
|
||||
setInitialState
|
||||
});
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
import { inject } from "vue";
|
||||
|
||||
const modelKey = Symbol("plugin-model");
|
||||
|
||||
{{{userImports}}}
|
||||
{{{extraImports}}}
|
||||
|
||||
@ -10,16 +14,26 @@ export const models = {
|
||||
{{/userModels}}
|
||||
}
|
||||
const cache = new Map();
|
||||
|
||||
export const install = (app)=>{
|
||||
const useModel = (name) => {
|
||||
const model = models[name];
|
||||
if(model === undefined){
|
||||
throw new Error("[plugin-model]: useModel, name is undefined.");
|
||||
}
|
||||
if (typeof model !== "function") {
|
||||
throw new Error("[plugin-model]: useModel is not a function.");
|
||||
}
|
||||
if(!cache.has(name)){
|
||||
cache.set(name, model())
|
||||
}
|
||||
return cache.get(name)
|
||||
};
|
||||
app.provide(modelKey, useModel);
|
||||
}
|
||||
|
||||
export const useModel = (name) => {
|
||||
const model = models[name];
|
||||
if(model === undefined){
|
||||
throw new Error("[plugin-model]: useModel, name is undefined.");
|
||||
}
|
||||
if (typeof model !== "function") {
|
||||
throw new Error("[plugin-model]: useModel is not a function.");
|
||||
}
|
||||
if(!cache.has(name)){
|
||||
cache.set(name, model())
|
||||
}
|
||||
return cache.get(name)
|
||||
};
|
||||
return inject(modelKey)(name);
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,26 +1,5 @@
|
||||
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
|
||||
import { useModel } from "./core.js";
|
||||
import { install } from "./core";
|
||||
|
||||
export function rootContainer(childComponent, args) {
|
||||
const useRuntimeConfig =
|
||||
plugin.applyPlugins({
|
||||
key: "initialStateConfig",
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {},
|
||||
}) || {};
|
||||
return {
|
||||
setup() {
|
||||
const { loading } = useModel("@@initialState") || {};
|
||||
return () => {
|
||||
if (loading.value) {
|
||||
return useRuntimeConfig.loading ? (
|
||||
<useRuntimeConfig.loading />
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
}
|
||||
return <childComponent />;
|
||||
};
|
||||
},
|
||||
};
|
||||
export function onAppCreated({ app }) {
|
||||
install(app)
|
||||
}
|
||||
|
@ -1,27 +1,19 @@
|
||||
import { access } from '@webank/fes';
|
||||
import PageLoading from '@/components/PageLoading.vue';
|
||||
|
||||
/**
|
||||
* 获取用户信息比较慢的时候会展示一个 loading
|
||||
*/
|
||||
export const initialStateConfig = {
|
||||
loading: <PageLoading />
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置页面初始化状态
|
||||
*/
|
||||
export async function getInitialState() {
|
||||
const { setRole } = access;
|
||||
const syncFunc = () => new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
setRole('admin');
|
||||
resolve({
|
||||
a: 1,
|
||||
b: 2
|
||||
});
|
||||
}, 3000);
|
||||
});
|
||||
const res = await syncFunc();
|
||||
return res;
|
||||
}
|
||||
export const beforeRender = {
|
||||
loading: <PageLoading />,
|
||||
action() {
|
||||
const { setRole } = access;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
setRole('admin');
|
||||
resolve({
|
||||
a: 1,
|
||||
b: 2
|
||||
});
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ export default {
|
||||
const router = useRouter();
|
||||
onMounted(() => {
|
||||
console.log(router);
|
||||
console.log(initialState.value);
|
||||
console.log(initialState);
|
||||
console.log('mounted1!!');
|
||||
// router.push('/onepiece');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user