feat: add info
This commit is contained in:
23
packages/vue/package.json
Normal file
23
packages/vue/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "@penna/vue",
|
||||
"type": "module",
|
||||
"version": "1.0.0-beta.1",
|
||||
"description": "this is penna core",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
"prepublish": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"pinia": "^3.0.3",
|
||||
"vue": "^3.5.20",
|
||||
"vue-router": "^4.5.1"
|
||||
}
|
||||
}
|
96
packages/vue/src/create-app.ts
Normal file
96
packages/vue/src/create-app.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import type { RouteRecordRaw, RouterOptions } from 'vue-router'
|
||||
import type { ModuleOptions } from './modules.ts'
|
||||
import { createApp as createClientApp, defineComponent, h } from 'vue'
|
||||
import { createRouter, createWebHistory, RouterView } from 'vue-router'
|
||||
import { useModules } from './utils/module.ts'
|
||||
|
||||
export interface CreateAppOptions {
|
||||
/**
|
||||
* 根容器选择器
|
||||
* @default "#app"
|
||||
*/
|
||||
rootContainer?: string
|
||||
/**
|
||||
* 模块配置
|
||||
*/
|
||||
modules?: ModuleOptions[]
|
||||
/**
|
||||
* 路由信息配置项
|
||||
* @default {}
|
||||
*/
|
||||
routerOptions?: RouterOptions
|
||||
/**
|
||||
* 根路由重定向地址
|
||||
* @default "/home"
|
||||
*/
|
||||
rootRedirect?: string
|
||||
}
|
||||
|
||||
const RootComponent = defineComponent(
|
||||
(_) => {
|
||||
// 获取全局配置中的信息
|
||||
const { modules } = useModules()
|
||||
for (const module of modules) {
|
||||
if (module.setup) {
|
||||
module.setup?.()
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
return h(RouterView)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
export async function createApp(options: CreateAppOptions) {
|
||||
const app = createClientApp(RootComponent)
|
||||
const modules = options?.modules ?? []
|
||||
// 挂载到全局的配置中
|
||||
app.config.globalProperties.$modules = modules
|
||||
let routes = (options?.routerOptions?.routes ?? []) as RouteRecordRaw[]
|
||||
// 1. 先执行所有模块的setup方法
|
||||
for (const module of modules) {
|
||||
// 顺序执行以避免问题
|
||||
if (module.app) {
|
||||
// 支持异步
|
||||
await module.app(app)
|
||||
}
|
||||
// 是否存在静态的路由配置信息
|
||||
if (module.routes) {
|
||||
if (typeof module.routes === 'function') {
|
||||
routes = module.routes(routes) ?? routes
|
||||
}
|
||||
else {
|
||||
routes.push(...(module.routes ?? []))
|
||||
}
|
||||
}
|
||||
}
|
||||
let rootRedirect = options?.rootRedirect ?? '/home'
|
||||
if (rootRedirect === '/') {
|
||||
console.error('[createApp]: rootRedirect cannot be \'/\', fall back to \'/home\'')
|
||||
rootRedirect = '/home'
|
||||
}
|
||||
const rootRoute: RouteRecordRaw = {
|
||||
path: '',
|
||||
name: 'ROOT_ROUTE',
|
||||
redirect: rootRedirect,
|
||||
children: routes,
|
||||
}
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
rootRoute,
|
||||
],
|
||||
...options?.routerOptions,
|
||||
})
|
||||
// 2. 再执行所有模块的router方法
|
||||
for (const module of modules) {
|
||||
if (module.router) {
|
||||
// 执行router相关的配置
|
||||
await module.router(router)
|
||||
}
|
||||
}
|
||||
app.use(router)
|
||||
// 判断是否已经完成了router的加载
|
||||
await router.isReady()
|
||||
app.mount(options?.rootContainer ?? '#app')
|
||||
}
|
3
packages/vue/src/index.ts
Normal file
3
packages/vue/src/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { createApp } from './create-app'
|
||||
export type { ModuleOptions } from './modules'
|
||||
export { defineModule } from './modules'
|
36
packages/vue/src/modules.ts
Normal file
36
packages/vue/src/modules.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import type { App } from 'vue'
|
||||
import type { Router, RouteRecordRaw } from 'vue-router'
|
||||
|
||||
export interface PageType {
|
||||
component: any
|
||||
meta?: RouteRecordRaw['meta']
|
||||
name?: string
|
||||
}
|
||||
|
||||
export interface ModuleOptions {
|
||||
/**
|
||||
* 初始化模块配置
|
||||
* @param app
|
||||
*/
|
||||
app?: (app: App) => Promise<void> | void
|
||||
/**
|
||||
* 静态的路由配置信息
|
||||
*/
|
||||
routes?: RouteRecordRaw[] | ((routes: RouteRecordRaw[]) => RouteRecordRaw[])
|
||||
/**
|
||||
* 动态路由页面配置
|
||||
*/
|
||||
pages?: Record<string, PageType>
|
||||
/**
|
||||
* 给用户router的实例,进行操作
|
||||
*/
|
||||
router?: (router: Router) => Promise<void> | void
|
||||
/**
|
||||
* 这里的setup就是rootComponent的setup
|
||||
*/
|
||||
setup?: () => void
|
||||
}
|
||||
|
||||
export function defineModule(options: ModuleOptions) {
|
||||
return options
|
||||
}
|
13
packages/vue/src/utils/module.ts
Normal file
13
packages/vue/src/utils/module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { ModuleOptions } from '../modules.ts'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
export function useModules() {
|
||||
const instance = getCurrentInstance()
|
||||
if (!instance) {
|
||||
throw new Error('Failed to get current instance')
|
||||
}
|
||||
const modules = (instance.appContext.config.globalProperties?.$modules ?? []) as ModuleOptions[]
|
||||
return {
|
||||
modules,
|
||||
}
|
||||
}
|
11
packages/vue/tsconfig.json
Normal file
11
packages/vue/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../tsconfig.json"
|
||||
],
|
||||
"compilerOptions": {
|
||||
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
9
packages/vue/tsdown.config.ts
Normal file
9
packages/vue/tsdown.config.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
export default defineConfig({
|
||||
platform: 'browser',
|
||||
entry: [
|
||||
'./src/index.ts',
|
||||
],
|
||||
dts: true,
|
||||
})
|
Reference in New Issue
Block a user