@viewfly/core 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/foundation/_api.d.ts +1 -0
- package/bundles/foundation/_utils.d.ts +1 -0
- package/bundles/foundation/component.d.ts +25 -20
- package/bundles/foundation/injection-tokens.d.ts +1 -0
- package/bundles/foundation/types.d.ts +3 -3
- package/bundles/index.esm.js +71 -25
- package/bundles/index.js +77 -29
- package/package.json +2 -2
|
@@ -107,7 +107,7 @@ export type ExtractInstanceType<T, U = T extends (...args: any) => any ? ReturnT
|
|
|
107
107
|
export interface AbstractInstanceType<T extends Record<string, any>> {
|
|
108
108
|
(): T & JSXInternal.ComponentInstance<any>;
|
|
109
109
|
}
|
|
110
|
-
export declare class
|
|
110
|
+
export declare class DynamicRef<T> {
|
|
111
111
|
private callback;
|
|
112
112
|
private unBindMap;
|
|
113
113
|
private targetCaches;
|
|
@@ -121,7 +121,7 @@ export declare class Ref<T> {
|
|
|
121
121
|
* @example
|
|
122
122
|
* ```tsx
|
|
123
123
|
* function App() {
|
|
124
|
-
* const ref =
|
|
124
|
+
* const ref = createDynamicRef(node => {
|
|
125
125
|
* function fn() {
|
|
126
126
|
* // do something...
|
|
127
127
|
* }
|
|
@@ -136,7 +136,12 @@ export declare class Ref<T> {
|
|
|
136
136
|
* }
|
|
137
137
|
* ```
|
|
138
138
|
*/
|
|
139
|
-
export declare function
|
|
139
|
+
export declare function createDynamicRef<T, U = ExtractInstanceType<T>>(callback: RefListener<U>): DynamicRef<U>;
|
|
140
|
+
export declare class StaticRef<T> extends DynamicRef<T> {
|
|
141
|
+
readonly current: T | null;
|
|
142
|
+
constructor();
|
|
143
|
+
}
|
|
144
|
+
export declare function createRef<T, U = ExtractInstanceType<T>>(): StaticRef<U>;
|
|
140
145
|
declare const depsKey: unique symbol;
|
|
141
146
|
/**
|
|
142
147
|
* 组件状态实例,直接调用可以获取最新的状态,通过 set 方法可以更新状态
|
|
@@ -162,7 +167,7 @@ export interface Signal<T> {
|
|
|
162
167
|
* ```tsx
|
|
163
168
|
* function App() {
|
|
164
169
|
* // 初始化状态
|
|
165
|
-
* const state =
|
|
170
|
+
* const state = createSignal(1)
|
|
166
171
|
*
|
|
167
172
|
* return () => {
|
|
168
173
|
* <div>
|
|
@@ -178,7 +183,7 @@ export interface Signal<T> {
|
|
|
178
183
|
* }
|
|
179
184
|
* }
|
|
180
185
|
*/
|
|
181
|
-
export declare function
|
|
186
|
+
export declare function createSignal<T>(state: T): Signal<T>;
|
|
182
187
|
/**
|
|
183
188
|
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
184
189
|
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
@@ -186,28 +191,28 @@ export declare function useSignal<T>(state: T): Signal<T>;
|
|
|
186
191
|
* @param callback
|
|
187
192
|
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
188
193
|
*/
|
|
189
|
-
export declare function
|
|
190
|
-
export interface
|
|
194
|
+
export declare function createDerived<T>(callback: () => T, isContinue?: (data: T) => unknown): Signal<T>;
|
|
195
|
+
export interface WatchCallback<T, U> {
|
|
191
196
|
(newValue: T, oldValue: U): void | (() => void);
|
|
192
197
|
}
|
|
193
198
|
/**
|
|
194
199
|
* 监听状态变化,当任意一个状态发生变更时,触发回调。
|
|
195
|
-
*
|
|
200
|
+
* watch 会返回一个取消监听的函数,调用此函数,可以取消监听。
|
|
196
201
|
* 当在组件中调用时,组件销毁时会自动取消监听。
|
|
197
202
|
* @param deps 依赖的状态 Signal,可以是一个 Signal,只可以一个数包含 Signal 的数组,或者是一个求值函数
|
|
198
|
-
* @param
|
|
203
|
+
* @param callback 状态变更后的回调函数
|
|
199
204
|
*/
|
|
200
|
-
export declare function
|
|
201
|
-
export declare function
|
|
202
|
-
export declare function
|
|
203
|
-
export declare function
|
|
204
|
-
export declare function
|
|
205
|
-
export declare function
|
|
206
|
-
export declare function
|
|
207
|
-
export declare function
|
|
208
|
-
export declare function
|
|
209
|
-
export declare function
|
|
210
|
-
export declare function
|
|
205
|
+
export declare function watch<T>(deps: Signal<T>, callback: WatchCallback<T, T>): () => void;
|
|
206
|
+
export declare function watch<T>(deps: [Signal<T>], callback: WatchCallback<[T], [T]>): () => void;
|
|
207
|
+
export declare function watch<T, T1>(deps: [Signal<T>, Signal<T1>], callback: WatchCallback<[T, T1], [T, T1]>): () => void;
|
|
208
|
+
export declare function watch<T, T1, T2>(deps: [Signal<T>, Signal<T1>, Signal<T2>], callback: WatchCallback<[T, T1, T2], [T, T1, T2]>): () => void;
|
|
209
|
+
export declare function watch<T, T1, T2, T3>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>], callback: WatchCallback<[T, T1, T2, T3], [T, T1, T2, T3]>): () => void;
|
|
210
|
+
export declare function watch<T, T1, T2, T3, T4>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>], callback: WatchCallback<[T, T1, T2, T3, T4], [T, T1, T2, T3, T4]>): () => void;
|
|
211
|
+
export declare function watch<T, T1, T2, T3, T4, T5>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>], callback: WatchCallback<[T, T1, T2, T3, T4, T5], [T, T1, T2, T3, T4, T5]>): () => void;
|
|
212
|
+
export declare function watch<T, T1, T2, T3, T4, T5, T6>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>, Signal<T6>], callback: WatchCallback<[T, T1, T2, T3, T4, T5, T6], [T, T1, T2, T3, T4, T5, T6]>): () => void;
|
|
213
|
+
export declare function watch<T, T1, T2, T3, T4, T5, T6, T7>(deps: [Signal<T>, Signal<T1>, Signal<T2>, Signal<T3>, Signal<T4>, Signal<T5>, Signal<T6>, Signal<T7>], callback: WatchCallback<[T, T1, T2, T3, T4, T5, T6, T7], [T, T1, T2, T3, T4, T5, T6, T7]>): () => void;
|
|
214
|
+
export declare function watch<T>(deps: () => T, callback: WatchCallback<T, T>): () => void;
|
|
215
|
+
export declare function watch<T = any>(deps: Signal<any>[], callback: WatchCallback<T[], T[]>): () => void;
|
|
211
216
|
/**
|
|
212
217
|
* 通过 IoC 容器当前组件提供上下文共享数据的方法
|
|
213
218
|
* @param provider
|
|
@@ -3,6 +3,7 @@ export declare abstract class NativeRenderer<ElementNode = NativeNode, TextNode
|
|
|
3
3
|
abstract createElement(name: string, isSvg: boolean): ElementNode;
|
|
4
4
|
abstract createTextNode(textContent: string, isSvg: boolean): TextNode;
|
|
5
5
|
abstract setProperty(node: ElementNode, key: string, value: any, isSvg: boolean): void;
|
|
6
|
+
abstract appendChild(parent: ElementNode, newChild: ElementNode | TextNode, isSvg: boolean): void;
|
|
6
7
|
abstract prependChild(parent: ElementNode, newChild: ElementNode | TextNode, isSvg: boolean): void;
|
|
7
8
|
abstract removeProperty(node: ElementNode, key: string, isSvg: boolean): void;
|
|
8
9
|
abstract setStyle(target: ElementNode, key: string, value: any, isSvg: boolean): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Key } from './jsx-element';
|
|
2
|
-
import { ExtractInstanceType,
|
|
2
|
+
import { ExtractInstanceType, DynamicRef } from './component';
|
|
3
3
|
import { Scope } from '../di/injectable';
|
|
4
4
|
export type JSXNode = JSXInternal.JSXNode;
|
|
5
5
|
export declare namespace JSXInternal {
|
|
@@ -19,7 +19,7 @@ export declare namespace JSXInternal {
|
|
|
19
19
|
ref?: any;
|
|
20
20
|
}
|
|
21
21
|
interface RefAttributes<T> extends IntrinsicAttributes {
|
|
22
|
-
ref?:
|
|
22
|
+
ref?: DynamicRef<ExtractInstanceType<T>> | DynamicRef<ExtractInstanceType<T>>[];
|
|
23
23
|
}
|
|
24
24
|
interface ElementClass<P = any> extends ComponentInstance<P> {
|
|
25
25
|
}
|
|
@@ -29,6 +29,6 @@ export declare namespace JSXInternal {
|
|
|
29
29
|
[name: string]: any;
|
|
30
30
|
}
|
|
31
31
|
interface IntrinsicClassAttributes<T> {
|
|
32
|
-
ref?:
|
|
32
|
+
ref?: DynamicRef<T>;
|
|
33
33
|
}
|
|
34
34
|
}
|
package/bundles/index.esm.js
CHANGED
|
@@ -728,7 +728,7 @@ class Component extends ReflectiveInjector {
|
|
|
728
728
|
signalDepsStack.push([]);
|
|
729
729
|
const template = this.instance.$render();
|
|
730
730
|
const deps = signalDepsStack.pop();
|
|
731
|
-
this.unWatch =
|
|
731
|
+
this.unWatch = watch(Array.from(new Set(deps)), () => {
|
|
732
732
|
this.markAsDirtied();
|
|
733
733
|
});
|
|
734
734
|
this.template = template;
|
|
@@ -764,7 +764,7 @@ class Component extends ReflectiveInjector {
|
|
|
764
764
|
signalDepsStack.push([]);
|
|
765
765
|
this.template = this.instance.$render();
|
|
766
766
|
const deps = signalDepsStack.pop();
|
|
767
|
-
this.unWatch =
|
|
767
|
+
this.unWatch = watch(Array.from(new Set(deps)), () => {
|
|
768
768
|
this.markAsDirtied();
|
|
769
769
|
});
|
|
770
770
|
return this.template;
|
|
@@ -845,7 +845,7 @@ class Component extends ReflectiveInjector {
|
|
|
845
845
|
}
|
|
846
846
|
function toRefs(ref) {
|
|
847
847
|
return (Array.isArray(ref) ? ref : [ref]).filter(i => {
|
|
848
|
-
return i instanceof
|
|
848
|
+
return i instanceof DynamicRef;
|
|
849
849
|
});
|
|
850
850
|
}
|
|
851
851
|
/**
|
|
@@ -926,7 +926,7 @@ function onUnmounted(callback) {
|
|
|
926
926
|
const component = getSetupContext();
|
|
927
927
|
component.unmountedCallbacks.push(callback);
|
|
928
928
|
}
|
|
929
|
-
class
|
|
929
|
+
class DynamicRef {
|
|
930
930
|
constructor(callback) {
|
|
931
931
|
this.callback = callback;
|
|
932
932
|
this.unBindMap = new Map();
|
|
@@ -960,7 +960,7 @@ class Ref {
|
|
|
960
960
|
* @example
|
|
961
961
|
* ```tsx
|
|
962
962
|
* function App() {
|
|
963
|
-
* const ref =
|
|
963
|
+
* const ref = createDynamicRef(node => {
|
|
964
964
|
* function fn() {
|
|
965
965
|
* // do something...
|
|
966
966
|
* }
|
|
@@ -975,8 +975,32 @@ class Ref {
|
|
|
975
975
|
* }
|
|
976
976
|
* ```
|
|
977
977
|
*/
|
|
978
|
-
function
|
|
979
|
-
return new
|
|
978
|
+
function createDynamicRef(callback) {
|
|
979
|
+
return new DynamicRef(callback);
|
|
980
|
+
}
|
|
981
|
+
const initValue = {};
|
|
982
|
+
class StaticRef extends DynamicRef {
|
|
983
|
+
constructor() {
|
|
984
|
+
let value = initValue;
|
|
985
|
+
let isInit = false;
|
|
986
|
+
super(v => {
|
|
987
|
+
if (v !== initValue && !isInit) {
|
|
988
|
+
value = v;
|
|
989
|
+
isInit = true;
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
Object.defineProperty(this, 'current', {
|
|
993
|
+
get() {
|
|
994
|
+
if (value === initValue) {
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
return value;
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function createRef() {
|
|
1003
|
+
return new StaticRef();
|
|
980
1004
|
}
|
|
981
1005
|
const depsKey = Symbol('deps');
|
|
982
1006
|
/**
|
|
@@ -986,7 +1010,7 @@ const depsKey = Symbol('deps');
|
|
|
986
1010
|
* ```tsx
|
|
987
1011
|
* function App() {
|
|
988
1012
|
* // 初始化状态
|
|
989
|
-
* const state =
|
|
1013
|
+
* const state = createSignal(1)
|
|
990
1014
|
*
|
|
991
1015
|
* return () => {
|
|
992
1016
|
* <div>
|
|
@@ -1002,7 +1026,7 @@ const depsKey = Symbol('deps');
|
|
|
1002
1026
|
* }
|
|
1003
1027
|
* }
|
|
1004
1028
|
*/
|
|
1005
|
-
function
|
|
1029
|
+
function createSignal(state) {
|
|
1006
1030
|
function signal() {
|
|
1007
1031
|
const depsContext = getSignalDepsContext();
|
|
1008
1032
|
if (depsContext) {
|
|
@@ -1088,9 +1112,9 @@ function listen(model, deps, callback, isContinue) {
|
|
|
1088
1112
|
* @param callback
|
|
1089
1113
|
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
1090
1114
|
*/
|
|
1091
|
-
function
|
|
1115
|
+
function createDerived(callback, isContinue) {
|
|
1092
1116
|
const { data, deps } = invokeDepFn(callback);
|
|
1093
|
-
const signal =
|
|
1117
|
+
const signal = createSignal(data);
|
|
1094
1118
|
const component = getSetupContext(false);
|
|
1095
1119
|
const unListen = listen(signal, deps, callback, isContinue);
|
|
1096
1120
|
if (component) {
|
|
@@ -1101,9 +1125,9 @@ function useDerived(callback, isContinue) {
|
|
|
1101
1125
|
return signal;
|
|
1102
1126
|
}
|
|
1103
1127
|
/* eslint-enable max-len*/
|
|
1104
|
-
function
|
|
1128
|
+
function watch(deps, callback) {
|
|
1105
1129
|
if (typeof deps === 'function' && !deps.$isSignal) {
|
|
1106
|
-
deps =
|
|
1130
|
+
deps = createDerived(deps);
|
|
1107
1131
|
}
|
|
1108
1132
|
const signals = Array.isArray(deps) ? deps : [deps];
|
|
1109
1133
|
let oldValues = signals.map(s => s());
|
|
@@ -1113,7 +1137,7 @@ function useEffect(deps, effect) {
|
|
|
1113
1137
|
prevCleanup();
|
|
1114
1138
|
}
|
|
1115
1139
|
const newValues = signals.map(s => s());
|
|
1116
|
-
prevCleanup = Array.isArray(deps) ?
|
|
1140
|
+
prevCleanup = Array.isArray(deps) ? callback(newValues, oldValues) : callback(newValues[0], oldValues[0]);
|
|
1117
1141
|
oldValues = newValues;
|
|
1118
1142
|
}
|
|
1119
1143
|
for (const dep of signals) {
|
|
@@ -1234,7 +1258,8 @@ function createRenderer(component, nativeRenderer) {
|
|
|
1234
1258
|
};
|
|
1235
1259
|
componentRender(nativeRenderer, component, atom, {
|
|
1236
1260
|
isParent: true,
|
|
1237
|
-
host
|
|
1261
|
+
host,
|
|
1262
|
+
rootHost: host
|
|
1238
1263
|
});
|
|
1239
1264
|
}
|
|
1240
1265
|
else {
|
|
@@ -1261,7 +1286,12 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
|
1261
1286
|
}
|
|
1262
1287
|
atom.nativeNode = nativeNode;
|
|
1263
1288
|
if (context.isParent) {
|
|
1264
|
-
|
|
1289
|
+
if (context.host === context.rootHost) {
|
|
1290
|
+
nativeRenderer.appendChild(context.host, nativeNode, atom.isSvg);
|
|
1291
|
+
}
|
|
1292
|
+
else {
|
|
1293
|
+
nativeRenderer.prependChild(context.host, nativeNode, atom.isSvg);
|
|
1294
|
+
}
|
|
1265
1295
|
}
|
|
1266
1296
|
else {
|
|
1267
1297
|
nativeRenderer.insertAfter(nativeNode, context.host, atom.isSvg);
|
|
@@ -1269,7 +1299,8 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
|
1269
1299
|
if (atom.jsxNode instanceof JSXElement) {
|
|
1270
1300
|
const childContext = {
|
|
1271
1301
|
isParent: true,
|
|
1272
|
-
host: nativeNode
|
|
1302
|
+
host: nativeNode,
|
|
1303
|
+
rootHost: context.rootHost
|
|
1273
1304
|
};
|
|
1274
1305
|
let child = atom.child;
|
|
1275
1306
|
while (child) {
|
|
@@ -1297,7 +1328,7 @@ function updateView(nativeRenderer, component) {
|
|
|
1297
1328
|
}
|
|
1298
1329
|
}
|
|
1299
1330
|
function applyChanges(nativeRenderer, component) {
|
|
1300
|
-
const { atom, host, isParent } = component.$$view;
|
|
1331
|
+
const { atom, host, isParent, rootHost } = component.$$view;
|
|
1301
1332
|
const diffAtom = atom.child;
|
|
1302
1333
|
const template = component.update(component.props, true);
|
|
1303
1334
|
if (template) {
|
|
@@ -1308,7 +1339,8 @@ function applyChanges(nativeRenderer, component) {
|
|
|
1308
1339
|
}
|
|
1309
1340
|
const context = {
|
|
1310
1341
|
host,
|
|
1311
|
-
isParent
|
|
1342
|
+
isParent,
|
|
1343
|
+
rootHost
|
|
1312
1344
|
};
|
|
1313
1345
|
diff(nativeRenderer, component, atom.child, diffAtom, context, 0, 0);
|
|
1314
1346
|
const next = atom.sibling;
|
|
@@ -1440,7 +1472,12 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
|
|
|
1440
1472
|
const host = context.host;
|
|
1441
1473
|
if (expectIndex - offset !== oldIndex) {
|
|
1442
1474
|
if (context.isParent) {
|
|
1443
|
-
|
|
1475
|
+
if (host === context.rootHost) {
|
|
1476
|
+
nativeRenderer.appendChild(host, newAtom.nativeNode, newAtom.isSvg);
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
|
|
1480
|
+
}
|
|
1444
1481
|
}
|
|
1445
1482
|
else {
|
|
1446
1483
|
nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
|
|
@@ -1452,7 +1489,8 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
|
|
|
1452
1489
|
if (newAtom.child) {
|
|
1453
1490
|
diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
|
|
1454
1491
|
host: newAtom.nativeNode,
|
|
1455
|
-
isParent: true
|
|
1492
|
+
isParent: true,
|
|
1493
|
+
rootHost: context.rootHost
|
|
1456
1494
|
}, 0, 0);
|
|
1457
1495
|
}
|
|
1458
1496
|
else if (oldAtom.child) {
|
|
@@ -1514,7 +1552,12 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
|
|
|
1514
1552
|
else {
|
|
1515
1553
|
if (moveView) {
|
|
1516
1554
|
if (context.isParent) {
|
|
1517
|
-
|
|
1555
|
+
if (context.host === context.rootHost) {
|
|
1556
|
+
nativeRenderer.appendChild(context.host, atom.nativeNode, atom.isSvg);
|
|
1557
|
+
}
|
|
1558
|
+
else {
|
|
1559
|
+
nativeRenderer.prependChild(context.host, atom.nativeNode, atom.isSvg);
|
|
1560
|
+
}
|
|
1518
1561
|
}
|
|
1519
1562
|
else {
|
|
1520
1563
|
nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
|
|
@@ -1773,7 +1816,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1773
1816
|
function applyRefs(refs, nativeNode, binding) {
|
|
1774
1817
|
const refList = Array.isArray(refs) ? refs : [refs];
|
|
1775
1818
|
for (const item of refList) {
|
|
1776
|
-
if (item instanceof
|
|
1819
|
+
if (item instanceof DynamicRef) {
|
|
1777
1820
|
binding ? item.bind(nativeNode) : item.unBind(nativeNode);
|
|
1778
1821
|
}
|
|
1779
1822
|
}
|
|
@@ -1814,7 +1857,10 @@ class RootComponent extends Component {
|
|
|
1814
1857
|
const viewflyErrorFn = makeError('Viewfly');
|
|
1815
1858
|
function viewfly(config) {
|
|
1816
1859
|
const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
|
|
1817
|
-
const appProviders = [
|
|
1860
|
+
const appProviders = [{
|
|
1861
|
+
provide: NativeRenderer,
|
|
1862
|
+
useValue: nativeRenderer
|
|
1863
|
+
}];
|
|
1818
1864
|
const modules = [];
|
|
1819
1865
|
let destroyed = false;
|
|
1820
1866
|
let appHost = null;
|
|
@@ -1900,4 +1946,4 @@ function viewfly(config) {
|
|
|
1900
1946
|
return app;
|
|
1901
1947
|
}
|
|
1902
1948
|
|
|
1903
|
-
export { Component, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop,
|
|
1949
|
+
export { Component, DynamicRef, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, Type, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, provide, viewfly, watch, withMemo };
|
package/bundles/index.js
CHANGED
|
@@ -730,7 +730,7 @@ class Component extends ReflectiveInjector {
|
|
|
730
730
|
signalDepsStack.push([]);
|
|
731
731
|
const template = this.instance.$render();
|
|
732
732
|
const deps = signalDepsStack.pop();
|
|
733
|
-
this.unWatch =
|
|
733
|
+
this.unWatch = watch(Array.from(new Set(deps)), () => {
|
|
734
734
|
this.markAsDirtied();
|
|
735
735
|
});
|
|
736
736
|
this.template = template;
|
|
@@ -766,7 +766,7 @@ class Component extends ReflectiveInjector {
|
|
|
766
766
|
signalDepsStack.push([]);
|
|
767
767
|
this.template = this.instance.$render();
|
|
768
768
|
const deps = signalDepsStack.pop();
|
|
769
|
-
this.unWatch =
|
|
769
|
+
this.unWatch = watch(Array.from(new Set(deps)), () => {
|
|
770
770
|
this.markAsDirtied();
|
|
771
771
|
});
|
|
772
772
|
return this.template;
|
|
@@ -847,7 +847,7 @@ class Component extends ReflectiveInjector {
|
|
|
847
847
|
}
|
|
848
848
|
function toRefs(ref) {
|
|
849
849
|
return (Array.isArray(ref) ? ref : [ref]).filter(i => {
|
|
850
|
-
return i instanceof
|
|
850
|
+
return i instanceof DynamicRef;
|
|
851
851
|
});
|
|
852
852
|
}
|
|
853
853
|
/**
|
|
@@ -928,7 +928,7 @@ function onUnmounted(callback) {
|
|
|
928
928
|
const component = getSetupContext();
|
|
929
929
|
component.unmountedCallbacks.push(callback);
|
|
930
930
|
}
|
|
931
|
-
class
|
|
931
|
+
class DynamicRef {
|
|
932
932
|
constructor(callback) {
|
|
933
933
|
this.callback = callback;
|
|
934
934
|
this.unBindMap = new Map();
|
|
@@ -962,7 +962,7 @@ class Ref {
|
|
|
962
962
|
* @example
|
|
963
963
|
* ```tsx
|
|
964
964
|
* function App() {
|
|
965
|
-
* const ref =
|
|
965
|
+
* const ref = createDynamicRef(node => {
|
|
966
966
|
* function fn() {
|
|
967
967
|
* // do something...
|
|
968
968
|
* }
|
|
@@ -977,8 +977,32 @@ class Ref {
|
|
|
977
977
|
* }
|
|
978
978
|
* ```
|
|
979
979
|
*/
|
|
980
|
-
function
|
|
981
|
-
return new
|
|
980
|
+
function createDynamicRef(callback) {
|
|
981
|
+
return new DynamicRef(callback);
|
|
982
|
+
}
|
|
983
|
+
const initValue = {};
|
|
984
|
+
class StaticRef extends DynamicRef {
|
|
985
|
+
constructor() {
|
|
986
|
+
let value = initValue;
|
|
987
|
+
let isInit = false;
|
|
988
|
+
super(v => {
|
|
989
|
+
if (v !== initValue && !isInit) {
|
|
990
|
+
value = v;
|
|
991
|
+
isInit = true;
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
Object.defineProperty(this, 'current', {
|
|
995
|
+
get() {
|
|
996
|
+
if (value === initValue) {
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
return value;
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function createRef() {
|
|
1005
|
+
return new StaticRef();
|
|
982
1006
|
}
|
|
983
1007
|
const depsKey = Symbol('deps');
|
|
984
1008
|
/**
|
|
@@ -988,7 +1012,7 @@ const depsKey = Symbol('deps');
|
|
|
988
1012
|
* ```tsx
|
|
989
1013
|
* function App() {
|
|
990
1014
|
* // 初始化状态
|
|
991
|
-
* const state =
|
|
1015
|
+
* const state = createSignal(1)
|
|
992
1016
|
*
|
|
993
1017
|
* return () => {
|
|
994
1018
|
* <div>
|
|
@@ -1004,7 +1028,7 @@ const depsKey = Symbol('deps');
|
|
|
1004
1028
|
* }
|
|
1005
1029
|
* }
|
|
1006
1030
|
*/
|
|
1007
|
-
function
|
|
1031
|
+
function createSignal(state) {
|
|
1008
1032
|
function signal() {
|
|
1009
1033
|
const depsContext = getSignalDepsContext();
|
|
1010
1034
|
if (depsContext) {
|
|
@@ -1090,9 +1114,9 @@ function listen(model, deps, callback, isContinue) {
|
|
|
1090
1114
|
* @param callback
|
|
1091
1115
|
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
1092
1116
|
*/
|
|
1093
|
-
function
|
|
1117
|
+
function createDerived(callback, isContinue) {
|
|
1094
1118
|
const { data, deps } = invokeDepFn(callback);
|
|
1095
|
-
const signal =
|
|
1119
|
+
const signal = createSignal(data);
|
|
1096
1120
|
const component = getSetupContext(false);
|
|
1097
1121
|
const unListen = listen(signal, deps, callback, isContinue);
|
|
1098
1122
|
if (component) {
|
|
@@ -1103,9 +1127,9 @@ function useDerived(callback, isContinue) {
|
|
|
1103
1127
|
return signal;
|
|
1104
1128
|
}
|
|
1105
1129
|
/* eslint-enable max-len*/
|
|
1106
|
-
function
|
|
1130
|
+
function watch(deps, callback) {
|
|
1107
1131
|
if (typeof deps === 'function' && !deps.$isSignal) {
|
|
1108
|
-
deps =
|
|
1132
|
+
deps = createDerived(deps);
|
|
1109
1133
|
}
|
|
1110
1134
|
const signals = Array.isArray(deps) ? deps : [deps];
|
|
1111
1135
|
let oldValues = signals.map(s => s());
|
|
@@ -1115,7 +1139,7 @@ function useEffect(deps, effect) {
|
|
|
1115
1139
|
prevCleanup();
|
|
1116
1140
|
}
|
|
1117
1141
|
const newValues = signals.map(s => s());
|
|
1118
|
-
prevCleanup = Array.isArray(deps) ?
|
|
1142
|
+
prevCleanup = Array.isArray(deps) ? callback(newValues, oldValues) : callback(newValues[0], oldValues[0]);
|
|
1119
1143
|
oldValues = newValues;
|
|
1120
1144
|
}
|
|
1121
1145
|
for (const dep of signals) {
|
|
@@ -1236,7 +1260,8 @@ function createRenderer(component, nativeRenderer) {
|
|
|
1236
1260
|
};
|
|
1237
1261
|
componentRender(nativeRenderer, component, atom, {
|
|
1238
1262
|
isParent: true,
|
|
1239
|
-
host
|
|
1263
|
+
host,
|
|
1264
|
+
rootHost: host
|
|
1240
1265
|
});
|
|
1241
1266
|
}
|
|
1242
1267
|
else {
|
|
@@ -1263,7 +1288,12 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
|
1263
1288
|
}
|
|
1264
1289
|
atom.nativeNode = nativeNode;
|
|
1265
1290
|
if (context.isParent) {
|
|
1266
|
-
|
|
1291
|
+
if (context.host === context.rootHost) {
|
|
1292
|
+
nativeRenderer.appendChild(context.host, nativeNode, atom.isSvg);
|
|
1293
|
+
}
|
|
1294
|
+
else {
|
|
1295
|
+
nativeRenderer.prependChild(context.host, nativeNode, atom.isSvg);
|
|
1296
|
+
}
|
|
1267
1297
|
}
|
|
1268
1298
|
else {
|
|
1269
1299
|
nativeRenderer.insertAfter(nativeNode, context.host, atom.isSvg);
|
|
@@ -1271,7 +1301,8 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
|
1271
1301
|
if (atom.jsxNode instanceof JSXElement) {
|
|
1272
1302
|
const childContext = {
|
|
1273
1303
|
isParent: true,
|
|
1274
|
-
host: nativeNode
|
|
1304
|
+
host: nativeNode,
|
|
1305
|
+
rootHost: context.rootHost
|
|
1275
1306
|
};
|
|
1276
1307
|
let child = atom.child;
|
|
1277
1308
|
while (child) {
|
|
@@ -1299,7 +1330,7 @@ function updateView(nativeRenderer, component) {
|
|
|
1299
1330
|
}
|
|
1300
1331
|
}
|
|
1301
1332
|
function applyChanges(nativeRenderer, component) {
|
|
1302
|
-
const { atom, host, isParent } = component.$$view;
|
|
1333
|
+
const { atom, host, isParent, rootHost } = component.$$view;
|
|
1303
1334
|
const diffAtom = atom.child;
|
|
1304
1335
|
const template = component.update(component.props, true);
|
|
1305
1336
|
if (template) {
|
|
@@ -1310,7 +1341,8 @@ function applyChanges(nativeRenderer, component) {
|
|
|
1310
1341
|
}
|
|
1311
1342
|
const context = {
|
|
1312
1343
|
host,
|
|
1313
|
-
isParent
|
|
1344
|
+
isParent,
|
|
1345
|
+
rootHost
|
|
1314
1346
|
};
|
|
1315
1347
|
diff(nativeRenderer, component, atom.child, diffAtom, context, 0, 0);
|
|
1316
1348
|
const next = atom.sibling;
|
|
@@ -1442,7 +1474,12 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
|
|
|
1442
1474
|
const host = context.host;
|
|
1443
1475
|
if (expectIndex - offset !== oldIndex) {
|
|
1444
1476
|
if (context.isParent) {
|
|
1445
|
-
|
|
1477
|
+
if (host === context.rootHost) {
|
|
1478
|
+
nativeRenderer.appendChild(host, newAtom.nativeNode, newAtom.isSvg);
|
|
1479
|
+
}
|
|
1480
|
+
else {
|
|
1481
|
+
nativeRenderer.prependChild(host, newAtom.nativeNode, newAtom.isSvg);
|
|
1482
|
+
}
|
|
1446
1483
|
}
|
|
1447
1484
|
else {
|
|
1448
1485
|
nativeRenderer.insertAfter(newAtom.nativeNode, host, newAtom.isSvg);
|
|
@@ -1454,7 +1491,8 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
|
|
|
1454
1491
|
if (newAtom.child) {
|
|
1455
1492
|
diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
|
|
1456
1493
|
host: newAtom.nativeNode,
|
|
1457
|
-
isParent: true
|
|
1494
|
+
isParent: true,
|
|
1495
|
+
rootHost: context.rootHost
|
|
1458
1496
|
}, 0, 0);
|
|
1459
1497
|
}
|
|
1460
1498
|
else if (oldAtom.child) {
|
|
@@ -1516,7 +1554,12 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
|
|
|
1516
1554
|
else {
|
|
1517
1555
|
if (moveView) {
|
|
1518
1556
|
if (context.isParent) {
|
|
1519
|
-
|
|
1557
|
+
if (context.host === context.rootHost) {
|
|
1558
|
+
nativeRenderer.appendChild(context.host, atom.nativeNode, atom.isSvg);
|
|
1559
|
+
}
|
|
1560
|
+
else {
|
|
1561
|
+
nativeRenderer.prependChild(context.host, atom.nativeNode, atom.isSvg);
|
|
1562
|
+
}
|
|
1520
1563
|
}
|
|
1521
1564
|
else {
|
|
1522
1565
|
nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
|
|
@@ -1775,7 +1818,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1775
1818
|
function applyRefs(refs, nativeNode, binding) {
|
|
1776
1819
|
const refList = Array.isArray(refs) ? refs : [refs];
|
|
1777
1820
|
for (const item of refList) {
|
|
1778
|
-
if (item instanceof
|
|
1821
|
+
if (item instanceof DynamicRef) {
|
|
1779
1822
|
binding ? item.bind(nativeNode) : item.unBind(nativeNode);
|
|
1780
1823
|
}
|
|
1781
1824
|
}
|
|
@@ -1816,7 +1859,10 @@ class RootComponent extends Component {
|
|
|
1816
1859
|
const viewflyErrorFn = makeError('Viewfly');
|
|
1817
1860
|
function viewfly(config) {
|
|
1818
1861
|
const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
|
|
1819
|
-
const appProviders = [
|
|
1862
|
+
const appProviders = [{
|
|
1863
|
+
provide: NativeRenderer,
|
|
1864
|
+
useValue: nativeRenderer
|
|
1865
|
+
}];
|
|
1820
1866
|
const modules = [];
|
|
1821
1867
|
let destroyed = false;
|
|
1822
1868
|
let appHost = null;
|
|
@@ -1903,6 +1949,7 @@ function viewfly(config) {
|
|
|
1903
1949
|
}
|
|
1904
1950
|
|
|
1905
1951
|
exports.Component = Component;
|
|
1952
|
+
exports.DynamicRef = DynamicRef;
|
|
1906
1953
|
exports.ForwardRef = ForwardRef;
|
|
1907
1954
|
exports.Fragment = Fragment;
|
|
1908
1955
|
exports.Inject = Inject;
|
|
@@ -1916,15 +1963,19 @@ exports.NativeRenderer = NativeRenderer;
|
|
|
1916
1963
|
exports.NullInjector = NullInjector;
|
|
1917
1964
|
exports.Optional = Optional;
|
|
1918
1965
|
exports.Prop = Prop;
|
|
1919
|
-
exports.Ref = Ref;
|
|
1920
1966
|
exports.ReflectiveInjector = ReflectiveInjector;
|
|
1921
1967
|
exports.RootComponent = RootComponent;
|
|
1922
1968
|
exports.Scope = Scope;
|
|
1923
1969
|
exports.Self = Self;
|
|
1924
1970
|
exports.SkipSelf = SkipSelf;
|
|
1971
|
+
exports.StaticRef = StaticRef;
|
|
1925
1972
|
exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1926
1973
|
exports.Type = Type;
|
|
1974
|
+
exports.createDerived = createDerived;
|
|
1975
|
+
exports.createDynamicRef = createDynamicRef;
|
|
1976
|
+
exports.createRef = createRef;
|
|
1927
1977
|
exports.createRenderer = createRenderer;
|
|
1978
|
+
exports.createSignal = createSignal;
|
|
1928
1979
|
exports.forwardRef = forwardRef;
|
|
1929
1980
|
exports.getCurrentInstance = getCurrentInstance;
|
|
1930
1981
|
exports.inject = inject;
|
|
@@ -1937,9 +1988,6 @@ exports.onPropsChanged = onPropsChanged;
|
|
|
1937
1988
|
exports.onUnmounted = onUnmounted;
|
|
1938
1989
|
exports.onUpdated = onUpdated;
|
|
1939
1990
|
exports.provide = provide;
|
|
1940
|
-
exports.useDerived = useDerived;
|
|
1941
|
-
exports.useEffect = useEffect;
|
|
1942
|
-
exports.useRef = useRef;
|
|
1943
|
-
exports.useSignal = useSignal;
|
|
1944
1991
|
exports.viewfly = viewfly;
|
|
1992
|
+
exports.watch = watch;
|
|
1945
1993
|
exports.withMemo = withMemo;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
|
|
5
5
|
"main": "./bundles/index.js",
|
|
6
6
|
"module": "./bundles/index.esm.js",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"bugs": {
|
|
48
48
|
"url": "https://github.com/viewfly/viewfly.git/issues"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "343b1bff988837e5e0a2acee63c18c3f4a3e8721",
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"reflect-metadata": "^0.1.13"
|
|
53
53
|
}
|