From a4cee12f1607dbee81dae5f0cf55efdbcae29be1 Mon Sep 17 00:00:00 2001 From: kaokei Date: Fri, 6 Aug 2021 21:38:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(plugin):=20=E6=94=AF=E6=8C=81vue=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持vue plugin,支持postHook和mergeHook,支持unmount生命周期 --- ISSUES.md | 12 ++++++++++++ package-lock.json | 14 +++++++------- package.json | 2 +- src/createVuePlugin.ts | 8 ++++++++ src/index.ts | 12 +++++++++++- src/utils.ts | 19 +++++++++++++++---- 6 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 src/createVuePlugin.ts diff --git a/ISSUES.md b/ISSUES.md index cb8c4a4..74a21ef 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -21,3 +21,15 @@ watch 功能其实和 useEffect 已经非常相似了。 ## 生命周期 主要是 destroy,卸载资源 + +## hooks + +post hook + +merge hook + +需要这两个 hook 才能配置响应式能力 + +## 支持 vue 插件 + +在 app 实例上声明 providers diff --git a/package-lock.json b/package-lock.json index a897f4f..e4d6645 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.13", "license": "MIT", "dependencies": { - "@kaokei/di": "^1.0.12" + "@kaokei/di": "^1.0.14" }, "devDependencies": { "@babel/core": "^7.12.3", @@ -2902,9 +2902,9 @@ } }, "node_modules/@kaokei/di": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@kaokei/di/-/di-1.0.12.tgz", - "integrity": "sha512-/ff1/+7WlZWXAZvvuoNGWNjMnM9h9qRU8tIJiP9kWgEkuWEAOnccuW18iVxdIiN1HWIe4ph782o9Vksj/TcFrw==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@kaokei/di/-/di-1.0.14.tgz", + "integrity": "sha512-5/d8fPfJrF0FyagczS1ISG9U/A+Nb51qP04Pq6kTgFcP15HQgskNgrkg+sMENNunC31YRtAa3OPV/vb5YEnQrg==", "peerDependencies": { "reflect-metadata": "^0.1.13" } @@ -23075,9 +23075,9 @@ } }, "@kaokei/di": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@kaokei/di/-/di-1.0.12.tgz", - "integrity": "sha512-/ff1/+7WlZWXAZvvuoNGWNjMnM9h9qRU8tIJiP9kWgEkuWEAOnccuW18iVxdIiN1HWIe4ph782o9Vksj/TcFrw==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@kaokei/di/-/di-1.0.14.tgz", + "integrity": "sha512-5/d8fPfJrF0FyagczS1ISG9U/A+Nb51qP04Pq6kTgFcP15HQgskNgrkg+sMENNunC31YRtAa3OPV/vb5YEnQrg==", "requires": {} }, "@nodelib/fs.scandir": { diff --git a/package.json b/package.json index 85fb35c..5270509 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "commit": "git-cz" }, "dependencies": { - "@kaokei/di": "^1.0.12" + "@kaokei/di": "^1.0.14" }, "peerDependencies": { "reflect-metadata": "^0.1.13", diff --git a/src/createVuePlugin.ts b/src/createVuePlugin.ts new file mode 100644 index 0000000..3bbf6cc --- /dev/null +++ b/src/createVuePlugin.ts @@ -0,0 +1,8 @@ +import { INJECTOR_KEY } from './constants'; +import { getInjector } from './utils'; + +export const createVuePlugin = (providers: any = []) => ({ + install: (app: any) => { + app.provide(INJECTOR_KEY, getInjector(providers)); + }, +}); diff --git a/src/index.ts b/src/index.ts index 9f55137..9389fc7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,12 @@ // 导出依赖注入需要的装饰器 -export { Inject, Self, Skip, Optional, Injectable } from '@kaokei/di'; +export { + Inject, + Self, + Skip, + Optional, + Injectable, + forwardRef, +} from '@kaokei/di'; // setup中声明服务提供者 export { declareProviders } from './declareProviders'; @@ -7,6 +14,9 @@ export { declareProviders } from './declareProviders'; // setup中获取服务实例 export { useService } from './useService'; +// 在createApp返回的app实例上挂载Injector +export { createVuePlugin } from './createVuePlugin'; + // 以下到处不是面向普通用户使用的 // 而是面向第三方库的开发者,比如我开发的支持类组件的库 export { INJECTOR_KEY, DEFAULT_INJECTOR } from './constants'; diff --git a/src/utils.ts b/src/utils.ts index 61328f9..143db59 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ -import { reactive, ref } from 'vue'; -import { Injector } from '@kaokei/di'; +import { reactive, ref, proxyRefs } from 'vue'; +import { Injector, has } from '@kaokei/di'; function DEFAULT_POST_HOOK(service: any) { if (service && typeof service === 'object') { @@ -9,10 +9,21 @@ function DEFAULT_POST_HOOK(service: any) { } } +function DEFAULT_MERGE_HOOK(target: any, source: any) { + for (const key in source) { + if (has(source, key)) { + target[key] = proxyRefs(source[key]); + } + } + return target; +} + export function getInjector( provides?: any[], parentInjector?: Injector, - postHook?: any + options: any = {} ) { - return new Injector(provides, parentInjector, postHook || DEFAULT_POST_HOOK); + options.postHook = options.postHook || DEFAULT_POST_HOOK; + options.mergeHook = options.mergeHook || DEFAULT_MERGE_HOOK; + return new Injector(provides, parentInjector, options); }