From 508b1c096315cc66ab9f935a9030d346e0e14257 Mon Sep 17 00:00:00 2001 From: agileago Date: Fri, 25 Feb 2022 22:14:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20computed=E5=A2=9E=E5=8A=A0eager?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E7=AB=8B=E5=8D=B3=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E5=87=BA=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 1 + example/main.tsx | 18 ++++++++-------- src/decorators/computed.ts | 42 +++++++++++++++++++++++++++++++------- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ae7323a..3935e16 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,5 +35,6 @@ module.exports = { ], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-floating-promises': 'off', + 'no-empty': 'warn', }, } diff --git a/example/main.tsx b/example/main.tsx index 7a7405d..6e4807f 100644 --- a/example/main.tsx +++ b/example/main.tsx @@ -1,8 +1,9 @@ import '@abraham/reflection' import { Component, + Computed, getCurrentInjector, - Hook, + Mut, VueComponent, VueService, } from 'vue3-oop' @@ -26,20 +27,17 @@ class App extends VueComponent { outService = new OutService() - @Hook('Mounted') - mount() { - console.log( - this.injector, - this.outService.injector, - this.injector === this.outService.injector - ) - } + @Mut() count = 1 + @Computed('pre') + get abc() { + return this.count > 10 + } render() { return (
- 指令: + 指令:abc大于20:{String(this.abc)}
diff --git a/src/decorators/computed.ts b/src/decorators/computed.ts index 6d6338c..64586c2 100644 --- a/src/decorators/computed.ts +++ b/src/decorators/computed.ts @@ -1,11 +1,17 @@ -import { computed } from 'vue' +import type { WatchOptionsBase } from 'vue' +import { computed, shallowRef, watchEffect } from 'vue' import type { Hanlder } from '../type' import { createDecorator, getProtoMetadata } from './util' export const Computed: ComputedDecorator = createDecorator('Computed') +type EagerType = true | WatchOptionsBase['flush'] + export interface ComputedDecorator { - (): MethodDecorator + /** + * @param eager 是否是急切的获取值 + */ + (eager?: EagerType): MethodDecorator /** * @param shallow 是否是浅层响应式 */ @@ -13,15 +19,37 @@ export interface ComputedDecorator { } function handler(targetThis: Record) { - const list = getProtoMetadata(targetThis, Computed.MetadataKey, true) + const list = getProtoMetadata( + targetThis, + Computed.MetadataKey, + true + ) if (!list || !list.length) return for (const item of list) { const desc = item.desc + const option = item.options if (!desc) continue - const keyVal = computed({ - get: () => desc.get?.call(targetThis), - set: (v: any) => desc.set?.call(targetThis, v), - }) + let keyVal: any + if (option) { + // eager computed + keyVal = shallowRef() + watchEffect( + () => { + try { + keyVal.value = desc.get?.call(targetThis) + } finally { + } + }, + { + flush: option === true ? 'sync' : option, + } + ) + } else { + keyVal = computed({ + get: () => desc.get?.call(targetThis), + set: (v: any) => desc.set?.call(targetThis, v), + }) + } Object.defineProperty(targetThis, item.key, { enumerable: desc?.enumerable, configurable: true,