From 6c0a4c600d4226961d42b8dd51aefb38fb5e1d7d Mon Sep 17 00:00:00 2001 From: leihaohao <2468048176@qq.com> Date: Sun, 6 Jul 2025 22:15:30 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20`asVuePlugin`?= =?UTF-8?q?=20=E5=87=BD=E6=95=B0=E7=94=A8=E4=BA=8E=E4=BB=A3=E6=9B=BF=20`cr?= =?UTF-8?q?eateVueRouterPlugin`=20=E7=9A=84=E4=BD=9C=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 `asVuePlugin` 函数,用于将 RouterPlugin 转换为 Vue 插件 - 标记 `createVueRouterPlugin` 为弃用 API,并推荐使用 `asVuePlugin` 代替 - 更新了 README 和相关文档,明确了两种插件模式的使用方法 --- README.md | 61 +++++++++++++++------------------ README.zh_CN.md | 31 +++++++---------- src/as-vue-plugin.ts | 39 +++++++++++++++++++++ src/create-vue-router-plugin.ts | 26 +++++--------- src/index.ts | 1 + tests/index.test.ts | 12 +++---- 6 files changed, 96 insertions(+), 74 deletions(-) create mode 100644 src/as-vue-plugin.ts diff --git a/README.md b/README.md index 65c4325..70bcffd 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ A lightweight solution providing standardized plugin system for Vue Router. ## 🌟 Core Features -| Feature | Description | -| -------------------------------------- | ------------------------------------------------------------------------------ | -| 🧱 **Standardized Plugin Interface** | Unified plugin development specification with auto-registration/uninstallation | -| 🔁 **Reactive Side-effect Management** | Automatic tracking/cleanup of plugin's reactive side-effects | -| ⚖️ **Dual-mode Compatibility** | Support both Vue Router plugin system and Vue plugin system | +| Feature | Description | +| -------------------------------------- | -------------------------------------------------------------------------------- | +| 🧱 **Standardized Plugin Interface** | Unified plugin development specification with auto-registration/uninstallation | +| 🔁 **Reactive Side-effect Management** | Automatic tracking/cleanup of plugin's reactive side-effects | +| ⚖️ **Dual-mode Compatibility** | Supports both Vue Router plugin system and Vue plugin system compatibility modes | --- @@ -26,7 +26,7 @@ npm install vue-router-plugin-system ## 🚀 Getting Started -### Mode 1: Vue Router Plugin (Recommended) +### Mode 1: Vue Router Plugin Mode (Recommended) **1. Plugin Development** @@ -70,37 +70,39 @@ const router = createRouter({ router.isNavigating.value ``` -### Mode 2: Vue Plugin (Compatibility) +### Mode 2: Vue Plugin Mode (Compatibility) -**1. Create Vue Plugin** +**1. Plugin Development** ```ts -import { createVueRouterPlugin } from 'vue-router-plugin-system' +import type { RouterPlugin } from 'vue-router-plugin-system' +import { ref } from 'vue' -export const NavigationStatePlugin = createVueRouterPlugin((ctx) => { - // Same implementation logic as above -}) +export const NavigationStatePlugin: RouterPlugin = (ctx) => { + // Implementation logic remains the same +} ``` **2. Application Integration** ```ts // main.ts +import { asVuePlugin } from 'vue-router-plugin-system' + const app = createApp(App) app.use(router) // Mount router first -app.use(NavigationStatePlugin) // Register plugin later +app.use(asVuePlugin(NavigationStatePlugin)) // Register plugin later ``` --- ## ⚠️ Mode Comparison -| Feature | Vue Router Plugin | Vue Plugin | -| ------------------------- | -------------------------------- | ------------------------------- | -| Initialization Order | Prior to app logic | Dependent on client usage order | -| Navigation Guard Priority | Higher | Dependent on registration order | -| Reactive Management | Automatic cleanup | Automatic cleanup | -| Dependency Requirement | Requires this lib's createRouter | No dependency required | +| Feature | Vue Router Plugin Mode | Vue Plugin Mode | +| -------------------- | -------------------------- | ----------------------------- | +| Initialization Order | Prioritized over app logic | Depends on client usage order | +| Guard Priority | Higher priority | Depends on registration order | +| Reactive Management | Auto-cleanup | Auto-cleanup | --- @@ -113,11 +115,11 @@ interface RouterPluginContext { */ router: Router /** - * Execute callback with vue app instance + * Execute callback with Vue app instance */ runWithApp: (handler: RouterPluginRunWithAppHandler) => void /** - * Register uninstall callback (can be called multiple times) + * Register uninstallation callback (supports multiple calls) */ onUninstall: (handler: RouterPluginUninstallHandler) => void } @@ -128,24 +130,17 @@ interface RouterPlugin { */ (ctx: RouterPluginContext): void } - -interface VueRouterPlugin extends RouterPlugin { - /** - * Vue plugin installation function - */ - install: (app: App) => void -} ``` --- -## 🤝 Contribution Guidelines +## 🤝 Contribution Guide -Contributions welcome! Please ensure: +Contributions are welcome! Please ensure: -1. Pass all unit tests -2. Maintain TypeScript type integrity -3. Add necessary documentation +1. All unit tests pass +2. TypeScript type integrity maintained +3. Necessary documentation added ## License diff --git a/README.zh_CN.md b/README.zh_CN.md index 1a9e322..8da128f 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -72,35 +72,37 @@ router.isNavigating.value ### 模式二:Vue 插件模式(兼容方案) -**1. 创建 Vue 插件** +**1. 开发插件** ```ts -import { createVueRouterPlugin } from 'vue-router-plugin-system' +import type { RouterPlugin } from 'vue-router-plugin-system' +import { ref } from 'vue' -export const NavigationStatePlugin = createVueRouterPlugin((ctx) => { +export const NavigationStatePlugin: RouterPlugin = (ctx) => { // 插件实现逻辑同上 -}) +} ``` **2. 应用集成** ```ts // main.ts +import { asVuePlugin } from 'vue-router-plugin-system' + const app = createApp(App) app.use(router) // 先挂载路由 -app.use(NavigationStatePlugin) // 后注册插件 +app.use(asVuePlugin(NavigationStatePlugin)) // 后注册插件 ``` --- ## ⚠️ 模式对比 -| 特性 | Vue Router 插件模式 | Vue 插件模式 | -| -------------- | --------------------- | ------------------ | -| 初始化顺序 | 优先于应用逻辑 | 依赖客户端使用顺序 | -| 导航守卫优先级 | 更高 | 依赖注册顺序 | -| 响应式管理 | 自动清理 | 自动清理 | -| 依赖要求 | 需要本库 createRouter | 无需本库 | +| 特性 | Vue Router 插件模式 | Vue 插件模式 | +| -------------- | ------------------- | ------------------ | +| 初始化顺序 | 优先于应用逻辑 | 依赖客户端使用顺序 | +| 导航守卫优先级 | 更高 | 依赖注册顺序 | +| 响应式管理 | 自动清理 | 自动清理 | --- @@ -128,13 +130,6 @@ interface RouterPlugin { */ (ctx: RouterPluginContext): void } - -interface VueRouterPlugin extends RouterPlugin { - /** - * Vue 插件安装函数 - */ - install: (app: App) => void -} ``` --- diff --git a/src/as-vue-plugin.ts b/src/as-vue-plugin.ts new file mode 100644 index 0000000..189ac76 --- /dev/null +++ b/src/as-vue-plugin.ts @@ -0,0 +1,39 @@ +import type { App, ObjectPlugin } from 'vue' +import type { RouterPlugin } from './plugin' +import { prepareInstall } from './prepare-install' +import { setupPlugin } from './setup-plugin' + +/** + * Convert a {@link RouterPlugin} to a {@link ObjectPlugin VuePlugin}. + * + * @description Wraps the plugin with an `install` method to adapt it to Vue's plugin registration mechanism. + * + * @param plugin {@link RouterPlugin} + * + * @returns Returns a {@link ObjectPlugin VuePlugin}. + * + * @example + * ```ts + * const SomePlugin: RouterPlugin = (ctx) => { + * // plugin implementation + * } + * + * // must be installed after the router + * app.use(router).use(asVuePlugin(SomePlugin)) + * ``` + */ +export function asVuePlugin(plugin: RouterPlugin): RouterPlugin & ObjectPlugin { + return Object.assign(plugin, { + install(app: App) { + const router = app.config.globalProperties.$router + if (!router) { + throw new Error( + '[vue-router-plugin-system] Please install vue-router first.', + ) + } + + prepareInstall({ app, router }) + setupPlugin({ router, plugin }) + }, + }) +} diff --git a/src/create-vue-router-plugin.ts b/src/create-vue-router-plugin.ts index 0b054dc..4961780 100644 --- a/src/create-vue-router-plugin.ts +++ b/src/create-vue-router-plugin.ts @@ -1,8 +1,10 @@ import type { App } from 'vue' import type { RouterPlugin } from './plugin' -import { prepareInstall } from './prepare-install' -import { setupPlugin } from './setup-plugin' +import { asVuePlugin } from './as-vue-plugin' +/** + * @deprecated + */ export interface VueRouterPlugin extends RouterPlugin { /** * Install the plugin. @@ -13,6 +15,9 @@ export interface VueRouterPlugin extends RouterPlugin { /** * Create a {@link VueRouterPlugin} from a {@link RouterPlugin}. + * + * @deprecated Please use {@link asVuePlugin} instead. + * * @param plugin {@link RouterPlugin} * @returns Returns a {@link VueRouterPlugin} * @example @@ -25,18 +30,5 @@ export interface VueRouterPlugin extends RouterPlugin { * app.use(router).use(SomePlugin) * ``` */ -export function createVueRouterPlugin(plugin: RouterPlugin): VueRouterPlugin { - return Object.assign(plugin, { - install(app: App) { - const router = app.config.globalProperties.$router - if (!router) { - throw new Error( - '[vue-router-plugin-system] Please install vue-router first.', - ) - } - - prepareInstall({ app, router }) - setupPlugin({ router, plugin }) - }, - }) -} +export const createVueRouterPlugin: (plugin: RouterPlugin) => VueRouterPlugin = + asVuePlugin diff --git a/src/index.ts b/src/index.ts index 20594df..5475d7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +export * from './as-vue-plugin' export * from './create-router' export * from './create-vue-router-plugin' export * from './plugin' diff --git a/tests/index.test.ts b/tests/index.test.ts index bd72554..06a7635 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -2,7 +2,7 @@ import type { RouterPlugin } from '../src/plugin' import { describe, expect, it, vi } from 'vitest' import { computed, createApp, ref, watch } from 'vue' import { createMemoryHistory } from 'vue-router' -import { createRouter, createVueRouterPlugin } from '../src/index' +import { asVuePlugin, createRouter } from '../src/index' describe.concurrent('vue Router Plugin System', () => { // 测试插件基础功能 @@ -107,15 +107,15 @@ describe.concurrent('vue Router Plugin System', () => { expect(logSpy).toHaveBeenCalledTimes(2) }) - // 测试从 vue app 进行安装并且功能正常 - it('should install from vue app', () => { + // 测试 asVuePlugin + it('test asVuePlugin', () => { const counter = ref(0) const logSpy = vi.fn() - const mockPlugin = createVueRouterPlugin(() => { + const mockPlugin: RouterPlugin = () => { const doubled = computed(() => counter.value * 2) watch(doubled, logSpy, { immediate: true, flush: 'sync' }) counter.value = 1 - }) + } const router = createRouter({ history: createMemoryHistory(), @@ -123,7 +123,7 @@ describe.concurrent('vue Router Plugin System', () => { }) const app = createApp(() => null) - app.use(router).use(mockPlugin) + app.use(router).use(asVuePlugin(mockPlugin)) app.unmount() expect(logSpy).toHaveBeenCalledTimes(2) From 4959a3f827a7a1a9e150d4e9728d0619599d1a21 Mon Sep 17 00:00:00 2001 From: leihaohao <2468048176@qq.com> Date: Sun, 6 Jul 2025 22:15:55 +0800 Subject: [PATCH 2/4] chore: release v1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6cef4fa..718e11f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vue-router-plugin-system", "type": "module", - "version": "1.0.0", + "version": "1.1.0", "packageManager": "pnpm@10.11.0", "description": "A lightweight solution providing standardized plugin system for Vue Router.", "author": "leihaohao ", From b458458c3682d6448487fb05fa979d1e74ab5f55 Mon Sep 17 00:00:00 2001 From: leihaohao <53589602+l246804@users.noreply.github.com> Date: Sun, 6 Jul 2025 22:19:53 +0800 Subject: [PATCH 3/4] =?UTF-8?q?chore(README.zh=5FCN):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.zh_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.zh_CN.md b/README.zh_CN.md index 8da128f..997f6bc 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -115,7 +115,7 @@ interface RouterPluginContext { */ router: Router /** - * 使用 vue app 实例执行回调函数 + * 使用 Vue app 实例执行回调函数 */ runWithApp: (handler: RouterPluginRunWithAppHandler) => void /** From 5b5993ef7470572ab87e08f8bc8a98568f1e10fe Mon Sep 17 00:00:00 2001 From: leihaohao <2468048176@qq.com> Date: Fri, 18 Jul 2025 10:36:07 +0800 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=E8=B0=83=E6=95=B4=20README=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 中英文版本的 Vue Router 插件系统 README 文件中,语言切换链接位置进行了调整 - 将语言切换链接从文档标题下方移动到核心功能展示区上方,以优化阅读体验 --- README.md | 4 ++-- README.zh_CN.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 70bcffd..f577f21 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # vue-router-plugin-system -[中文文档](./README.zh_CN.md) - A lightweight solution providing standardized plugin system for Vue Router. +[中文文档](./README.zh_CN.md) + --- ## 🌟 Core Features diff --git a/README.zh_CN.md b/README.zh_CN.md index 997f6bc..670c8ba 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -1,9 +1,9 @@ # vue-router-plugin-system -[English Document](./README.md) - 为 Vue Router 提供标准化插件系统的轻量级解决方案。 +[English Document](./README.md) + --- ## 🌟 核心优势