diff --git a/package.json b/package.json index 69d9acf..89c72d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "front-next", - "version": "0.4.1", + "version": "0.5.0", "scripts": { "dev": "vite", "build": "vue-tsc --noEmit --skipLibCheck && vite build", diff --git a/src/cool/modules/test/components/about.vue b/src/cool/modules/test/components/about.vue new file mode 100644 index 0000000..40d3044 --- /dev/null +++ b/src/cool/modules/test/components/about.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/cool/modules/test/components/index.ts b/src/cool/modules/test/components/index.ts new file mode 100644 index 0000000..9e37562 --- /dev/null +++ b/src/cool/modules/test/components/index.ts @@ -0,0 +1,7 @@ +import About from "./about.vue"; + +export default { + About +}; + +// 导出的组件会以 name 参数命名全局注册,当前为: cl-about diff --git a/src/cool/modules/test/directives/index.ts b/src/cool/modules/test/directives/index.ts new file mode 100644 index 0000000..08dd2c8 --- /dev/null +++ b/src/cool/modules/test/directives/index.ts @@ -0,0 +1,13 @@ +// 参考官方例子 https://v3.vuejs.org/guide/custom-directive.html + +export default { + // 聚焦元素 + focus: { + mounted(el) { + el.focus(); + } + } +}; + +// 在模块中使用 +// diff --git a/src/cool/modules/test/index.ts b/src/cool/modules/test/index.ts new file mode 100644 index 0000000..9684a62 --- /dev/null +++ b/src/cool/modules/test/index.ts @@ -0,0 +1,19 @@ +import components from "./components"; +import directives from "./directives"; +import pages from "./pages"; +import service from "./service"; +import store from "./store"; +import views from "./views"; + +export default { + install() { + return { + components, + directives, + pages, + service, + store, + views + }; + } +}; diff --git a/src/cool/modules/test/pages/about.vue b/src/cool/modules/test/pages/about.vue new file mode 100644 index 0000000..364bb4c --- /dev/null +++ b/src/cool/modules/test/pages/about.vue @@ -0,0 +1,3 @@ + diff --git a/src/cool/modules/test/pages/index.ts b/src/cool/modules/test/pages/index.ts new file mode 100644 index 0000000..cdbbf0c --- /dev/null +++ b/src/cool/modules/test/pages/index.ts @@ -0,0 +1,8 @@ +// 导出的列表会自动注册到路由中 + +export default [ + { + path: "/test-pages/about", // 路由地址 + component: () => import("./about.vue") // 组件实例 + } +]; diff --git a/src/cool/modules/test/service/index.ts b/src/cool/modules/test/service/index.ts new file mode 100644 index 0000000..bd271d2 --- /dev/null +++ b/src/cool/modules/test/service/index.ts @@ -0,0 +1,5 @@ +import Test from "./test"; + +export default { + test: new Test() +}; diff --git a/src/cool/modules/test/service/test.ts b/src/cool/modules/test/service/test.ts new file mode 100644 index 0000000..22adc01 --- /dev/null +++ b/src/cool/modules/test/service/test.ts @@ -0,0 +1,19 @@ +import { BaseService, Service, Permission } from "/@/core"; + +@Service("test") +class Test extends BaseService { + // 继承后可使用:page、list、add、delete、update、info 6个基本接口 + + // 添加其他接口 + @Permission("batchAdd") // 是否需要权限控制,建议参数与请求地址保持一致 + batchAdd(params: any): Promise { + return this.request({ + url: "/batchAdd", + method: "GET", + params + // 参数与 axios 一致 + }); + } +} + +export default Test; diff --git a/src/cool/modules/test/store/calc.ts b/src/cool/modules/test/store/calc.ts new file mode 100644 index 0000000..7be1bf2 --- /dev/null +++ b/src/cool/modules/test/store/calc.ts @@ -0,0 +1,13 @@ +// 参考官方例子 https://vuex.vuejs.org/zh/ + +export default { + state: { + count: 0 + }, + mutations: { + increment(state: any) { + state.count++; + } + }, + actions: {} +}; diff --git a/src/cool/modules/test/store/index.ts b/src/cool/modules/test/store/index.ts new file mode 100644 index 0000000..9513ead --- /dev/null +++ b/src/cool/modules/test/store/index.ts @@ -0,0 +1,7 @@ +import calc from "./calc"; + +export default { + calc +}; + +// 导出后会以 模块名-calc 命名注册 diff --git a/src/cool/modules/test/views/about.vue b/src/cool/modules/test/views/about.vue new file mode 100644 index 0000000..364bb4c --- /dev/null +++ b/src/cool/modules/test/views/about.vue @@ -0,0 +1,3 @@ + diff --git a/src/cool/modules/test/views/index.ts b/src/cool/modules/test/views/index.ts new file mode 100644 index 0000000..ed088e4 --- /dev/null +++ b/src/cool/modules/test/views/index.ts @@ -0,0 +1,12 @@ +// 导出的列表会自动注册到 "/" 子路由中 + +export default [ + { + path: "/test-views/about", // 路由地址 + component: () => import("./about.vue"), // 组件实例 + meta: { + keepAlive: true, // 是否缓存路由 + label: "关于 cool-admin" // 路由名称 + } + } +]; diff --git a/src/core/module/index.ts b/src/core/module/index.ts index 5198efc..9c99638 100644 --- a/src/core/module/index.ts +++ b/src/core/module/index.ts @@ -1,11 +1,11 @@ import cool from "/@/cool"; import store from "/@/store"; import router from "/@/router"; -import { deepMerge, isFunction, isObject } from "../utils"; +import { deepMerge, isFunction, isObject, isEmpty } from "../utils"; import { deepFiles } from "../service"; // 模块列表 -const modules: any[] = []; +const modules: any[] = [...cool.modules]; function useModule(app: any) { // 安装模块 @@ -28,13 +28,13 @@ function useModule(app: any) { // 注册组件 if (components) { - components.forEach((e: any) => { - if (e.name) { - if (e.cool?.global || e.name.indexOf("cl-") === 0) { - app.component(e.name, e); + for (const i in components) { + if (components[i]) { + if (components[i].cool?.global || i.indexOf("cl-") === 0) { + app.component(components[i].name, components[i]); } } - }); + } } // 注册指令 @@ -70,6 +70,7 @@ function useModule(app: any) { } } + // 扫描文件 const files = import.meta.globEager("/src/cool/modules/**/*"); for (const i in files) { @@ -78,6 +79,36 @@ function useModule(app: any) { const fname: string = (cname || "").split(".")[0]; function next(d: any) { + // 配置参数入口 + if (fn == "config.ts") { + d.options = value || {}; + } + + // 模块入口 + if (fn == "index.ts") { + if (value) { + // 阻止往下加载 + d.isLoaded = true; + + // 之前 + d._beforeFn = (e: any) => { + if (e.components) { + for (const i in e.components) { + // 全局注册 + e.components[i].cool = { + global: true + }; + } + } + }; + + d.value = value; + + return d; + } + } + + // 其他功能 switch (fn) { case "service": d._services.push({ @@ -97,7 +128,7 @@ function useModule(app: any) { break; case "components": - d.components.push(value); + d.components[value.name] = value; break; case "store": @@ -107,12 +138,6 @@ function useModule(app: any) { case "directives": d.directives[fname] = value; break; - - case "config.ts": - if (value) { - d.options = value; - } - break; } return d; @@ -121,14 +146,16 @@ function useModule(app: any) { const item: any = modules.find((e) => e.name === name); if (item) { - next(item); + if (!item.isLoaded) { + next(item); + } } else { modules.push( next({ name, options: {}, directives: {}, - components: [], + components: {}, pages: [], views: [], store: {}, @@ -138,25 +165,25 @@ function useModule(app: any) { } } - // 本地模块 - modules.forEach((e) => { - e.service = deepFiles(e._services); - install(e); - }); - - // npm模块 - cool.modules.forEach((e: any) => { - const d: any = e; + // 模块安装 + modules.forEach((e: any) => { + if (!isEmpty(e._services)) { + e.service = deepFiles(e._services); + } if (isObject(e.value)) { if (isFunction(e.value.install)) { - Object.assign(d, e.value.install(app, e.options)); + Object.assign(e, e.value.install(app, e.options)); } else { - Object.assign(d, e.value); + Object.assign(e, e.value); } } - install(d); + if (e._beforeFn) { + e._beforeFn(e); + } + + install(e); }); // 缓存模块