Skip to content

Commit

Permalink
feat: 依赖进行缓存,提高性能
Browse files Browse the repository at this point in the history
  • Loading branch information
agileago committed Jan 20, 2022
1 parent 06560b5 commit fcf9969
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 18 deletions.
14 changes: 13 additions & 1 deletion example/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,17 @@ class Home1 extends Home {
}
}

const app = createApp(Home1)
class App extends VueComponent {
render() {
return (
<>
<Home1></Home1>
<Home1></Home1>
<Home1></Home1>
</>
)
}
}

const app = createApp(App)
app.mount('#app')
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:serve": "vitepress serve docs",
"test": "vitest",
"test": "vitest --ui",
"coverage": "vitest --coverage"
},
"files": [
Expand Down Expand Up @@ -64,6 +64,7 @@
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
"@vitejs/plugin-vue": "^2.0.1",
"@vitest/ui": "^0.1.19",
"@vue/test-utils": "^2.0.0-rc.18",
"@vue3-oop/plugin-vue-jsx": "^1.4.0",
"ant-design-vue": "^3.0.0-alpha.11",
Expand Down
38 changes: 35 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 25 additions & 13 deletions src/di/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
InjectionToken,
Provider,
ReflectiveInjector,
ResolvedReflectiveProvider,
SkipSelf,
TypeProvider,
} from 'injection-js'
Expand All @@ -13,6 +14,7 @@ import { createSymbol } from '../helper'
export const InjectorKey: InjectionKey<ReflectiveInjector> = createSymbol('VUE3-OOP_ReflectiveInjector') as symbol

const MetadataKey = createSymbol('VUE3-OOP_Component')
const MetadataProviderKey = createSymbol('VUE3-OOP_ResolveProviders')

declare module 'vue' {
interface App {
Expand All @@ -38,6 +40,11 @@ export interface ComponentOptions {
* 此注入器是否作为全局的store
*/
globalStore?: boolean
/**
* option是否是稳定的,
* 依赖解析只会在第一次的时候解析并且缓存下来,所以options如果是动态变化的,请标记
*/
stable?: boolean
}

export function Component(options?: ComponentOptions): ClassDecorator {
Expand All @@ -51,21 +58,26 @@ export function resolveComponent(target: { new (...args: []): any }) {
// 如果没有使用 injection-js 则不创建注入器
if (!Reflect.getMetadata('annotations', target)) return new target()
const parent = inject(InjectorKey, undefined)
let resolveProviders = Reflect.getOwnMetadata<ResolvedReflectiveProvider[]>(MetadataProviderKey, target)
const options: ComponentOptions | undefined = Reflect.getOwnMetadata(MetadataKey, target)
// 依赖
let deps: Provider[] = [target]
if (options?.providers?.length) {
deps = deps.concat(options.providers)
}
// 自动解析依赖的依赖
if (options?.autoResolveDeps !== false) {
deps = resolveDependencies(deps)
}
// 排除掉某些依赖
if (options?.exclude?.length) {
deps = deps.filter((k) => !options.exclude?.includes(k))
if (!resolveProviders || options?.stable === false) {
// 依赖
let deps: Provider[] = [target]
if (options?.providers?.length) {
deps = deps.concat(options.providers)
}
// 自动解析依赖的依赖
if (options?.autoResolveDeps !== false) {
deps = resolveDependencies(deps)
}
// 排除掉某些依赖
if (options?.exclude?.length) {
deps = deps.filter((k) => !options.exclude?.includes(k))
}
resolveProviders = ReflectiveInjector.resolve(deps)
// 缓存解析过的依赖, 提高性能
Reflect.defineMetadata(MetadataProviderKey, resolveProviders, target)
}
const resolveProviders = ReflectiveInjector.resolve(deps)
const injector = ReflectiveInjector.fromResolvedProviders(resolveProviders, parent)
if (options?.globalStore) {
// 如果作为全局的服务,则注入到根上面
Expand Down

0 comments on commit fcf9969

Please sign in to comment.