修复失效的Ref关键字,更新receiver初始化时机为mounted而非setup

This commit is contained in:
陈梓阳 2025-06-04 14:48:36 +08:00
parent 49afb5e3a6
commit 6ed8fd1ddc
6 changed files with 43 additions and 29 deletions

View File

@ -1,7 +1,7 @@
{
"name": "vue-modpage",
"private": true,
"version": "1.0.6",
"version": "1.0.11",
"type": "module",
"files": [
"public",

View File

@ -22,16 +22,16 @@ const dom = ref(h(SlotTester, null, { default: () => [
onMounted(() => {
setTimeout(() => {
console.log(test.value);
console.log(testRef.value);
}, 3000);
});
const test = ref<HTMLDivElement>();
const testRef = ref<HTMLDivElement>();
const vueVer = version;
const items = [
//
{
tag: 'div', data: { ref: test, style: { backgroundColor: 'gray', padding: '10px' } }, children: '1. 字符串渲染测试'
tag: 'div', data: { style: { backgroundColor: 'gray', padding: '10px' } }, children: '1. 字符串渲染测试'
},
{
tag: 'div', data: { style: { background: 'cyan', padding: '10px' } }, children: [
@ -65,11 +65,12 @@ const items = [
{
tag: 'test-parent',
data: {
ref: testRef,
message: '8. 事件调用测试',
style: 'color: red',
onCallback: (msg) => { // NativeOn?
alert(msg);
console.log(test.value)
console.log(testRef.value)
}
}
}

View File

@ -24,16 +24,17 @@ function splitAttrs(obj: object) : { attrs: Record<string, any>, on: Record<stri
* @returns
*/
function splitVue2Data(rawData?: Record<string, any> | null) {
// console.warn("Handling Vue2 data: ", rawData);
if (!rawData) return {};
console.log("[ModPage Render Function] Handling Vue2 data: ", rawData);
if (!rawData) return null;
if (isVue3) throw new Error("Vue3 data object is not supported in Vue2");
// Vue2分离式处理
else {
const on = {}; // 可能需要区分NativeOn
const { class: cls, style, attrs = {}, props = {}, ...rest } = rawData;
// 从 rawData 中显式提取 ref其余的放入 rest
const { class: cls, style, attrs = {}, props = {}, ref: v2Ref, ...rest } = rawData;
// 处理事件
// 处理事件:从 rest 中提取事件处理器到 on 对象
for (const key in rest) {
if (key.indexOf('on') == 0 && key != 'on') {
const newKey = key[2].toLowerCase() + key.substring(3);
@ -44,8 +45,10 @@ function splitVue2Data(rawData?: Record<string, any> | null) {
class: cls,
style,
attrs: attrs,
props: { ...props, ...rest }, // 未明确的属性放入props
// props 现在由原始 props 和 rest 中剩余的非事件、非 ref 属性组成
props: { ...props, ...rest },
on,
ref: v2Ref, // 将提取的 ref 放置在 v2data 的顶层
}
return v2data;
}
@ -132,5 +135,7 @@ export function hh(tag: string | object, data?: Record<string, any> | null, chil
// console.debug("Processed", {
// processedTag, processedData, processedChildren
// });
return render(processedTag, processedData, processedChildren);
const result = render(processedTag, processedData, processedChildren);
console.log("[ModPage Render Function] result: ", result);
return result;
}

View File

@ -2,6 +2,7 @@ import {
defineComponent,
h,
isVue2,
markRaw,
onMounted,
onUnmounted,
ref,
@ -51,7 +52,9 @@ export default defineComponent({
window[invokerKey][id] = {
getRenderContext,
initFinish,
receiver,
getReceiver() {
return receiver;
}
};
@ -77,9 +80,11 @@ export default defineComponent({
// vue3 渲染上下文
function getRenderContext() {
return props.items;
return markRaw(props.items);
}
// 用expose外部没有感知用defineExpose在vue2会报错没办法
expose({
getRefs,
getRenderContext,

View File

@ -31,22 +31,25 @@ export default defineComponent({
const renderItems = ref(invokerContext.getRenderContext() ?? []);
// 若Invoker未接收到当前实例(首次初始化),则进行初始化
if (!invokerContext.receiver) {
invokerContext.initFinish({
get renderVersion() {
return renderVersion.value;
},
Update: function (): void {
renderVersion.value += 1;
renderItems.value = invokerContext.getRenderContext() ?? [];
instance?.proxy?.$forceUpdate();
},
// @ts-ignore
get refs() {
return instance?.proxy?.$refs;
}
});
}
onMounted(function () {
if (!invokerContext.receiver) {
invokerContext.initFinish({
get renderVersion() {
return renderVersion.value;
},
Update: function (): void {
renderVersion.value += 1;
renderItems.value = invokerContext.getRenderContext() ?? [];
instance?.proxy?.$forceUpdate();
},
// @ts-ignore
get refs() {
return instance?.proxy?.$refs;
}
});
}
})
return (createElem) => {
const render = isVue2 ? createElem : h;

Binary file not shown.