diff --git a/packages/fes-plugin-access/src/index.js b/packages/fes-plugin-access/src/index.js index 0b1224c8..b041cecf 100644 --- a/packages/fes-plugin-access/src/index.js +++ b/packages/fes-plugin-access/src/index.js @@ -49,7 +49,7 @@ export default (api) => { } ]); - api.addRuntimePluginKey(() => 'notAllowHandler'); + api.addRuntimePluginKey(() => 'noAccessHandler'); api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`); }; diff --git a/packages/fes-plugin-access/src/template/core.tpl b/packages/fes-plugin-access/src/template/core.tpl index 8152799e..0a286aa3 100644 --- a/packages/fes-plugin-access/src/template/core.tpl +++ b/packages/fes-plugin-access/src/template/core.tpl @@ -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; -} \ No newline at end of file + return inject(accessKey)(path); +}; diff --git a/packages/fes-plugin-access/src/template/runtime.tpl b/packages/fes-plugin-access/src/template/runtime.tpl index 379cfe33..cdb1f0d8 100644 --- a/packages/fes-plugin-access/src/template/runtime.tpl +++ b/packages/fes-plugin-access/src/template/runtime.tpl @@ -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) +} diff --git a/packages/fes-plugin-built-in/src/plugins/generateFiles/core/plugin/index.js b/packages/fes-plugin-built-in/src/plugins/generateFiles/core/plugin/index.js index 9285f28b..e574df9e 100644 --- a/packages/fes-plugin-built-in/src/plugins/generateFiles/core/plugin/index.js +++ b/packages/fes-plugin-built-in/src/plugins/generateFiles/core/plugin/index.js @@ -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({ diff --git a/packages/fes-plugin-built-in/src/plugins/generateFiles/fes/fes.tpl b/packages/fes-plugin-built-in/src/plugins/generateFiles/fes/fes.tpl index db5f2974..76e42e26 100644 --- a/packages/fes-plugin-built-in/src/plugins/generateFiles/fes/fes.tpl +++ b/packages/fes-plugin-built-in/src/plugins/generateFiles/fes/fes.tpl @@ -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 }}} diff --git a/packages/fes-plugin-model/src/index.js b/packages/fes-plugin-model/src/index.js index a775a56d..ca10132f 100644 --- a/packages/fes-plugin-model/src/index.js +++ b/packages/fes-plugin-model/src/index.js @@ -83,8 +83,5 @@ export default (api) => { } ]); - // 注册 initialStateConfig 方法 - api.addRuntimePluginKey(() => 'initialStateConfig'); - api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`); }; diff --git a/packages/fes-plugin-model/src/models/initialState.tpl b/packages/fes-plugin-model/src/models/initialState.tpl index 53be94f6..efc402bb 100644 --- a/packages/fes-plugin-model/src/models/initialState.tpl +++ b/packages/fes-plugin-model/src/models/initialState.tpl @@ -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 + }); } diff --git a/packages/fes-plugin-model/src/template/core.tpl b/packages/fes-plugin-model/src/template/core.tpl index 2cae17a6..5dc0ed61 100644 --- a/packages/fes-plugin-model/src/template/core.tpl +++ b/packages/fes-plugin-model/src/template/core.tpl @@ -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) -}; \ No newline at end of file + return inject(modelKey)(name); +}; + + diff --git a/packages/fes-plugin-model/src/template/runtime.tpl b/packages/fes-plugin-model/src/template/runtime.tpl index 242e1ea0..41c090a7 100644 --- a/packages/fes-plugin-model/src/template/runtime.tpl +++ b/packages/fes-plugin-model/src/template/runtime.tpl @@ -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 ? ( - - ) : ( - <> - ); - } - return ; - }; - }, - }; +export function onAppCreated({ app }) { + install(app) } diff --git a/packages/fes-template/src/app.js b/packages/fes-template/src/app.js index e24e2c1b..70e65954 100644 --- a/packages/fes-template/src/app.js +++ b/packages/fes-template/src/app.js @@ -1,27 +1,19 @@ import { access } from '@webank/fes'; import PageLoading from '@/components/PageLoading.vue'; -/** - * 获取用户信息比较慢的时候会展示一个 loading - */ -export const initialStateConfig = { - loading: -}; -/** - * 设置页面初始化状态 - */ -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: , + action() { + const { setRole } = access; + return new Promise((resolve) => { + setTimeout(() => { + setRole('admin'); + resolve({ + a: 1, + b: 2 + }); + }, 3000); + }); + } +}; diff --git a/packages/fes-template/src/pages/index.vue b/packages/fes-template/src/pages/index.vue index 6c02798a..36321b45 100644 --- a/packages/fes-template/src/pages/index.vue +++ b/packages/fes-template/src/pages/index.vue @@ -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'); });