actview 3.0.0 → 3.2.0
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/README.md +1 -1
- package/dist/index.d.ts +30 -13
- package/dist/index.js +89 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
## 核心功能
|
|
8
8
|
|
|
9
9
|
- **vue 运行时 re-export**:响应式(`ref` / `reactive` / `computed` / `watch` / `effectScope`)、组件(`defineComponent` / `createApp` / `h`)、生命周期、内置组件(`KeepAlive` / `Teleport` / `Suspense` / `Transition` / `TransitionGroup`)
|
|
10
|
-
- **defineComponent 桥接**(React
|
|
10
|
+
- **defineComponent 桥接**(React 对齐):props 读不到时从 attrs 兜底(React 风格任意 props 可读);**`props.children` 渲染期读取 = 子内容值**(React 语义,非渲染期读取返回 undefined 并提示——判断有无子内容用 `props.slots.default != null`);`props.slots.default()` 具名插槽/显式调用(render 期);**createVNode 包装**:`<p {...props}>` 展开的 children 键自动抽进第三参(React 对齐);桥接虚拟键(children/slots)不参与展开/遍历;**有 props 声明时自动落根**(`inheritAttrs` 开启,未消费 attrs 透传到根元素 + scoped data-v 生效),无声明时保持不透传(React 语义,避免 props 污染 DOM)
|
|
11
11
|
- **createContext**:React 语义(`.Provider` / `.use()`),基于 vue `provide/inject`
|
|
12
12
|
- **JSX 类型层**:全局 `IntrinsicElements` 完整标签表(React 语义属性)+ vue 组件兼容;组件 props 严格检查(未声明 prop 报错)
|
|
13
13
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
import { VNode, Reactive, SetupContext } from 'vue';
|
|
2
|
-
export { App, Comment, Component, ComponentPublicInstance, ComputedRef, DeepReadonly, DefineComponent, EffectScope, EffectScope as EffectScopeType, EmitsOptions, Fragment, InjectionKey, KeepAlive, Plugin, PropType, Reactive, Ref, RenderFunction, SetupContext, ShallowReactive, ShallowRef, Slot, Slots, Static,
|
|
2
|
+
export { App, Comment, Component, ComponentPublicInstance, ComputedRef, DeepReadonly, DefineComponent, EffectScope, EffectScope as EffectScopeType, EmitsOptions, Fragment, InjectionKey, KeepAlive, Plugin, PropType, Reactive, Ref, RenderFunction, SetupContext, ShallowReactive, ShallowRef, Slot, Slots, Static, Teleport, Text, Transition, TransitionGroup, VNode, VNodeChild, VNodeTypes, WatchCallback, WatchOptions, WatchSource, WritableComputedRef, cloneVNode, computed, createApp, customRef, defineAsyncComponent, effectScope, getCurrentInstance, getCurrentScope, h, inject, isProxy, isReactive, isReadonly, isRef, isShallow, isVNode, markRaw, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, onWatcherCleanup, provide, proxyRefs, reactive, readonly, ref, resolveComponent, resolveDirective, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, toValue, triggerRef, unref, useAttrs, useId, useSlots, useTemplateRef, version, watch, watchEffect, watchPostEffect, watchSyncEffect, withDirectives } from 'vue';
|
|
3
3
|
|
|
4
|
+
declare function createVNode(type: any, props: any, children?: any): VNode;
|
|
5
|
+
interface SuspenseProps {
|
|
6
|
+
/** React 语义:异步解析期间显示的 fallback(桥接为 vue #fallback 插槽) */
|
|
7
|
+
fallback?: any;
|
|
8
|
+
/** vue 原生插槽(默认插槽 props.slots.default()) */
|
|
9
|
+
slots?: any;
|
|
10
|
+
/** 其余透传:vue Suspense 事件/选项 */
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
declare const Suspense: ActViewComponent<SuspenseProps>;
|
|
4
14
|
/**
|
|
5
15
|
* v2 组件类型(类型层形状):
|
|
6
16
|
* 运行时是 vue DefineComponent(createApp/渲染消费),但类型层用自定义形状
|
|
7
17
|
* ——只有 call signature、无构造签名。TS 6 的 JSX 检查(getJsxReferenceKind)
|
|
8
18
|
* 按「构造签名 → Component 路径($props 宽松)/ 调用签名 → Function 路径
|
|
9
19
|
* (props = 参数类型,严格)」分流——无构造签名让组件走 Function 路径,
|
|
10
|
-
* props 检查精确为 Props
|
|
20
|
+
* props 检查精确为 Props(React 严格语义:未声明 prop 报错)。
|
|
21
|
+
* 子内容类型:JSX children 属性来自全局 IntrinsicAttributes(react-jsx
|
|
22
|
+
* 机制);组件内读 props.slots(vue 原生,类型由组件 props 声明或 any)。
|
|
11
23
|
*/
|
|
12
24
|
type ActViewComponent<Props extends Record<string, any> = Record<string, any>> = {
|
|
13
|
-
/** 类型层 call signature:TS 走 Function 路径,props = Props
|
|
14
|
-
(props: Props
|
|
15
|
-
children?: any;
|
|
16
|
-
}): VNode;
|
|
25
|
+
/** 类型层 call signature:TS 走 Function 路径,props = Props */
|
|
26
|
+
(props: Props): VNode;
|
|
17
27
|
/** ElementAttributesProperty{ $props } 兜底(vue 全局 JSX 机制) */
|
|
18
|
-
$props: Props
|
|
19
|
-
children?: any;
|
|
20
|
-
};
|
|
28
|
+
$props: Props;
|
|
21
29
|
name?: string;
|
|
22
30
|
/** vue 组件标记(运行时是 DefineComponent) */
|
|
23
31
|
__isVue?: true;
|
|
24
32
|
__vccOpts?: any;
|
|
25
33
|
};
|
|
26
|
-
|
|
34
|
+
interface ActViewDefineComponentOptions {
|
|
35
|
+
name?: string;
|
|
36
|
+
/**
|
|
37
|
+
* 运行时 props 声明(@actview/plugin-jsx 编译期从类型注解提取注入,
|
|
38
|
+
* 也可手写)。存在时开启自动落根:未消费的 attrs(class / data-v-* /
|
|
39
|
+
* 事件 / 透传属性)自动 apply 到根元素。
|
|
40
|
+
*/
|
|
41
|
+
props?: Record<string, any>;
|
|
42
|
+
}
|
|
43
|
+
declare function defineComponent<Props extends Record<string, any> = Record<string, any>>(setup: (props: Props, ctx: SetupContext) => unknown, options?: ActViewDefineComponentOptions | string): ActViewComponent<Props>;
|
|
27
44
|
interface Context<T> {
|
|
28
45
|
/** 内部唯一键(Symbol):对象身份即键 */
|
|
29
46
|
readonly _key: symbol;
|
|
30
|
-
/**
|
|
31
|
-
|
|
47
|
+
/** vue 组件对象形态的 setup——<Ctx value={v}> 直接作组件用(React 19 风格) */
|
|
48
|
+
setup: (props: any, setupCtx: any) => any;
|
|
32
49
|
name?: string;
|
|
33
50
|
/** <Ctx.Provider value={v}> 经典风格 */
|
|
34
51
|
Provider: Context<T>;
|
|
@@ -43,4 +60,4 @@ interface Context<T> {
|
|
|
43
60
|
declare function createContext<T extends object>(defaultValue: Reactive<T>): Context<T>;
|
|
44
61
|
declare function createContext<T>(defaultValue: T): Context<T>;
|
|
45
62
|
|
|
46
|
-
export { type ActViewComponent, type Context, createContext, defineComponent };
|
|
63
|
+
export { type ActViewComponent, type ActViewDefineComponentOptions, type Context, Suspense, type SuspenseProps, createContext, createVNode, defineComponent };
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,6 @@ import {
|
|
|
35
35
|
createApp,
|
|
36
36
|
nextTick,
|
|
37
37
|
h,
|
|
38
|
-
createVNode,
|
|
39
38
|
cloneVNode,
|
|
40
39
|
mergeProps,
|
|
41
40
|
isVNode,
|
|
@@ -46,7 +45,6 @@ import {
|
|
|
46
45
|
Static,
|
|
47
46
|
KeepAlive,
|
|
48
47
|
Teleport,
|
|
49
|
-
Suspense,
|
|
50
48
|
Transition,
|
|
51
49
|
TransitionGroup,
|
|
52
50
|
defineAsyncComponent,
|
|
@@ -73,52 +71,115 @@ import {
|
|
|
73
71
|
version
|
|
74
72
|
} from "vue";
|
|
75
73
|
import {
|
|
74
|
+
createVNode as vueCreateVNode,
|
|
76
75
|
defineComponent as vueDefineComponent,
|
|
77
76
|
Fragment as _Fragment,
|
|
78
77
|
h as h2,
|
|
79
78
|
inject as inject2,
|
|
80
|
-
|
|
79
|
+
isVNode as isVNode2,
|
|
80
|
+
provide as provide2,
|
|
81
|
+
Suspense as VueSuspense
|
|
81
82
|
} from "vue";
|
|
82
|
-
|
|
83
|
+
var activeRenderDepth = 0;
|
|
84
|
+
function wrapSlots(children) {
|
|
85
|
+
if (children && typeof children === "object" && !Array.isArray(children) && !isVNode2(children)) {
|
|
86
|
+
for (const k in children) {
|
|
87
|
+
const fn = children[k];
|
|
88
|
+
if (typeof fn === "function") {
|
|
89
|
+
children[k] = (...args) => {
|
|
90
|
+
activeRenderDepth++;
|
|
91
|
+
try {
|
|
92
|
+
return fn(...args);
|
|
93
|
+
} finally {
|
|
94
|
+
activeRenderDepth--;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return children;
|
|
101
|
+
}
|
|
102
|
+
function createVNode(type, props, children) {
|
|
103
|
+
if (props && "children" in props) {
|
|
104
|
+
if (children == null) {
|
|
105
|
+
children = props.children;
|
|
106
|
+
}
|
|
107
|
+
delete props.children;
|
|
108
|
+
}
|
|
109
|
+
if (children != null && !Array.isArray(children) && isVNode2(children)) {
|
|
110
|
+
children = [children];
|
|
111
|
+
}
|
|
112
|
+
return vueCreateVNode(type, props, wrapSlots(children));
|
|
113
|
+
}
|
|
114
|
+
var Suspense = defineComponent(function(props) {
|
|
115
|
+
return () => {
|
|
116
|
+
const { fallback, ...rest } = props;
|
|
117
|
+
return h2(VueSuspense, rest, {
|
|
118
|
+
default: () => props.slots?.default?.() ?? [],
|
|
119
|
+
fallback: () => fallback != null ? fallback : []
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
}, "ActViewSuspense");
|
|
123
|
+
function defineComponent(setup, options) {
|
|
124
|
+
const opts = typeof options === "string" ? { name: options } : options ?? {};
|
|
83
125
|
return vueDefineComponent({
|
|
84
|
-
name,
|
|
85
|
-
//
|
|
86
|
-
|
|
126
|
+
name: opts.name,
|
|
127
|
+
// 编译期提取的 props 声明(无则 undefined——组件保持「任意 props 兜底」)
|
|
128
|
+
props: opts.props,
|
|
129
|
+
// 有 props 声明 → 开启自动落根(透传 + scoped data-v 生效);
|
|
130
|
+
// 无声明 → false(React 语义:避免未消费 props 以 DOM 属性形式污染根元素)
|
|
131
|
+
inheritAttrs: !!opts.props,
|
|
87
132
|
setup(props, ctx) {
|
|
88
133
|
const attrs = ctx.attrs;
|
|
134
|
+
let renderPhase = false;
|
|
135
|
+
let warnedNonRenderRead = false;
|
|
89
136
|
const bridge = new Proxy(props, {
|
|
90
137
|
get(t, k) {
|
|
91
|
-
if (k === "children") return ctx.slots.default?.() ?? null;
|
|
92
138
|
if (k === "slots") return ctx.slots;
|
|
139
|
+
if (k === "children") {
|
|
140
|
+
if (renderPhase || activeRenderDepth > 0) {
|
|
141
|
+
return ctx.slots.default?.() ?? null;
|
|
142
|
+
}
|
|
143
|
+
if (!warnedNonRenderRead) {
|
|
144
|
+
warnedNonRenderRead = true;
|
|
145
|
+
console.warn(
|
|
146
|
+
"[actview] \u975E\u6E32\u67D3\u671F\u8BFB\u53D6 props.children\uFF1A\u63D2\u69FD\u5185\u5BB9\u53EA\u5728\u6E32\u67D3\u671F\u53EF\u7528\u3002\u5224\u65AD\u6709\u65E0\u5B50\u5185\u5BB9\u8BF7\u7528 props.slots.default != null\uFF1B\u6E32\u67D3\u671F\u7528 props.children \u6216 props.slots.default()"
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return void 0;
|
|
150
|
+
}
|
|
93
151
|
const own = Reflect.get(t, k);
|
|
94
152
|
if (own !== void 0) return own;
|
|
95
153
|
return attrs[k];
|
|
96
154
|
},
|
|
97
155
|
has(t, k) {
|
|
98
|
-
return k === "
|
|
156
|
+
return k === "slots" || k === "children" || Reflect.has(t, k) || k in attrs;
|
|
99
157
|
},
|
|
100
158
|
ownKeys(t) {
|
|
101
159
|
return [
|
|
102
160
|
.../* @__PURE__ */ new Set([
|
|
103
161
|
...Reflect.ownKeys(t),
|
|
104
|
-
...Reflect.ownKeys(attrs)
|
|
105
|
-
"children",
|
|
106
|
-
"slots"
|
|
162
|
+
...Reflect.ownKeys(attrs)
|
|
107
163
|
])
|
|
108
164
|
];
|
|
109
165
|
},
|
|
110
166
|
getOwnPropertyDescriptor(t, k) {
|
|
111
|
-
if (k === "children" || k === "slots") {
|
|
112
|
-
return {
|
|
113
|
-
enumerable: true,
|
|
114
|
-
configurable: true,
|
|
115
|
-
value: k === "children" ? ctx.slots.default?.() ?? null : ctx.slots
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
167
|
return Reflect.getOwnPropertyDescriptor(t, k) ?? Reflect.getOwnPropertyDescriptor(attrs, k);
|
|
119
168
|
}
|
|
120
169
|
});
|
|
121
|
-
|
|
170
|
+
const userResult = setup(bridge, ctx);
|
|
171
|
+
if (typeof userResult === "function") {
|
|
172
|
+
const userRender = userResult;
|
|
173
|
+
return () => {
|
|
174
|
+
renderPhase = true;
|
|
175
|
+
try {
|
|
176
|
+
return userRender();
|
|
177
|
+
} finally {
|
|
178
|
+
renderPhase = false;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return userResult;
|
|
122
183
|
}
|
|
123
184
|
// 返回类型以声明为准(vue 的推断带 ExtractPropTypes 包装,与泛型 Props 不完全同构)
|
|
124
185
|
});
|
|
@@ -127,13 +188,19 @@ function createContext(defaultValue) {
|
|
|
127
188
|
const key = /* @__PURE__ */ Symbol("actview-context");
|
|
128
189
|
const provider = defineComponent(function(props) {
|
|
129
190
|
provide2(key, props.value ?? defaultValue);
|
|
130
|
-
return () => h2(_Fragment, null, props.
|
|
191
|
+
return () => h2(_Fragment, null, props.slots.default?.() ?? null);
|
|
131
192
|
}, "ActViewContext.Provider");
|
|
132
193
|
const ctx = {
|
|
133
194
|
_key: key,
|
|
134
|
-
__setup: provider.__setup,
|
|
135
195
|
name: "ActViewContext",
|
|
136
196
|
Provider: provider,
|
|
197
|
+
// React 19 风格 <Ctx value={v}>:Context 直接作组件——
|
|
198
|
+
// vue 组件对象 setup 形态(provide + 渲染 children)
|
|
199
|
+
setup(props, setupCtx) {
|
|
200
|
+
const value = props.value ?? setupCtx.attrs?.value ?? defaultValue;
|
|
201
|
+
provide2(key, value);
|
|
202
|
+
return () => h2(_Fragment, null, setupCtx.slots?.default?.() ?? null);
|
|
203
|
+
},
|
|
137
204
|
use() {
|
|
138
205
|
return inject2(key, defaultValue);
|
|
139
206
|
}
|