Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qianlong66
uni-app
提交
ae7ec06d
U
uni-app
项目概览
qianlong66
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ae7ec06d
编写于
10月 24, 2021
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(mp): scoped slots
上级
f63216a6
变更
51
展开全部
隐藏空白更改
内联
并排
Showing
51 changed file
with
1644 addition
and
3369 deletion
+1644
-3369
packages/shims-vue-runtime.d.ts
packages/shims-vue-runtime.d.ts
+3
-1
packages/uni-core/src/helpers/hook.ts
packages/uni-core/src/helpers/hook.ts
+6
-2
packages/uni-mp-alipay/dist/uni.mp.esm.js
packages/uni-mp-alipay/dist/uni.mp.esm.js
+62
-362
packages/uni-mp-alipay/src/runtime/createComponent.ts
packages/uni-mp-alipay/src/runtime/createComponent.ts
+2
-3
packages/uni-mp-alipay/src/runtime/createPage.ts
packages/uni-mp-alipay/src/runtime/createPage.ts
+0
-2
packages/uni-mp-baidu/dist/uni.mp.esm.js
packages/uni-mp-baidu/dist/uni.mp.esm.js
+96
-404
packages/uni-mp-compiler/__tests__/component.spec.ts
packages/uni-mp-compiler/__tests__/component.spec.ts
+5
-5
packages/uni-mp-compiler/__tests__/scopedSlot.spec.ts
packages/uni-mp-compiler/__tests__/scopedSlot.spec.ts
+31
-0
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
+46
-6
packages/uni-mp-compiler/src/ast.ts
packages/uni-mp-compiler/src/ast.ts
+1
-50
packages/uni-mp-compiler/src/compile.ts
packages/uni-mp-compiler/src/compile.ts
+3
-2
packages/uni-mp-compiler/src/runtimeHelpers.ts
packages/uni-mp-compiler/src/runtimeHelpers.ts
+4
-0
packages/uni-mp-compiler/src/template/codegen.ts
packages/uni-mp-compiler/src/template/codegen.ts
+6
-34
packages/uni-mp-compiler/src/transform.ts
packages/uni-mp-compiler/src/transform.ts
+5
-7
packages/uni-mp-compiler/src/transforms/transformComponent.ts
...ages/uni-mp-compiler/src/transforms/transformComponent.ts
+24
-18
packages/uni-mp-compiler/src/transforms/transformElement.ts
packages/uni-mp-compiler/src/transforms/transformElement.ts
+9
-3
packages/uni-mp-compiler/src/transforms/transformIdentifier.ts
...ges/uni-mp-compiler/src/transforms/transformIdentifier.ts
+12
-10
packages/uni-mp-compiler/src/transforms/transformSlot.ts
packages/uni-mp-compiler/src/transforms/transformSlot.ts
+94
-0
packages/uni-mp-compiler/src/transforms/utils.ts
packages/uni-mp-compiler/src/transforms/utils.ts
+38
-2
packages/uni-mp-compiler/src/transforms/vFor.ts
packages/uni-mp-compiler/src/transforms/vFor.ts
+74
-15
packages/uni-mp-compiler/src/transforms/vIf.ts
packages/uni-mp-compiler/src/transforms/vIf.ts
+7
-4
packages/uni-mp-compiler/src/transforms/vSlot.ts
packages/uni-mp-compiler/src/transforms/vSlot.ts
+291
-0
packages/uni-mp-core/src/index.ts
packages/uni-mp-core/src/index.ts
+0
-1
packages/uni-mp-core/src/runtime/component.ts
packages/uni-mp-core/src/runtime/component.ts
+0
-2
packages/uni-mp-core/src/runtime/componentEvents.ts
packages/uni-mp-core/src/runtime/componentEvents.ts
+0
-327
packages/uni-mp-core/src/runtime/componentInstance/index.ts
packages/uni-mp-core/src/runtime/componentInstance/index.ts
+1
-70
packages/uni-mp-core/src/runtime/componentInstance/utils.ts
packages/uni-mp-core/src/runtime/componentInstance/utils.ts
+2
-3
packages/uni-mp-core/src/runtime/componentProps.ts
packages/uni-mp-core/src/runtime/componentProps.ts
+1
-1
packages/uni-mp-core/src/runtime/util.ts
packages/uni-mp-core/src/runtime/util.ts
+0
-16
packages/uni-mp-kuaishou/dist/uni.mp.esm.js
packages/uni-mp-kuaishou/dist/uni.mp.esm.js
+96
-396
packages/uni-mp-qq/dist/uni.mp.esm.js
packages/uni-mp-qq/dist/uni.mp.esm.js
+96
-396
packages/uni-mp-toutiao/dist/uni.mp.esm.js
packages/uni-mp-toutiao/dist/uni.mp.esm.js
+96
-396
packages/uni-mp-toutiao/src/runtime/componentLifetimes.ts
packages/uni-mp-toutiao/src/runtime/componentLifetimes.ts
+1
-1
packages/uni-mp-vue/__tests__/withScopedSlot.spec.ts
packages/uni-mp-vue/__tests__/withScopedSlot.spec.ts
+41
-0
packages/uni-mp-vue/build.json
packages/uni-mp-vue/build.json
+1
-1
packages/uni-mp-vue/dist/vue.runtime.esm.js
packages/uni-mp-vue/dist/vue.runtime.esm.js
+84
-77
packages/uni-mp-vue/lib/vue.runtime.esm.js
packages/uni-mp-vue/lib/vue.runtime.esm.js
+3
-3
packages/uni-mp-vue/src/helpers/index.ts
packages/uni-mp-vue/src/helpers/index.ts
+2
-0
packages/uni-mp-vue/src/helpers/renderSlot.ts
packages/uni-mp-vue/src/helpers/renderSlot.ts
+33
-0
packages/uni-mp-vue/src/helpers/vOn.ts
packages/uni-mp-vue/src/helpers/vOn.ts
+35
-10
packages/uni-mp-vue/src/helpers/withScopedSlot.ts
packages/uni-mp-vue/src/helpers/withScopedSlot.ts
+104
-0
packages/uni-mp-vue/src/index.ts
packages/uni-mp-vue/src/index.ts
+4
-2
packages/uni-mp-vue/src/state.ts
packages/uni-mp-vue/src/state.ts
+0
-4
packages/uni-mp-weixin/dist/uni.mp.esm.js
packages/uni-mp-weixin/dist/uni.mp.esm.js
+105
-405
packages/uni-mp-weixin/src/runtime/lifetimes.ts
packages/uni-mp-weixin/src/runtime/lifetimes.ts
+1
-1
packages/uni-quickapp-webview/dist/uni.mp.esm.js
packages/uni-quickapp-webview/dist/uni.mp.esm.js
+76
-326
packages/uni-shared/dist/uni-shared.cjs.js
packages/uni-shared/dist/uni-shared.cjs.js
+13
-0
packages/uni-shared/dist/uni-shared.d.ts
packages/uni-shared/dist/uni-shared.d.ts
+2
-0
packages/uni-shared/dist/uni-shared.es.js
packages/uni-shared/dist/uni-shared.es.js
+13
-1
packages/uni-shared/src/data.ts
packages/uni-shared/src/data.ts
+14
-0
packages/uni-shared/src/index.ts
packages/uni-shared/src/index.ts
+1
-0
未找到文件。
packages/shims-vue-runtime.d.ts
浏览文件 @
ae7ec06d
...
...
@@ -21,10 +21,12 @@ declare module '@vue/runtime-core' {
type
UniLifecycleHookInstance
=
{
[
name
in
UniLifecycleHooks
]:
LifecycleHook
}
interface
ComponentInternalInstance
extends
UniLifecycleHookInstance
{
interface
ComponentInternalInstance
{
__isUnload
:
boolean
__isVisible
:
boolean
__isActive
?:
boolean
// tabBar
// h5 | app
$wxsModules
?:
string
[]
}
export
const
callSyncHook
:
(
...
...
packages/uni-core/src/helpers/hook.ts
浏览文件 @
ae7ec06d
...
...
@@ -36,7 +36,9 @@ export function invokeHook(
return
(
vm
as
any
).
__call_hook
(
name
,
args
)
}
}
const
hooks
=
vm
.
$
[
name
as
string
]
const
hooks
=
(
vm
.
$
as
unknown
as
{
[
name
:
string
]:
Function
[]
})[
name
as
string
]
return
hooks
&&
invokeArrayFns
(
hooks
,
args
)
}
...
...
@@ -52,6 +54,8 @@ export function hasHook(vm: ComponentPublicInstance | number, name: string) {
if
(
!
vm
)
{
return
false
}
const
hooks
=
vm
.
$
[
name
]
const
hooks
=
(
vm
.
$
as
unknown
as
{
[
name
:
string
]:
Function
[]
})[
name
as
string
]
return
!!
(
hooks
&&
hooks
.
length
)
}
packages/uni-mp-alipay/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
import
{
isPlainObject
,
isArray
,
extend
,
hyphenate
,
isObject
,
hasOwn
,
toNumber
,
capitalize
,
isFunction
,
NOOP
,
EMPTY_OBJ
,
camelize
}
from
'
@vue/shared
'
;
import
{
onUnmounted
,
injectHook
,
ref
}
from
'
vue
'
;
import
{
isPlainObject
,
extend
,
hyphenate
,
isObject
,
hasOwn
,
isArray
,
toNumber
,
capitalize
,
isFunction
,
EMPTY_OBJ
,
camelize
}
from
'
@vue/shared
'
;
import
{
injectHook
,
ref
}
from
'
vue
'
;
const
encode
=
encodeURIComponent
;
function
stringifyQuery
(
obj
,
encodeStr
=
encode
)
{
...
...
@@ -21,6 +21,18 @@ function stringifyQuery(obj, encodeStr = encode) {
return
res
?
`?
${
res
}
`
:
''
;
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
cache
(
fn
)
{
const
cache
=
Object
.
create
(
null
);
return
(
str
)
=>
{
...
...
@@ -131,67 +143,8 @@ function getEventChannel(id) {
return
eventChannelStack
.
shift
();
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
function
getTarget
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
let
key
=
parts
[
0
];
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
));
}
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
getValue
(
dataPath
,
target
)
{
return
get
Target
(
target
||
this
,
dataPath
);
return
get
DataByPath
(
target
||
this
,
dataPath
);
}
function
getClass
(
dynamicClass
,
staticClass
)
{
return
renderClass
(
staticClass
,
dynamicClass
);
...
...
@@ -393,9 +346,6 @@ function initBaseInstance(instance, options) {
}
function
initComponentInstance
(
instance
,
options
)
{
initBaseInstance
(
instance
,
options
);
{
initScopedSlotsParams
(
instance
);
}
const
ctx
=
instance
.
ctx
;
MP_METHODS
.
forEach
((
method
)
=>
{
ctx
[
method
]
=
function
(...
args
)
{
...
...
@@ -445,53 +395,6 @@ function callHook(name, args) {
}
const
hooks
=
this
.
$
[
name
];
return
hooks
&&
invokeArrayFns
(
hooks
,
args
);
}
const
center
=
{};
const
parents
=
{};
function
initScopedSlotsParams
(
instance
)
{
const
ctx
=
instance
.
ctx
;
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
)
{
const
has
=
center
[
vueId
];
if
(
!
has
)
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
return
has
;
};
ctx
.
$getScopedSlotsParams
=
function
(
vueId
,
name
,
key
)
{
const
data
=
center
[
vueId
];
if
(
data
)
{
const
object
=
data
[
name
]
||
{};
return
key
?
object
[
key
]
:
object
;
}
else
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
};
ctx
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueIds
=
instance
.
attrs
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{});
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
;
const
vueId
=
propsData
&&
propsData
.
vueId
;
if
(
vueId
)
{
delete
center
[
vueId
];
delete
parents
[
vueId
];
}
},
instance
);
}
const
PAGE_HOOKS
=
[
...
...
@@ -612,6 +515,50 @@ function initLocale(appVm) {
});
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
const
PROP_TYPES
=
[
String
,
Number
,
Boolean
,
Object
,
Array
,
null
];
function
parsePropType
(
key
,
type
,
defaultValue
)
{
// [String]=>String
...
...
@@ -628,7 +575,7 @@ function initDefaultProps(isBehavior = false) {
value
:
''
,
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
newVal
)
{
...
...
@@ -758,252 +705,6 @@ function initBehaviors(vueOptions, initBehavior) {
return
behaviors
;
}
function
getExtraValue
(
instance
,
dataPathsArray
)
{
let
context
=
instance
;
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
];
const
value
=
dataPathArray
[
2
];
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
];
const
valuePath
=
dataPathArray
[
3
];
let
vFor
;
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
;
}
else
if
(
!
dataPath
)
{
vFor
=
context
;
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
);
}
else
{
vFor
=
getTarget
(
context
,
dataPath
);
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
;
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
];
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
;
});
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
;
});
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
);
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
);
}
}
});
return
context
;
}
function
processEventExtra
(
instance
,
extra
,
event
)
{
const
extraObj
=
{};
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
;
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
;
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
;
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
];
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
));
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
);
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
);
}
});
}
return
extraObj
;
}
function
getObjByArray
(
arr
)
{
const
obj
=
{};
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
];
obj
[
element
[
0
]]
=
element
[
1
];
}
return
obj
;
}
function
processEventArgs
(
instance
,
event
,
args
=
[],
extra
=
[],
isCustom
,
methodName
)
{
let
isCustomMPEvent
=
false
;
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
;
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
];
}
return
event
.
detail
.
__args__
||
event
.
detail
;
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
);
const
ret
=
[];
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
(
event
.
target
.
value
);
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
]);
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
);
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
));
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
]);
}
else
{
ret
.
push
(
arg
);
}
}
});
return
ret
;
}
function
wrapper
(
event
)
{
event
.
stopPropagation
=
NOOP
;
event
.
preventDefault
=
NOOP
;
event
.
target
=
event
.
target
||
{};
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
return
event
;
}
const
ONCE
=
'
~
'
;
const
CUSTOM
=
'
^
'
;
function
matchEventType
(
eventType
,
optType
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
)));
}
function
handleEvent
(
event
)
{
event
=
wrapper
(
event
);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
;
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
]);
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
;
const
ret
=
[];
eventOpts
.
forEach
((
eventOpt
)
=>
{
let
type
=
eventOpt
[
0
];
const
eventsArray
=
eventOpt
[
1
];
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
;
type
=
isCustom
?
type
.
slice
(
1
)
:
type
;
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
;
type
=
isOnce
?
type
.
slice
(
1
)
:
type
;
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
)
=>
{
const
methodName
=
eventArray
[
0
];
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
;
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
;
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
));
return
;
}
const
handler
=
handlerCtx
[
methodName
];
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
);
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
;
}
handler
.
once
=
true
;
}
let
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
);
params
=
Array
.
isArray
(
params
)
?
params
:
[];
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()))
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
]);
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
));
}
});
}
});
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
];
}
}
let
$createComponentFn
;
let
$destroyComponentFn
;
function
$createComponent
(
initialVNode
,
options
)
{
...
...
@@ -1324,7 +1025,6 @@ function createPage$1(vueOptions) {
},
},
__r
:
handleRef
,
__e
:
handleEvent
,
__l
:
handleLink
,
};
if
(
__VUE_OPTIONS_API__
)
{
...
...
@@ -1346,7 +1046,8 @@ function initComponentProps(rawProps) {
onVueInit
:
function
()
{
},
};
Object
.
keys
(
properties
).
forEach
((
key
)
=>
{
if
(
key
!==
'
vueSlots
'
)
{
// vueSlots
if
(
key
!==
'
vS
'
)
{
props
[
key
]
=
properties
[
key
].
value
;
}
});
...
...
@@ -1409,7 +1110,6 @@ function createComponent$1(vueOptions) {
},
methods
:
{
__r
:
handleRef
,
__e
:
handleEvent
,
__l
:
handleLink
,
triggerEvent
,
},
...
...
packages/uni-mp-alipay/src/runtime/createComponent.ts
浏览文件 @
ae7ec06d
...
...
@@ -3,7 +3,6 @@ import {
initProps
,
initBehaviors
,
initData
,
handleEvent
,
$destroyComponent
,
initVueIds
,
initWxsCallMethods
,
...
...
@@ -37,7 +36,8 @@ function initComponentProps(rawProps: Record<string, any>) {
onVueInit
:
function
()
{},
}
Object
.
keys
(
properties
).
forEach
((
key
)
=>
{
if
(
key
!==
'
vueSlots
'
)
{
// vueSlots
if
(
key
!==
'
vS
'
)
{
props
[
key
]
=
properties
[
key
].
value
}
})
...
...
@@ -104,7 +104,6 @@ export function createComponent(vueOptions: ComponentOptions) {
},
methods
:
{
__r
:
handleRef
,
__e
:
handleEvent
,
__l
:
handleLink
,
triggerEvent
,
},
...
...
packages/uni-mp-alipay/src/runtime/createPage.ts
浏览文件 @
ae7ec06d
...
...
@@ -2,7 +2,6 @@ import { ComponentOptions } from 'vue'
import
{
PAGE_HOOKS
,
handleEvent
,
initData
,
initHooks
,
initUnknownHooks
,
...
...
@@ -59,7 +58,6 @@ export function createPage(vueOptions: ComponentOptions) {
},
},
__r
:
handleRef
,
__e
:
handleEvent
,
__l
:
handleLink
,
}
if
(
__VUE_OPTIONS_API__
)
{
...
...
packages/uni-mp-baidu/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
import
{
isPlainObject
,
hasOwn
,
isArray
,
extend
,
hyphenate
,
isObject
,
toNumber
,
isFunction
,
NOOP
,
camelize
}
from
'
@vue/shared
'
;
import
{
onUnmounted
,
injectHook
,
ref
}
from
'
vue
'
;
import
{
isPlainObject
,
extend
,
hyphenate
,
isObject
,
isArray
,
hasOwn
,
toNumber
,
isFunction
,
camelize
}
from
'
@vue/shared
'
;
import
{
injectHook
,
ref
}
from
'
vue
'
;
const
encode
=
encodeURIComponent
;
function
stringifyQuery
(
obj
,
encodeStr
=
encode
)
{
...
...
@@ -21,6 +21,18 @@ function stringifyQuery(obj, encodeStr = encode) {
return
res
?
`?
${
res
}
`
:
''
;
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
cache
(
fn
)
{
const
cache
=
Object
.
create
(
null
);
return
(
str
)
=>
{
...
...
@@ -129,102 +141,8 @@ function getEventChannel(id) {
return
eventChannelStack
.
shift
();
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
function
getTarget
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
let
key
=
parts
[
0
];
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
));
}
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
getValue
(
dataPath
,
target
)
{
return
get
Target
(
target
||
this
,
dataPath
);
return
get
DataByPath
(
target
||
this
,
dataPath
);
}
function
getClass
(
dynamicClass
,
staticClass
)
{
return
renderClass
(
staticClass
,
dynamicClass
);
...
...
@@ -420,9 +338,6 @@ function initBaseInstance(instance, options) {
}
function
initComponentInstance
(
instance
,
options
)
{
initBaseInstance
(
instance
,
options
);
{
initScopedSlotsParams
(
instance
);
}
const
ctx
=
instance
.
ctx
;
MP_METHODS
.
forEach
((
method
)
=>
{
ctx
[
method
]
=
function
(...
args
)
{
...
...
@@ -469,53 +384,6 @@ function callHook(name, args) {
}
const
hooks
=
this
.
$
[
name
];
return
hooks
&&
invokeArrayFns
(
hooks
,
args
);
}
const
center
=
{};
const
parents
=
{};
function
initScopedSlotsParams
(
instance
)
{
const
ctx
=
instance
.
ctx
;
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
)
{
const
has
=
center
[
vueId
];
if
(
!
has
)
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
return
has
;
};
ctx
.
$getScopedSlotsParams
=
function
(
vueId
,
name
,
key
)
{
const
data
=
center
[
vueId
];
if
(
data
)
{
const
object
=
data
[
name
]
||
{};
return
key
?
object
[
key
]
:
object
;
}
else
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
};
ctx
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueIds
=
instance
.
attrs
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{});
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
;
const
vueId
=
propsData
&&
propsData
.
vueId
;
if
(
vueId
)
{
delete
center
[
vueId
];
delete
parents
[
vueId
];
}
},
instance
);
}
const
PAGE_HOOKS
=
[
...
...
@@ -633,6 +501,85 @@ function initLocale(appVm) {
});
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
const
PROP_TYPES
=
[
String
,
Number
,
Boolean
,
Object
,
Array
,
null
];
function
createObserver
(
name
)
{
return
function
observer
(
newVal
)
{
...
...
@@ -667,7 +614,7 @@ function initDefaultProps(isBehavior = false) {
value
:
''
,
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
newVal
)
{
...
...
@@ -800,260 +747,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) {
componentOptions
.
behaviors
=
initBehaviors
(
vueOptions
,
initBehavior
);
}
function
getExtraValue
(
instance
,
dataPathsArray
)
{
let
context
=
instance
;
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
];
const
value
=
dataPathArray
[
2
];
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
];
const
valuePath
=
dataPathArray
[
3
];
let
vFor
;
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
;
}
else
if
(
!
dataPath
)
{
vFor
=
context
;
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
);
}
else
{
vFor
=
getTarget
(
context
,
dataPath
);
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
;
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
];
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
;
});
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
;
});
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
);
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
);
}
}
});
return
context
;
}
function
processEventExtra
(
instance
,
extra
,
event
)
{
const
extraObj
=
{};
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
;
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
;
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
;
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
];
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
));
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
);
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
);
}
});
}
return
extraObj
;
}
function
getObjByArray
(
arr
)
{
const
obj
=
{};
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
];
obj
[
element
[
0
]]
=
element
[
1
];
}
return
obj
;
}
function
processEventArgs
(
instance
,
event
,
args
=
[],
extra
=
[],
isCustom
,
methodName
)
{
let
isCustomMPEvent
=
false
;
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
;
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
];
}
return
event
.
detail
.
__args__
||
event
.
detail
;
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
);
const
ret
=
[];
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
(
event
.
target
.
value
);
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
]);
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
);
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
));
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
]);
}
else
{
ret
.
push
(
arg
);
}
}
});
return
ret
;
}
function
wrapper
(
event
)
{
event
.
stopPropagation
=
NOOP
;
event
.
preventDefault
=
NOOP
;
event
.
target
=
event
.
target
||
{};
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
{
// mp-baidu,checked=>value
if
(
isPlainObject
(
event
.
detail
)
&&
hasOwn
(
event
.
detail
,
'
checked
'
)
&&
!
hasOwn
(
event
.
detail
,
'
value
'
))
{
event
.
detail
.
value
=
event
.
detail
.
checked
;
}
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
return
event
;
}
const
ONCE
=
'
~
'
;
const
CUSTOM
=
'
^
'
;
function
matchEventType
(
eventType
,
optType
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
)));
}
function
handleEvent
(
event
)
{
event
=
wrapper
(
event
);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
;
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
]);
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
;
const
ret
=
[];
eventOpts
.
forEach
((
eventOpt
)
=>
{
let
type
=
eventOpt
[
0
];
const
eventsArray
=
eventOpt
[
1
];
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
;
type
=
isCustom
?
type
.
slice
(
1
)
:
type
;
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
;
type
=
isOnce
?
type
.
slice
(
1
)
:
type
;
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
)
=>
{
const
methodName
=
eventArray
[
0
];
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
;
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
;
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
));
return
;
}
const
handler
=
handlerCtx
[
methodName
];
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
);
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
;
}
handler
.
once
=
true
;
}
let
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
);
params
=
Array
.
isArray
(
params
)
?
params
:
[];
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()))
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
]);
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
));
}
});
}
});
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
];
}
}
function
parseComponent
(
vueOptions
,
{
parse
,
mocks
,
isPage
,
initRelation
,
handleLink
,
initLifetimes
,
})
{
vueOptions
=
vueOptions
.
default
||
vueOptions
;
const
options
=
{
...
...
@@ -1079,7 +772,6 @@ function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handle
},
methods
:
{
__l
:
handleLink
,
__e
:
handleEvent
,
},
};
if
(
__VUE_OPTIONS_API__
)
{
...
...
@@ -1248,7 +940,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
},
{
mpType
:
isPage
(
mpInstance
)
?
'
page
'
:
'
component
'
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
,
options
)
{
initRefs
(
instance
,
mpInstance
);
...
...
packages/uni-mp-compiler/__tests__/component.spec.ts
浏览文件 @
ae7ec06d
...
...
@@ -17,7 +17,7 @@ describe('compiler: transform component', () => {
test
(
'
component + component
'
,
()
=>
{
assert
(
`<custom><custom1/></custom>`
,
`<custom
vue-slots="{{['default']}}" class="v-r
" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 class="v-r" v-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"/></custom>`
,
`<custom
class="v-r" v-s="{{['default']}}
" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 class="v-r" v-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"/></custom>`
,
`(_ctx, _cache) => {
return {}
}`
,
...
...
@@ -29,7 +29,7 @@ describe('compiler: transform component', () => {
test
(
'
component + component + component
'
,
()
=>
{
assert
(
`<custom><custom1><custom2/><custom2/></custom1></custom>`
,
`<custom
vue-slots="{{['default']}}" class="v-r" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 vue-slots="{{['default']}}" class="v-r
" v-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"><custom2 class="v-r" v-i="2a9ec0b0-2,2a9ec0b0-1" bind:__l="__l"/><custom2 class="v-r" v-i="2a9ec0b0-3,2a9ec0b0-1" bind:__l="__l"/></custom1></custom>`
,
`<custom
class="v-r" v-s="{{['default']}}" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 class="v-r" v-s="{{['default']}}
" v-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"><custom2 class="v-r" v-i="2a9ec0b0-2,2a9ec0b0-1" bind:__l="__l"/><custom2 class="v-r" v-i="2a9ec0b0-3,2a9ec0b0-1" bind:__l="__l"/></custom1></custom>`
,
`(_ctx, _cache) => {
return {}
}`
,
...
...
@@ -63,7 +63,7 @@ describe('compiler: transform component', () => {
test
(
'
component + component with v-for
'
,
()
=>
{
assert
(
`<custom><custom1 v-for="item in items"/></custom>`
,
`<custom
vue-slots="{{['default']}}" class="v-r
" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 wx:for="{{a}}" wx:for-item="item" class="v-r-i-f" v-i="{{item.a}}" bind:__l="__l"/></custom>`
,
`<custom
class="v-r" v-s="{{['default']}}
" v-i="2a9ec0b0-0" bind:__l="__l"><custom1 wx:for="{{a}}" wx:for-item="item" class="v-r-i-f" v-i="{{item.a}}" bind:__l="__l"/></custom>`
,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }; }) }
}`
,
...
...
@@ -75,7 +75,7 @@ describe('compiler: transform component', () => {
test
(
'
component with v-for + component
'
,
()
=>
{
assert
(
`<custom v-for="item in items"><custom1/></custom>`
,
`<custom wx:for="{{a}}" wx:for-item="item"
vue-slots="{{['default']}}" class="v-r-i-f
" v-i="{{item.b}}" bind:__l="__l"><custom1 class="v-r-i-f" v-i="{{item.a}}" bind:__l="__l"/></custom>`
,
`<custom wx:for="{{a}}" wx:for-item="item"
class="v-r-i-f" v-s="{{['default']}}
" v-i="{{item.b}}" bind:__l="__l"><custom1 class="v-r-i-f" v-i="{{item.a}}" bind:__l="__l"/></custom>`
,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + ('2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}`
,
...
...
@@ -87,7 +87,7 @@ describe('compiler: transform component', () => {
test
(
'
component with v-for + component with v-for
'
,
()
=>
{
assert
(
`<custom v-for="item in items"><custom1 v-for="item1 in item.items"/></custom>`
,
`<custom wx:for="{{a}}" wx:for-item="item"
vue-slots="{{['default']}}" class="v-r-i-f
" v-i="{{item.b}}" bind:__l="__l"><custom1 wx:for="{{item.a}}" wx:for-item="item1" class="v-r-i-f" v-i="{{item1.a}}" bind:__l="__l"/></custom>`
,
`<custom wx:for="{{a}}" wx:for-item="item"
class="v-r-i-f" v-s="{{['default']}}
" v-i="{{item.b}}" bind:__l="__l"><custom1 wx:for="{{item.a}}" wx:for-item="item1" class="v-r-i-f" v-i="{{item1.a}}" bind:__l="__l"/></custom>`
,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.items, (item1, k1, i1) => { return { a: '2a9ec0b0-1' + '-' + i0 + '-' + i1 + ',' + ('2a9ec0b0-0' + '-' + i0) }; }), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}`
,
...
...
packages/uni-mp-compiler/__tests__/scopedSlot.spec.ts
0 → 100644
浏览文件 @
ae7ec06d
import
{
assert
}
from
'
./testUtils
'
describe
(
'
compiler: transform scoped slots
'
,
()
=>
{
test
(
'
basic
'
,
()
=>
{
assert
(
`<view><slot :item="item" :index="index"/></view>`
,
`<view><slot/></view>`
,
`(_ctx, _cache) => {
return { a: _r("default", { item: _ctx.item, index: _ctx.index }) }
}`
)
})
test
(
'
named slots
'
,
()
=>
{
assert
(
`<view><slot name="header" :item="item" :index="index"/></view>`
,
`<view><slot name="header"/></view>`
,
`(_ctx, _cache) => {
return { a: _r("header", { item: _ctx.item, index: _ctx.index }) }
}`
)
})
test
(
'
named slots + v-if
'
,
()
=>
{
assert
(
`<view><slot v-if="ok" name="header" :item="item" :index="index"/></view>`
,
`<view><slot wx:if="{{a}}" name="header"/></view>`
,
`(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? { b: _r("header", { item: _ctx.item, index: _ctx.index }) } : {})
}`
)
})
})
packages/uni-mp-compiler/__tests__/vSlot.spec.ts
浏览文件 @
ae7ec06d
...
...
@@ -4,14 +4,14 @@ describe('compiler: transform v-slot', () => {
test
(
'
default slot
'
,
()
=>
{
assert
(
`<custom><template v-slot/></custom>`
,
`<custom
vue-slots="{{['default']}}" class="v-r
" v-i="2a9ec0b0-0"><view /></custom>`
,
`<custom
class="v-r" v-s="{{['default']}}
" v-i="2a9ec0b0-0"><view /></custom>`
,
`(_ctx, _cache) => {
return {}
}`
)
assert
(
`<custom>test</custom>`
,
`<custom
vue-slots="{{['default']}}" class="v-r
" v-i="2a9ec0b0-0">test</custom>`
,
`<custom
class="v-r" v-s="{{['default']}}
" v-i="2a9ec0b0-0">test</custom>`
,
`(_ctx, _cache) => {
return {}
}`
...
...
@@ -20,19 +20,59 @@ describe('compiler: transform v-slot', () => {
test
(
'
named slots
'
,
()
=>
{
assert
(
`<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`
,
`<custom
vue-slots="{{['header','default','footer']}}" class="v-r
" v-i="2a9ec0b0-0"><view slot="header"/><view slot="default"/><view slot="footer"/></custom>`
,
`<custom
class="v-r" v-s="{{['header','default','footer']}}
" v-i="2a9ec0b0-0"><view slot="header"/><view slot="default"/><view slot="footer"/></custom>`
,
`(_ctx, _cache) => {
return {}
}`
)
})
// TODO 还未实现scoped slot
test
(
'
scoped slots
'
,
()
=>
{
assert
(
`<custom><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`
,
`<custom vue-slots="{{['default']}}" class="v-r" v-i="2a9ec0b0-0"><view slot="default"><view>{{a}}</view></view></custom>`
,
`<custom class="v-r" v-s="{{['default']}}" v-i="2a9ec0b0-0"><view slot="default"><block wx:for="{{a}}" wx:for-item="slotProps" wx:key="b"><view>{{slotProps.a}}</view></block></view></custom>`
,
`(_ctx, _cache) => {
return { a: _w((slotProps, s0, i0) => { return { a: _t(slotProps.item), b: s0 }; }, { name: 'default', vueId: '2a9ec0b0-0' }) }
}`
)
})
test
(
'
scoped slots + scoped slots
'
,
()
=>
{
assert
(
`<custom><template v-slot:default="slotProps"><custom1><template v-slot:default="slotProps1">{{ slotProps.item }}{{ slotProps1.item }}</template></custom1></template></custom>`
,
`<custom class="v-r" v-s="{{['default']}}" v-i="2a9ec0b0-0"><view slot="default"><block wx:for="{{a}}" wx:for-item="slotProps" wx:key="d"><custom1 class="v-r" v-s="{{['default']}}" v-i="{{slotProps.c}}"><view slot="default"><block wx:for="{{slotProps.a}}" wx:for-item="slotProps1" wx:key="b">{{slotProps.b}}{{slotProps1.a}}</block></view></custom1></block></view></custom>`
,
`(_ctx, _cache) => {
return { a: _w((slotProps, s0, i0) => { return { a: _w((slotProps1, s1, i1) => { return { a: _t(slotProps1.item), b: s1 }; }, { name: 'default', vueId: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }), b: _t(slotProps.item), c: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0', d: s0 }; }, { name: 'default', vueId: '2a9ec0b0-0' }) }
}`
)
})
test
(
'
v-if + scoped slots
'
,
()
=>
{
assert
(
`<custom><template v-if="ok" v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`
,
`<custom class="v-r" v-s="{{['default']}}" v-i="2a9ec0b0-0"><view wx:if="{{a}}" slot="default"><block wx:for="{{b}}" wx:for-item="slotProps" wx:key="b"><view>{{slotProps.a}}</view></block></view></custom>`
,
`(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? { b: _w((slotProps, s0, i0) => { return { a: _t(slotProps.item), b: s0 }; }, { name: 'default', vueId: '2a9ec0b0-0' }) } : {})
}`
)
})
test
(
'
v-for + scoped slots
'
,
()
=>
{
assert
(
`<custom v-for="item in items"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`
,
`<custom wx:for="{{a}}" wx:for-item="item" class="v-r-i-f" v-s="{{['default']}}" v-i="{{item.b}}"><view slot="default"><block wx:for="{{item.a}}" wx:for-item="slotProps" wx:key="b"><view>{{slotProps.a}}</view></block></view></custom>`
,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _w((slotProps, s1, i1) => { return { a: _t(slotProps.item), b: s1 }; }, { name: 'default', vueId: '2a9ec0b0-0' + '-' + i0 }), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}`
)
})
test
(
'
v-for + v-for + scoped slots
'
,
()
=>
{
assert
(
`<view v-for="item in items"><custom v-for="item1 in item.list" :item="item1"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom></view>`
,
`<view wx:for="{{a}}" wx:for-item="item"><custom wx:for="{{item.a}}" wx:for-item="item1" class="v-r-i-f" v-s="{{['default']}}" item="{{item1.b}}" v-i="{{item1.c}}"><view slot="default"><block wx:for="{{item1.a}}" wx:for-item="slotProps" wx:key="b"><view>{{slotProps.a}}</view></block></view></custom></view>`
,
`(_ctx, _cache) => {
return { a: _
t(_ctx.slotProps.item), b: slotProps
}
return { a: _
f(_ctx.items, (item, k0, i0) => { return { a: _f(item.list, (item1, k1, i1) => { return { a: _w((slotProps, s2, i2) => { return { a: _t(slotProps.item), b: s2 }; }, { name: 'default', vueId: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }), b: item1, c: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }; }) }; })
}
}`
)
})
...
...
packages/uni-mp-compiler/src/ast.ts
浏览文件 @
ae7ec06d
...
...
@@ -2,8 +2,6 @@ import { isString } from '@vue/shared'
import
{
parseExpression
}
from
'
@babel/parser
'
import
{
identifier
,
blockStatement
,
callExpression
,
objectProperty
,
objectExpression
,
spreadElement
,
...
...
@@ -12,14 +10,10 @@ import {
Expression
,
SpreadElement
,
ConditionalExpression
,
arrowFunctionExpression
,
Identifier
,
returnStatement
,
conditionalExpression
,
NumericLiteral
,
isNumericLiteral
,
Pattern
,
RestElement
,
ArrowFunctionExpression
,
stringLiteral
,
StringLiteral
,
...
...
@@ -41,10 +35,9 @@ import {
locStub
,
NodeTypes
,
}
from
'
@vue/compiler-core
'
import
{
CodegenScope
,
CodegenV
ForScope
,
CodegenV
IfScope
}
from
'
./options
'
import
{
CodegenScope
,
CodegenVIfScope
}
from
'
./options
'
import
{
TransformContext
}
from
'
./transform
'
import
{
genExpr
}
from
'
./codegen
'
import
{
V_FOR
}
from
'
./runtimeHelpers
'
export
function
createIdentifier
(
name
:
string
)
{
return
identifier
(
name
)
...
...
@@ -91,22 +84,6 @@ export function createVIfSpreadElement(vIfScope: CodegenVIfScope) {
// return arrayExpression(elements)
// }
export
function
createVForCallExpression
(
vForScope
:
CodegenVForScope
,
context
:
TransformContext
)
{
// let sourceExpr: Expression = vForScope.sourceExpr!
// if (isNumericLiteral(sourceExpr)) {
// sourceExpr = numericLiteralToArrayExpr((sourceExpr as NumericLiteral).value)
// }
return
callExpression
(
identifier
(
context
.
helperString
(
V_FOR
)),
[
vForScope
.
sourceExpr
!
,
createVForArrowFunctionExpression
(
vForScope
),
])
}
type
FunctionParam
=
Identifier
|
Pattern
|
RestElement
export
function
parseExpr
(
code
:
string
|
ExpressionNode
,
context
:
TransformContext
,
...
...
@@ -141,32 +118,6 @@ export function parseParam(
return
expr
}
function
createVForArrowFunctionExpression
({
valueExpr
,
keyExpr
,
indexExpr
,
properties
,
}:
CodegenVForScope
)
{
const
params
:
FunctionParam
[]
=
[]
if
(
valueExpr
)
{
params
.
push
(
valueExpr
)
}
else
if
(
keyExpr
||
indexExpr
)
{
params
.
push
(
identifier
(
'
_
'
))
}
if
(
keyExpr
)
{
params
.
push
(
keyExpr
)
}
else
if
(
indexExpr
)
{
params
.
push
(
identifier
(
'
__
'
))
}
if
(
indexExpr
)
{
params
.
push
(
indexExpr
)
}
return
arrowFunctionExpression
(
params
,
blockStatement
([
returnStatement
(
objectExpression
(
properties
))])
)
}
export
function
isUndefined
(
expr
:
Expression
)
{
return
isIdentifier
(
expr
)
&&
expr
.
name
===
'
undefined
'
}
...
...
packages/uni-mp-compiler/src/compile.ts
浏览文件 @
ae7ec06d
...
...
@@ -14,6 +14,7 @@ import { transformOn } from './transforms/vOn'
import
{
transformElement
}
from
'
./transforms/transformElement
'
import
{
transformBind
}
from
'
./transforms/vBind
'
import
{
transformComponent
}
from
'
./transforms/transformComponent
'
import
{
transformSlot
}
from
'
./transforms/vSlot
'
export
type
TransformPreset
=
[
NodeTransform
[],
...
...
@@ -27,7 +28,8 @@ export function getBaseTransformPreset({
prefixIdentifiers
:
boolean
skipTransformIdentifier
:
boolean
}):
TransformPreset
{
const
nodeTransforms
=
[
transformIf
,
transformFor
]
// order is important
const
nodeTransforms
=
[
transformIf
,
transformFor
,
transformSlot
]
if
(
!
skipTransformIdentifier
)
{
nodeTransforms
.
push
(
transformIdentifier
)
}
...
...
@@ -49,7 +51,6 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
prefixIdentifiers
,
skipTransformIdentifier
:
options
.
skipTransformIdentifier
===
true
,
})
options
.
hashId
=
genHashId
(
options
)
if
(
options
.
filename
)
{
...
...
packages/uni-mp-compiler/src/runtimeHelpers.ts
浏览文件 @
ae7ec06d
...
...
@@ -5,6 +5,8 @@ export const V_FOR = Symbol(`vFor`)
export
const
EXTEND
=
Symbol
(
`extend`
)
export
const
CAMELIZE
=
Symbol
(
`camelize`
)
export
const
HYPHENATE
=
Symbol
(
`hyphenate`
)
export
const
RENDER_SLOT
=
Symbol
(
`renderSlot`
)
export
const
WITH_SCOPED_SLOT
=
Symbol
(
`withScopedSlot`
)
export
const
STRINGIFY_STYLE
=
Symbol
(
`stringifyStyle`
)
export
const
NORMALIZE_CLASS
=
Symbol
(
`normalizeClass`
)
export
const
TO_DISPLAY_STRING
=
Symbol
(
`toDisplayString`
)
...
...
@@ -14,6 +16,8 @@ registerRuntimeHelpers({
[
EXTEND
]:
'
e
'
,
[
CAMELIZE
]:
'
c
'
,
[
HYPHENATE
]:
'
h
'
,
[
RENDER_SLOT
]:
'
r
'
,
[
WITH_SCOPED_SLOT
]:
'
w
'
,
[
STRINGIFY_STYLE
]:
'
s
'
,
[
NORMALIZE_CLASS
]:
'
n
'
,
[
TO_DISPLAY_STRING
]:
`t`
,
...
...
packages/uni-mp-compiler/src/template/codegen.ts
浏览文件 @
ae7ec06d
...
...
@@ -19,7 +19,7 @@ import { TemplateCodegenOptions } from '../options'
import
{
genExpr
}
from
'
../codegen
'
import
{
isForElementNode
,
VForOptions
}
from
'
../transforms/vFor
'
import
{
IfElementNode
,
isIfElementNode
}
from
'
../transforms/vIf
'
import
{
createBindDirectiveNode
}
from
'
../as
t
'
import
{
findSlotName
}
from
'
../transforms/vSlo
t
'
interface
TemplateCodegenContext
{
code
:
string
directive
:
string
...
...
@@ -95,7 +95,7 @@ function genVElse({ push, directive }: TemplateCodegenContext) {
}
function
genVFor
(
{
sourceAlias
,
valueAlias
,
keyAlias
}:
VForOptions
,
{
sourceAlias
,
valueAlias
}:
VForOptions
,
node
:
ElementNode
,
{
push
,
directive
}:
TemplateCodegenContext
)
{
...
...
@@ -112,6 +112,8 @@ function genVFor(
}
function
genSlot
(
node
:
SlotOutletNode
,
context
:
TemplateCodegenContext
)
{
// 移除掉所有非name属性,即移除作用域插槽的绑定指令
node
.
props
=
node
.
props
.
filter
((
prop
)
=>
prop
.
name
===
'
name
'
)
if
(
!
node
.
children
.
length
)
{
return
genElement
(
node
,
context
)
}
...
...
@@ -139,24 +141,11 @@ function genSlot(node: SlotOutletNode, context: TemplateCodegenContext) {
push
(
`</block>`
)
}
function
findSlotName
(
node
:
ElementNode
)
{
function
genTemplate
(
node
:
TemplateNode
,
context
:
TemplateCodegenContext
)
{
const
slotProp
=
node
.
props
.
find
(
(
prop
)
=>
prop
.
type
===
NodeTypes
.
DIRECTIVE
&&
prop
.
name
===
'
slot
'
)
as
DirectiveNode
|
undefined
if
(
slotProp
)
{
const
{
arg
}
=
slotProp
if
(
!
arg
)
{
return
'
default
'
}
if
(
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
isStatic
)
{
return
arg
.
content
}
}
}
function
genTemplate
(
node
:
TemplateNode
,
context
:
TemplateCodegenContext
)
{
const
slotName
=
findSlotName
(
node
)
if
(
slotName
)
{
if
(
slotProp
&&
findSlotName
(
slotProp
))
{
/**
* 仅百度、字节支持使用 block 作为命名插槽根节点
* 此处为了统一仅默认替换为view
...
...
@@ -173,23 +162,6 @@ function genTemplate(node: TemplateNode, context: TemplateCodegenContext) {
}
function
genComponent
(
node
:
ComponentNode
,
context
:
TemplateCodegenContext
)
{
const
slots
=
new
Set
<
string
>
()
if
(
!
node
.
children
.
length
)
{
return
genElement
(
node
,
context
)
}
node
.
children
.
forEach
((
child
)
=>
{
if
(
child
.
type
===
NodeTypes
.
ELEMENT
)
{
slots
.
add
(
findSlotName
(
child
)
||
'
default
'
)
}
else
if
(
child
.
type
===
NodeTypes
.
TEXT
)
{
slots
.
add
(
'
default
'
)
}
})
node
.
props
.
unshift
(
createBindDirectiveNode
(
'
vue-slots
'
,
`[
${[...
slots
].
map
((
name
)
=>
`'
${
name
}
'`
).
join
(
'
,
'
)}
]`
)
)
return
genElement
(
node
,
context
)
}
...
...
packages/uni-mp-compiler/src/transform.ts
浏览文件 @
ae7ec06d
...
...
@@ -39,8 +39,6 @@ import {
CompilerError
,
helperNameMap
,
ExpressionNode
,
ElementTypes
,
isVSlot
,
JSChildNode
,
CacheExpression
,
locStub
,
...
...
@@ -478,9 +476,9 @@ export function createStructuralDirectiveTransform(
const
{
props
}
=
node
// structural directive transforms are not concerned with slots
// as they are handled separately in vSlot.ts
if
(
node
.
tagType
===
ElementTypes
.
TEMPLATE
&&
props
.
some
(
isVSlot
))
{
return
}
//
if (node.tagType === ElementTypes.TEMPLATE && props.some(isVSlot)) {
//
return
//
}
const
exitFns
=
[]
for
(
let
i
=
0
;
i
<
props
.
length
;
i
++
)
{
const
prop
=
props
[
i
]
...
...
@@ -488,8 +486,8 @@ export function createStructuralDirectiveTransform(
// structural directives are removed to avoid infinite recursion
// also we remove them *before* applying so that it can further
// traverse itself in case it moves the node around
//
props.splice(i, 1)
//
i--
props
.
splice
(
i
,
1
)
i
--
const
onExit
=
fn
(
node
,
prop
,
context
)
if
(
onExit
)
exitFns
.
push
(
onExit
)
}
...
...
packages/uni-mp-compiler/src/transforms/transformComponent.ts
浏览文件 @
ae7ec06d
import
{
ComponentNode
,
ElementTypes
,
isCoreComponent
,
NodeTypes
,
}
from
'
@vue/compiler-core
'
import
{
isComponentTag
}
from
'
@dcloudio/uni-shared
'
import
{
ComponentNode
}
from
'
@vue/compiler-core
'
import
{
isVForScope
,
NodeTransform
,
TransformContext
}
from
'
../transform
'
import
{
createAttributeNode
,
createBindDirectiveNode
}
from
'
../ast
'
import
{
addStaticClass
}
from
'
./transformElement
'
import
{
ATTR_VUE_ID
,
CLASS_VUE_REF
,
CLASS_VUE_REF_IN_FOR
,
isUserComponent
,
}
from
'
./utils
'
import
{
CodegenScope
}
from
'
../options
'
import
{
isScopedSlotVFor
}
from
'
./vSlot
'
export
const
transformComponent
:
NodeTransform
=
(
node
,
context
)
=>
{
const
isComponent
=
node
.
type
===
NodeTypes
.
ELEMENT
&&
node
.
tagType
===
ElementTypes
.
COMPONENT
&&
!
isComponentTag
(
node
.
tag
)
&&
!
isCoreComponent
(
node
.
tag
)
&&
!
context
.
isBuiltInComponent
(
node
.
tag
)
if
(
!
isComponent
)
{
if
(
!
isUserComponent
(
node
,
context
))
{
return
}
addVueRef
(
node
,
context
)
...
...
@@ -60,9 +55,9 @@ function addVueId(node: ComponentNode, context: TransformContext) {
}
}
if
(
value
.
includes
(
'
+
'
))
{
return
node
.
props
.
push
(
createBindDirectiveNode
(
'
v-i
'
,
value
))
return
node
.
props
.
push
(
createBindDirectiveNode
(
ATTR_VUE_ID
,
value
))
}
return
node
.
props
.
push
(
createAttributeNode
(
'
v-i
'
,
value
))
return
node
.
props
.
push
(
createAttributeNode
(
ATTR_VUE_ID
,
value
))
}
function
addVueRef
(
node
:
ComponentNode
,
context
:
TransformContext
)
{
...
...
@@ -70,6 +65,17 @@ function addVueRef(node: ComponentNode, context: TransformContext) {
node
,
// vue-ref-in-for
// vue-ref
context
.
scopes
.
vFor
?
'
v-r-i-f
'
:
'
v-r
'
isInVFor
(
context
.
currentScope
)
?
CLASS_VUE_REF_IN_FOR
:
CLASS_VUE_REF
)
}
function
isInVFor
(
scope
:
CodegenScope
)
{
let
parent
:
CodegenScope
|
null
=
scope
while
(
parent
)
{
if
(
isVForScope
(
parent
)
&&
!
isScopedSlotVFor
(
parent
))
{
return
true
}
parent
=
parent
.
parent
}
return
false
}
packages/uni-mp-compiler/src/transforms/transformElement.ts
浏览文件 @
ae7ec06d
...
...
@@ -191,8 +191,12 @@ function resolveSetupReference(name: string, context: TransformContext) {
}
}
function
processProps
(
node
:
ElementNode
,
context
:
TransformContext
)
{
const
{
tag
,
props
}
=
node
export
function
processProps
(
node
:
ElementNode
,
context
:
TransformContext
,
props
:
ElementNode
[
'
props
'
]
=
node
.
props
)
{
const
{
tag
}
=
node
const
isComponent
=
node
.
tagType
===
ElementTypes
.
COMPONENT
for
(
let
i
=
0
;
i
<
props
.
length
;
i
++
)
{
...
...
@@ -292,5 +296,7 @@ function processVModel(node: ElementNode, context: TransformContext) {
i
--
}
}
props
.
push
(...
dirs
)
if
(
dirs
.
length
)
{
props
.
push
(...
dirs
)
}
}
packages/uni-mp-compiler/src/transforms/transformIdentifier.ts
浏览文件 @
ae7ec06d
import
{
createCompoundExpression
,
DirectiveNode
,
isSlotOutlet
,
NodeTypes
,
}
from
'
@vue/compiler-core
'
import
{
NodeTransform
}
from
'
../transform
'
import
{
isForElementNode
}
from
'
./vFor
'
import
{
rewriteExpression
}
from
'
./utils
'
import
{
ATTR_VUE_SLOTS
,
rewriteExpression
}
from
'
./utils
'
import
{
isSelfKey
,
rewriteSelfKey
}
from
'
./transformKey
'
import
{
findStaticClassIndex
,
...
...
@@ -19,9 +20,10 @@ import {
rewriteStyle
,
}
from
'
./transformStyle
'
import
{
TO_DISPLAY_STRING
}
from
'
../runtimeHelpers
'
import
{
rewriteSlot
}
from
'
./transformSlot
'
export
const
transformIdentifier
:
NodeTransform
=
(
node
,
context
)
=>
{
return
()
=>
{
return
function
transformIdentifier
()
{
if
(
node
.
type
===
NodeTypes
.
INTERPOLATION
)
{
node
.
content
=
rewriteExpression
(
createCompoundExpression
([
...
...
@@ -31,6 +33,8 @@ export const transformIdentifier: NodeTransform = (node, context) => {
]),
context
)
}
else
if
(
isSlotOutlet
(
node
))
{
rewriteSlot
(
node
,
context
)
}
else
if
(
node
.
type
===
NodeTypes
.
ELEMENT
)
{
const
vFor
=
isForElementNode
(
node
)
&&
node
.
vFor
const
{
props
}
=
node
...
...
@@ -82,13 +86,11 @@ export const transformIdentifier: NodeTransform = (node, context) => {
}
}
// vue-id
// const builtInProps = ['v-i']
const
builtInProps
=
[
ATTR_VUE_SLOTS
]
function
isBuiltIn
(
_dir
:
DirectiveNode
)
{
return
false
// return (
// arg?.type === NodeTypes.SIMPLE_EXPRESSION &&
// builtInProps.includes(arg.content)
// )
function
isBuiltIn
({
arg
}:
DirectiveNode
)
{
return
(
arg
?.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
builtInProps
.
includes
(
arg
.
content
)
)
}
packages/uni-mp-compiler/src/transforms/transformSlot.ts
0 → 100644
浏览文件 @
ae7ec06d
import
{
AttributeNode
,
createCompilerError
,
createCompoundExpression
,
DirectiveNode
,
ErrorCodes
,
ExpressionNode
,
isBindKey
,
isStaticExp
,
NodeTypes
,
SimpleExpressionNode
,
SlotOutletNode
,
}
from
'
@vue/compiler-core
'
import
{
camelize
}
from
'
@vue/shared
'
import
{
RENDER_SLOT
}
from
'
../runtimeHelpers
'
import
{
genExpr
}
from
'
../codegen
'
import
{
TransformContext
}
from
'
../transform
'
import
{
processProps
}
from
'
./transformElement
'
import
{
rewriteExpression
}
from
'
./utils
'
export
function
rewriteSlot
(
node
:
SlotOutletNode
,
context
:
TransformContext
)
{
let
slotName
:
string
|
ExpressionNode
=
`"default"`
let
hasOtherDir
=
false
const
nonNameProps
:
(
AttributeNode
|
DirectiveNode
)[]
=
[]
for
(
let
i
=
0
;
i
<
node
.
props
.
length
;
i
++
)
{
const
p
=
node
.
props
[
i
]
if
(
p
.
type
===
NodeTypes
.
ATTRIBUTE
)
{
if
(
p
.
value
)
{
if
(
p
.
name
===
'
name
'
)
{
slotName
=
JSON
.
stringify
(
p
.
value
.
content
)
}
else
{
p
.
name
=
camelize
(
p
.
name
)
nonNameProps
.
push
(
p
)
}
}
}
else
{
if
(
p
.
name
!==
'
bind
'
)
{
hasOtherDir
=
true
}
if
(
p
.
name
===
'
bind
'
&&
isBindKey
(
p
.
arg
,
'
name
'
))
{
if
(
p
.
exp
)
slotName
=
p
.
exp
}
else
{
if
(
p
.
name
===
'
bind
'
&&
p
.
arg
&&
isStaticExp
(
p
.
arg
))
{
p
.
arg
.
content
=
camelize
(
p
.
arg
.
content
)
}
nonNameProps
.
push
(
p
)
}
}
}
if
(
hasOtherDir
)
{
context
.
onError
(
createCompilerError
(
ErrorCodes
.
X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET
,
node
.
loc
)
)
}
if
(
nonNameProps
.
length
>
0
)
{
processProps
(
node
,
context
,
nonNameProps
)
const
properties
:
string
[]
=
[]
nonNameProps
.
forEach
((
prop
)
=>
{
if
(
prop
.
type
===
NodeTypes
.
DIRECTIVE
&&
prop
.
name
===
'
bind
'
)
{
const
property
=
transformProperty
(
prop
,
context
)
property
&&
properties
.
push
(
property
)
}
})
if
(
properties
.
length
)
{
rewriteExpression
(
createCompoundExpression
([
context
.
helperString
(
RENDER_SLOT
)
+
'
(
'
,
slotName
,
'
,
'
,
`{
${
properties
.
join
(
'
,
'
)}
}`
,
'
)
'
,
]),
context
)
}
}
}
function
transformProperty
(
dir
:
DirectiveNode
,
context
:
TransformContext
)
{
if
(
!
dir
.
arg
||
!
dir
.
exp
)
{
return
}
const
isStaticArg
=
dir
.
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
dir
.
arg
.
isStatic
if
(
isStaticArg
)
{
return
`
${(
dir
.
arg
as
SimpleExpressionNode
).
content
}
:
${
genExpr
(
dir
.
exp
)}
`
}
return
`[
${
genExpr
(
dir
.
arg
)}
||'']:
${
genExpr
(
dir
.
exp
)}
`
}
packages/uni-mp-compiler/src/transforms/utils.ts
浏览文件 @
ae7ec06d
...
...
@@ -10,11 +10,17 @@ import {
objectProperty
,
SpreadElement
,
}
from
'
@babel/types
'
import
{
isComponentTag
}
from
'
@dcloudio/uni-shared
'
import
{
ComponentNode
,
createSimpleExpression
,
ElementTypes
,
ExpressionNode
,
isCoreComponent
,
NodeTypes
,
RootNode
,
SourceLocation
,
TemplateChildNode
,
}
from
'
@vue/compiler-core
'
import
{
walk
,
BaseNode
}
from
'
estree-walker
'
import
{
isUndefined
,
parseExpr
}
from
'
../ast
'
...
...
@@ -22,6 +28,25 @@ import { genBabelExpr, genExpr } from '../codegen'
import
{
CodegenScope
}
from
'
../options
'
import
{
isVForScope
,
isVIfScope
,
TransformContext
}
from
'
../transform
'
export
const
ATTR_VUE_ID
=
'
v-i
'
export
const
ATTR_VUE_SLOTS
=
'
v-s
'
export
const
CLASS_VUE_REF
=
'
v-r
'
export
const
CLASS_VUE_REF_IN_FOR
=
'
v-r-i-f
'
export
const
SCOPED_SLOT_IDENTIFIER
=
'
__SCOPED_SLOT__
'
export
function
isUserComponent
(
node
:
RootNode
|
TemplateChildNode
,
context
:
TransformContext
):
node
is
ComponentNode
{
return
(
node
.
type
===
NodeTypes
.
ELEMENT
&&
node
.
tagType
===
ElementTypes
.
COMPONENT
&&
!
isComponentTag
(
node
.
tag
)
&&
!
isCoreComponent
(
node
.
tag
)
&&
!
context
.
isBuiltInComponent
(
node
.
tag
)
)
}
export
function
rewriteSpreadElement
(
name
:
symbol
,
expr
:
SpreadElement
,
...
...
@@ -75,11 +100,20 @@ export function parseExprWithRewriteClass(
)
as
Identifier
|
MemberExpression
|
undefined
}
export
function
rewriteExpression
(
export
function
rewriteExpression
WithoutProperty
(
node
:
ExpressionNode
,
context
:
TransformContext
,
babelNode
?:
Expression
,
scope
:
CodegenScope
=
context
.
currentScope
)
{
return
rewriteExpression
(
node
,
context
,
babelNode
,
scope
,
false
)
}
export
function
rewriteExpression
(
node
:
ExpressionNode
,
context
:
TransformContext
,
babelNode
?:
Expression
,
scope
:
CodegenScope
=
context
.
currentScope
,
property
:
boolean
=
true
)
{
if
(
node
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
node
.
isStatic
)
{
return
node
...
...
@@ -104,7 +138,9 @@ export function rewriteExpression(
scope
=
findReferencedScope
(
babelNode
,
scope
)
const
id
=
scope
.
id
.
next
()
scope
.
properties
.
push
(
objectProperty
(
identifier
(
id
),
babelNode
!
))
if
(
property
)
{
scope
.
properties
.
push
(
objectProperty
(
identifier
(
id
),
babelNode
!
))
}
// 在v-for中包含的v-if块,所有变量需要补充当前v-for value前缀
if
(
isVIfScope
(
scope
))
{
if
(
isVForScope
(
scope
.
parentScope
))
{
...
...
packages/uni-mp-compiler/src/transforms/vFor.ts
浏览文件 @
ae7ec06d
...
...
@@ -7,26 +7,39 @@ import {
getInnerRange
,
SimpleExpressionNode
,
SourceLocation
,
createStructuralDirectiveTransform
,
ElementTypes
,
ElementNode
,
NodeTypes
,
isTemplateNode
,
findProp
,
ComponentNode
,
}
from
'
@vue/compiler-core
'
import
{
createVForCallExpression
,
parseExpr
,
parseParam
}
from
'
../ast
'
import
{
NodeTransform
,
TransformContext
}
from
'
../transform
'
import
{
parseExpr
,
parseParam
}
from
'
../ast
'
import
{
createStructuralDirectiveTransform
,
NodeTransform
,
TransformContext
,
}
from
'
../transform
'
import
{
processExpression
}
from
'
./transformExpression
'
import
{
genExpr
}
from
'
../codegen
'
import
{
arrowFunctionExpression
,
blockStatement
,
callExpression
,
cloneNode
,
Expression
,
identifier
,
Identifier
,
isIdentifier
,
objectExpression
,
Pattern
,
RestElement
,
returnStatement
,
}
from
'
@babel/types
'
import
{
rewriteExpression
}
from
'
./utils
'
import
{
CodegenVForScope
}
from
'
../options
'
import
{
V_FOR
}
from
'
../runtimeHelpers
'
import
{
createVSlotCallExpression
,
isScopedSlotVFor
}
from
'
./vSlot
'
export
type
VForOptions
=
Omit
<
ForParseResult
,
'
tagType
'
>
&
{
sourceExpr
?:
Expression
...
...
@@ -50,8 +63,7 @@ export function isForElementNode(node: unknown): node is ForElementNode {
}
export
const
transformFor
=
createStructuralDirectiveTransform
(
'
for
'
,
(
node
,
dir
,
_context
)
=>
{
const
context
=
_context
as
unknown
as
TransformContext
(
node
,
dir
,
context
)
=>
{
if
(
!
dir
.
exp
)
{
context
.
onError
(
createCompilerError
(
ErrorCodes
.
X_V_FOR_NO_EXPRESSION
,
dir
.
loc
)
...
...
@@ -89,10 +101,17 @@ export const transformFor = createStructuralDirectiveTransform(
const
indexCode
=
genExpr
(
index
)
const
indexExpr
=
parseParam
(
indexCode
,
context
,
index
)
const
indexAlias
=
parseAlias
(
indexExpr
,
indexCode
,
'
i
'
+
scopes
.
vFor
)
// 先占位vFor,后续更新 cloneSourceExpr 为 CallExpression
const
cloneSourceExpr
=
cloneNode
(
sourceExpr
!
,
false
)
const
vForData
:
VForOptions
=
{
source
,
sourceExpr
,
sourceAlias
:
''
,
sourceAlias
:
rewriteExpression
(
source
,
context
,
cloneSourceExpr
,
parentScope
).
content
,
value
,
valueCode
,
valueExpr
,
...
...
@@ -111,17 +130,12 @@ export const transformFor = createStructuralDirectiveTransform(
...
vForData
,
locals
:
findVForLocals
(
parseResult
),
})
// 先占位vFor,后续更新 cloneSourceExpr 为 CallExpression
const
cloneSourceExpr
=
cloneNode
(
sourceExpr
!
,
false
)
const
vFor
=
{
...
vForData
,
sourceAlias
:
rewriteExpression
(
source
,
context
,
cloneSourceExpr
,
parentScope
).
content
,
}
const
isScopedSlot
=
isScopedSlotVFor
(
vForScope
)
;(
node
as
ForElementNode
).
vFor
=
vFor
scopes
.
vFor
++
...
...
@@ -150,7 +164,14 @@ export const transformFor = createStructuralDirectiveTransform(
}
extend
(
clearExpr
(
cloneSourceExpr
),
createVForCallExpression
(
vForScope
,
context
)
isScopedSlot
?
createVSlotCallExpression
(
(
node
as
unknown
as
{
slotComponent
:
ComponentNode
})
.
slotComponent
,
vForScope
,
context
)
:
createVForCallExpression
(
vForScope
,
context
)
)
popScope
()
}
...
...
@@ -316,3 +337,41 @@ function createParamsList(
.
slice
(
0
,
i
+
1
)
.
map
((
arg
,
i
)
=>
arg
||
createSimpleExpression
(
`_`
.
repeat
(
i
+
1
),
false
))
}
function
createVForCallExpression
(
vForScope
:
CodegenVForScope
,
context
:
TransformContext
)
{
// let sourceExpr: Expression = vForScope.sourceExpr!
// if (isNumericLiteral(sourceExpr)) {
// sourceExpr = numericLiteralToArrayExpr((sourceExpr as NumericLiteral).value)
// }
return
callExpression
(
identifier
(
context
.
helperString
(
V_FOR
)),
[
vForScope
.
sourceExpr
!
,
createVForArrowFunctionExpression
(
vForScope
),
])
}
type
FunctionParam
=
Identifier
|
Pattern
|
RestElement
export
function
createVForArrowFunctionExpression
({
valueExpr
,
keyExpr
,
indexExpr
,
properties
,
}:
CodegenVForScope
)
{
const
params
:
FunctionParam
[]
=
[]
if
(
valueExpr
)
{
params
.
push
(
valueExpr
)
}
if
(
keyExpr
)
{
params
.
push
(
keyExpr
)
}
if
(
indexExpr
)
{
params
.
push
(
indexExpr
)
}
return
arrowFunctionExpression
(
params
,
blockStatement
([
returnStatement
(
objectExpression
(
properties
))])
)
}
packages/uni-mp-compiler/src/transforms/vIf.ts
浏览文件 @
ae7ec06d
...
...
@@ -9,7 +9,6 @@ import {
import
{
createCompilerError
,
createSimpleExpression
,
createStructuralDirectiveTransform
,
DirectiveNode
,
ElementNode
,
ErrorCodes
,
...
...
@@ -25,7 +24,12 @@ import {
parseExpr
,
}
from
'
../ast
'
import
{
CodegenScope
}
from
'
../options
'
import
{
NodeTransform
,
TransformContext
,
traverseNode
}
from
'
../transform
'
import
{
createStructuralDirectiveTransform
,
NodeTransform
,
TransformContext
,
traverseNode
,
}
from
'
../transform
'
import
{
processExpression
}
from
'
./transformExpression
'
import
{
rewriteExpression
}
from
'
./utils
'
interface
IfOptions
{
...
...
@@ -42,8 +46,7 @@ export function isIfElementNode(node: unknown): node is IfElementNode {
export
const
transformIf
=
createStructuralDirectiveTransform
(
/^
(
if|else|else-if
)
$/
,
(
node
,
dir
,
_context
)
=>
{
const
context
=
_context
as
unknown
as
TransformContext
(
node
,
dir
,
context
)
=>
{
return
processIf
(
node
,
dir
,
context
,
(
ifNode
,
branch
,
isRoot
)
=>
{
const
{
currentScope
:
parentScope
,
popScope
}
=
context
const
ifOptions
:
IfOptions
=
{
...
...
packages/uni-mp-compiler/src/transforms/vSlot.ts
0 → 100644
浏览文件 @
ae7ec06d
import
{
binaryExpression
,
BinaryExpression
,
callExpression
,
identifier
,
objectExpression
,
objectProperty
,
stringLiteral
,
}
from
'
@babel/types
'
import
{
ComponentNode
,
CompoundExpressionNode
,
createCompilerError
,
createSimpleExpression
,
DirectiveNode
,
ElementTypes
,
ErrorCodes
,
ExpressionNode
,
findDir
,
findProp
,
isStaticExp
,
isTemplateNode
,
locStub
,
NodeTypes
,
TemplateChildNode
,
TemplateNode
,
}
from
'
@vue/compiler-core
'
import
{
WITH_SCOPED_SLOT
}
from
'
../runtimeHelpers
'
import
{
createBindDirectiveNode
,
parseExpr
}
from
'
../ast
'
import
{
genExpr
}
from
'
../codegen
'
import
{
CodegenScope
,
CodegenVForScope
}
from
'
../options
'
import
{
isVForScope
,
NodeTransform
,
TransformContext
}
from
'
../transform
'
import
{
ATTR_VUE_ID
,
ATTR_VUE_SLOTS
,
isUserComponent
,
rewriteExpressionWithoutProperty
,
SCOPED_SLOT_IDENTIFIER
,
}
from
'
./utils
'
import
{
createVForArrowFunctionExpression
}
from
'
./vFor
'
export
const
transformSlot
:
NodeTransform
=
(
node
,
context
)
=>
{
if
(
!
isUserComponent
(
node
,
context
))
{
return
}
const
{
children
}
=
node
const
slots
=
new
Set
<
string
>
()
const
onComponentSlot
=
findDir
(
node
,
'
slot
'
,
true
)
const
implicitDefaultChildren
:
TemplateChildNode
[]
=
[]
for
(
let
i
=
0
;
i
<
children
.
length
;
i
++
)
{
const
slotElement
=
children
[
i
]
let
slotDir
:
DirectiveNode
|
undefined
if
(
!
isTemplateNode
(
slotElement
)
||
!
(
slotDir
=
findDir
(
slotElement
,
'
slot
'
,
true
))
)
{
// not a <template v-slot>, skip.
if
(
slotElement
.
type
!==
NodeTypes
.
COMMENT
)
{
implicitDefaultChildren
.
push
(
slotElement
)
}
continue
}
if
(
onComponentSlot
)
{
// already has on-component slot - this is incorrect usage.
context
.
onError
(
createCompilerError
(
ErrorCodes
.
X_V_SLOT_MIXED_SLOT_USAGE
,
slotDir
.
loc
)
)
break
}
const
slotName
=
findSlotName
(
slotDir
)
if
(
!
slotName
)
{
continue
}
slots
.
add
(
slotName
)
const
{
exp
}
=
slotDir
// non scoped slots
if
(
!
exp
)
{
continue
}
// empty
if
(
exp
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
!
exp
.
content
.
trim
())
{
continue
}
slots
.
add
(
slotName
)
// 使用vFor来简单处理scoped slot作用域问题
slotElement
.
children
=
[
createVForTemplate
(
slotElement
,
{
name
:
slotName
,
value
:
genExpr
(
exp
),
slotComponent
:
node
},
context
),
]
// v-slot="slotProps" => v-slot 避免 transformIdentifier 生成 slotProps 的变量声明
slotDir
.
exp
=
undefined
}
if
(
implicitDefaultChildren
.
length
)
{
slots
.
add
(
'
default
'
)
}
if
(
slots
.
size
)
{
node
.
props
.
unshift
(
createBindDirectiveNode
(
ATTR_VUE_SLOTS
,
`[
${[...
slots
].
map
((
name
)
=>
`'
${
name
}
'`
).
join
(
'
,
'
)}
]`
)
)
}
}
export
function
findSlotName
(
slotDir
:
DirectiveNode
)
{
if
(
!
slotDir
.
arg
)
{
return
'
default
'
}
if
(
isStaticExp
(
slotDir
.
arg
))
{
return
slotDir
.
arg
.
content
}
}
export
function
isScopedSlotVFor
({
source
}:
CodegenVForScope
)
{
if
(
source
.
type
!==
NodeTypes
.
COMPOUND_EXPRESSION
)
{
return
false
}
const
first
=
source
.
children
[
0
]
as
ExpressionNode
return
(
first
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
first
.
content
.
includes
(
SCOPED_SLOT_IDENTIFIER
)
)
}
function
findCurrentVForValueAlias
(
context
:
TransformContext
)
{
let
scope
:
CodegenScope
|
null
=
context
.
currentScope
while
(
scope
)
{
if
(
isVForScope
(
scope
))
{
return
scope
.
valueAlias
}
scope
=
scope
.
parent
}
return
''
}
function
createVForTemplate
(
slotElement
:
TemplateNode
,
{
name
,
value
,
slotComponent
,
}:
{
name
:
string
value
:
string
slotComponent
:
ComponentNode
},
context
:
TransformContext
)
{
const
key
=
'
s
'
+
context
.
scopes
.
vFor
const
keyProp
:
DirectiveNode
=
createBindDirectiveNode
(
'
key
'
,
key
)
const
vForProp
:
DirectiveNode
=
{
type
:
NodeTypes
.
DIRECTIVE
,
name
:
'
for
'
,
loc
:
locStub
,
modifiers
:
[],
arg
:
undefined
,
exp
:
createSimpleExpression
(
`(
${
value
}
,
${
key
}
) in
${
SCOPED_SLOT_IDENTIFIER
}
('
${
name
}
',
${
findCurrentVForValueAlias
(
context
)
||
`''`
}
)`
),
}
return
{
loc
:
slotElement
.
loc
,
ns
:
0
,
tag
:
'
template
'
,
type
:
NodeTypes
.
ELEMENT
,
tagType
:
ElementTypes
.
TEMPLATE
,
props
:
[
vForProp
,
keyProp
],
isSelfClosing
:
false
,
codegenNode
:
undefined
,
children
:
slotElement
.
children
,
slotComponent
,
}
as
TemplateNode
}
const
slotNameRE
=
/
\(
'
(
.*
)
',/
/**
* ('default','') => default
* @param source
* @returns
*/
function
findCurrentSlotName
(
source
:
ExpressionNode
)
{
return
stringLiteral
(
((
source
as
CompoundExpressionNode
).
children
[
1
]
as
string
).
match
(
slotNameRE
)
!
[
1
]
)
}
function
createPathBinaryExpr
(
scope
:
CodegenVForScope
)
{
return
binaryExpression
(
'
+
'
,
binaryExpression
(
'
+
'
,
stringLiteral
(
parseVForPath
(
scope
.
sourceAlias
)
+
'
.
'
),
identifier
(
scope
.
indexAlias
)
),
stringLiteral
(
'
.
'
)
)
}
export
function
findCurrentPath
(
id
:
string
,
scope
:
CodegenScope
)
{
let
parent
=
scope
.
parent
let
binaryExpr
:
BinaryExpression
|
null
=
null
while
(
parent
)
{
if
(
isVForScope
(
parent
))
{
if
(
!
binaryExpr
)
{
binaryExpr
=
createPathBinaryExpr
(
parent
)
}
else
{
binaryExpr
=
binaryExpression
(
'
+
'
,
createPathBinaryExpr
(
parent
),
binaryExpr
)
}
}
parent
=
parent
.
parent
}
return
(
(
binaryExpr
&&
binaryExpression
(
'
+
'
,
binaryExpr
,
stringLiteral
(
id
)))
||
stringLiteral
(
id
)
)
}
function
findCurrentVueIdExpr
(
node
:
ComponentNode
,
context
:
TransformContext
)
{
if
(
!
node
)
{
return
stringLiteral
(
''
)
}
const
vueIdProp
=
findProp
(
node
,
ATTR_VUE_ID
)
!
if
(
vueIdProp
.
type
===
NodeTypes
.
ATTRIBUTE
)
{
return
stringLiteral
(
vueIdProp
.
value
!
.
content
)
}
return
parseExpr
(
genExpr
(
vueIdProp
.
exp
!
),
context
)
||
stringLiteral
(
''
)
}
/**
* 目前无用
* @param vForScope
* @param parentScope
* @param context
*/
export
function
rewriteScopedSlotVForScope
(
vForScope
:
CodegenVForScope
,
parentScope
:
CodegenScope
,
context
:
TransformContext
)
{
// 生成一个新的sourceAlias,用于scopedSlots
const
{
source
,
sourceExpr
}
=
vForScope
vForScope
.
sourceAlias
=
rewriteExpressionWithoutProperty
(
source
,
context
,
sourceExpr
,
parentScope
).
content
}
function
parseVForPath
(
id
:
string
)
{
return
id
.
includes
(
'
.
'
)
?
id
.
split
(
'
.
'
)[
1
]
:
id
}
export
function
createVSlotCallExpression
(
slotComponent
:
ComponentNode
,
vForScope
:
CodegenVForScope
,
context
:
TransformContext
)
{
const
{
source
/*, sourceAlias*/
}
=
vForScope
// const id = parseVForPath(sourceAlias)
return
callExpression
(
identifier
(
context
.
helperString
(
WITH_SCOPED_SLOT
)),
[
createVForArrowFunctionExpression
(
vForScope
),
objectExpression
([
// 插槽名称,数据更新path,vueId
objectProperty
(
identifier
(
'
name
'
),
findCurrentSlotName
(
source
)),
// 暂不生成path
// objectProperty(identifier('path'), findCurrentPath(id, vForScope)),
objectProperty
(
identifier
(
'
vueId
'
),
findCurrentVueIdExpr
(
slotComponent
,
context
)
),
]),
])
}
packages/uni-mp-core/src/index.ts
浏览文件 @
ae7ec06d
...
...
@@ -23,7 +23,6 @@ export {
initUnknownHooks
,
}
from
'
./runtime/componentHooks
'
export
{
initMocks
,
initComponentInstance
}
from
'
./runtime/componentInstance
'
export
{
handleEvent
}
from
'
./runtime/componentEvents
'
export
{
$createComponent
,
$destroyComponent
}
from
'
./runtime/component
'
export
{
initRefs
,
...
...
packages/uni-mp-core/src/runtime/component.ts
浏览文件 @
ae7ec06d
...
...
@@ -6,7 +6,6 @@ import { initExtraOptions, initWxsCallMethods, initBehavior } from './util'
import
{
initProps
}
from
'
./componentProps
'
import
{
applyOptions
}
from
'
./componentOptions
'
import
{
handleEvent
}
from
'
./componentEvents
'
import
{
CreateComponentOptions
}
from
'
./componentInstance
'
import
Component
=
WechatMiniprogram
.
Component
...
...
@@ -102,7 +101,6 @@ export function parseComponent(
},
methods
:
{
__l
:
handleLink
,
__e
:
handleEvent
,
},
}
...
...
packages/uni-mp-core/src/runtime/componentEvents.ts
已删除
100644 → 0
浏览文件 @
f63216a6
import
{
extend
,
hasOwn
,
NOOP
,
isArray
,
isPlainObject
,
isFunction
,
}
from
'
@vue/shared
'
import
{
ComponentPublicInstance
}
from
'
vue
'
import
{
MPComponentInstance
}
from
'
./component
'
import
{
getTarget
}
from
'
./util
'
interface
Event
extends
WechatMiniprogram
.
BaseEvent
{
detail
:
Record
<
string
,
any
>
stopPropagation
:
()
=>
void
preventDefault
:
()
=>
void
}
function
getExtraValue
(
instance
:
ComponentPublicInstance
,
dataPathsArray
:
string
[]
)
{
let
context
:
unknown
=
instance
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
]
const
value
=
dataPathArray
[
2
]
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
]
const
valuePath
=
dataPathArray
[
3
]
let
vFor
:
any
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
}
else
if
(
!
dataPath
)
{
vFor
=
context
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
)
}
else
{
vFor
=
getTarget
(
context
,
dataPath
)
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
]
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
})
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
})
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
)
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
)
}
}
})
return
context
}
function
processEventExtra
(
instance
:
ComponentPublicInstance
,
extra
:
any
[],
event
:
Event
)
{
const
extraObj
:
Record
<
string
,
any
>
=
{}
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
]
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
)
)
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
)
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
)
}
})
}
return
extraObj
}
function
getObjByArray
(
arr
:
any
[])
{
const
obj
:
Record
<
string
,
any
>
=
{}
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
]
obj
[
element
[
0
]]
=
element
[
1
]
}
return
obj
}
function
processEventArgs
(
instance
:
ComponentPublicInstance
,
event
:
Event
,
args
=
[],
extra
=
[],
isCustom
:
boolean
,
methodName
:
string
)
{
let
isCustomMPEvent
=
false
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
]
}
return
event
.
detail
.
__args__
||
event
.
detail
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
)
const
ret
:
any
[]
=
[]
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
((
event
.
target
as
any
).
value
)
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
])
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
)
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
))
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
])
}
else
{
ret
.
push
(
arg
)
}
}
})
return
ret
}
function
wrapper
(
event
:
Event
)
{
event
.
stopPropagation
=
NOOP
event
.
preventDefault
=
NOOP
event
.
target
=
event
.
target
||
{}
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{}
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{}
event
.
detail
.
markerId
=
(
event
as
any
).
markerId
}
if
(
__PLATFORM__
===
'
mp-baidu
'
)
{
// mp-baidu,checked=>value
if
(
isPlainObject
(
event
.
detail
)
&&
hasOwn
(
event
.
detail
,
'
checked
'
)
&&
!
hasOwn
(
event
.
detail
,
'
value
'
)
)
{
;(
event
.
detail
as
any
).
value
=
(
event
.
detail
as
any
).
checked
}
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
)
}
return
event
}
const
ONCE
=
'
~
'
const
CUSTOM
=
'
^
'
function
matchEventType
(
eventType
:
string
,
optType
:
string
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
))
)
}
export
function
handleEvent
(
this
:
MPComponentInstance
,
event
:
Event
)
{
event
=
wrapper
(
event
)
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
)
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
])
as
unknown
as
any
[]
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
)
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
const
ret
:
any
[]
=
[]
eventOpts
.
forEach
((
eventOpt
:
any
[])
=>
{
let
type
=
eventOpt
[
0
]
const
eventsArray
=
eventOpt
[
1
]
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
type
=
isCustom
?
type
.
slice
(
1
)
:
type
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
type
=
isOnce
?
type
.
slice
(
1
)
:
type
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
:
any
[])
=>
{
const
methodName
=
eventArray
[
0
]
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
!
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
!
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
)
)
return
}
const
handler
=
(
handlerCtx
as
any
)[
methodName
]
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
)
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
}
handler
.
once
=
true
}
let
params
=
processEventArgs
(
this
.
$vm
!
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
)
params
=
Array
.
isArray
(
params
)
?
params
:
[]
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()
)
)
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
])
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
))
}
})
}
})
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
]
}
}
packages/uni-mp-core/src/runtime/componentInstance/index.ts
浏览文件 @
ae7ec06d
...
...
@@ -7,11 +7,7 @@ import {
isObject
,
isPlainObject
,
}
from
'
@vue/shared
'
import
{
ComponentPublicInstance
,
ComponentInternalInstance
,
onUnmounted
,
}
from
'
vue
'
import
{
ComponentPublicInstance
,
ComponentInternalInstance
}
from
'
vue
'
import
{
getEventChannel
}
from
'
../../api/protocols/navigateTo
'
import
{
MPComponentInstance
}
from
'
../component
'
import
{
getClass
,
getStyle
,
getValue
}
from
'
./utils
'
...
...
@@ -170,16 +166,6 @@ export function initComponentInstance(
options
:
CreateComponentOptions
)
{
initBaseInstance
(
instance
,
options
)
if
(
__PLATFORM__
===
'
mp-weixin
'
||
__PLATFORM__
===
'
mp-qq
'
||
__PLATFORM__
===
'
mp-toutiao
'
||
__PLATFORM__
===
'
mp-kuaishou
'
||
__PLATFORM__
===
'
mp-alipay
'
||
__PLATFORM__
===
'
mp-baidu
'
)
{
initScopedSlotsParams
(
instance
)
}
const
ctx
=
(
instance
as
any
).
ctx
MP_METHODS
.
forEach
((
method
)
=>
{
...
...
@@ -238,58 +224,3 @@ function callHook(this: ComponentPublicInstance, name: string, args?: unknown) {
const
hooks
=
(
this
.
$
as
any
)[
name
]
return
hooks
&&
invokeArrayFns
(
hooks
,
args
)
}
const
center
:
Record
<
string
,
any
>
=
{}
const
parents
:
Record
<
string
,
ComponentPublicInstance
>
=
{}
function
initScopedSlotsParams
(
instance
:
ComponentInternalInstance
)
{
const
ctx
=
(
instance
as
any
).
ctx
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
:
string
)
{
const
has
=
center
[
vueId
]
if
(
!
has
)
{
parents
[
vueId
]
=
this
onUnmounted
(()
=>
{
delete
parents
[
vueId
]
},
instance
)
}
return
has
}
ctx
.
$getScopedSlotsParams
=
function
(
vueId
:
string
,
name
:
string
,
key
:
string
)
{
const
data
=
center
[
vueId
]
if
(
data
)
{
const
object
=
data
[
name
]
||
{}
return
key
?
object
[
key
]
:
object
}
else
{
parents
[
vueId
]
=
this
onUnmounted
(()
=>
{
delete
parents
[
vueId
]
},
instance
)
}
}
ctx
.
$setScopedSlotsParams
=
function
(
name
:
string
,
value
:
any
)
{
const
vueIds
=
instance
.
attrs
.
vueId
as
string
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
]
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{})
object
[
name
]
=
value
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
()
}
}
}
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
const
vueId
=
propsData
&&
(
propsData
.
vueId
as
string
)
if
(
vueId
)
{
delete
center
[
vueId
]
delete
parents
[
vueId
]
}
},
instance
)
}
packages/uni-mp-core/src/runtime/componentInstance/utils.ts
浏览文件 @
ae7ec06d
import
{
ComponentPublicInstance
}
from
'
vue
'
import
{
extend
,
isObject
,
hyphenate
}
from
'
@vue/shared
'
import
{
cache
}
from
'
@dcloudio/uni-shared
'
import
{
getTarget
}
from
'
../util
'
import
{
cache
,
getDataByPath
}
from
'
@dcloudio/uni-shared
'
export
function
getValue
(
this
:
ComponentPublicInstance
,
dataPath
:
string
,
target
:
Record
<
string
,
any
>
)
{
return
get
Target
(
target
||
this
,
dataPath
)
return
get
DataByPath
(
target
||
this
,
dataPath
)
}
export
function
getClass
(
dynamicClass
:
unknown
,
staticClass
:
string
)
{
...
...
packages/uni-mp-core/src/runtime/componentProps.ts
浏览文件 @
ae7ec06d
...
...
@@ -48,7 +48,7 @@ function initDefaultProps(isBehavior: boolean = false) {
}
}
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
this
:
MPComponentInstance
,
newVal
)
{
...
...
packages/uni-mp-core/src/runtime/util.ts
浏览文件 @
ae7ec06d
...
...
@@ -124,19 +124,3 @@ export function findVmByVueId(
}
}
}
export
function
getTarget
(
obj
:
any
,
path
:
string
):
unknown
{
const
parts
=
path
.
split
(
'
.
'
)
let
key
:
number
|
string
=
parts
[
0
]
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
))
}
if
(
!
obj
)
{
obj
=
{}
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
]
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
))
}
packages/uni-mp-kuaishou/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
import
{
isPlainObject
,
hasOwn
,
isArray
,
extend
,
hyphenate
,
isObject
,
toNumber
,
isFunction
,
NOOP
,
camelize
}
from
'
@vue/shared
'
;
import
{
onUnmounted
,
injectHook
,
ref
}
from
'
vue
'
;
import
{
isPlainObject
,
extend
,
hyphenate
,
isObject
,
isArray
,
hasOwn
,
toNumber
,
isFunction
,
camelize
}
from
'
@vue/shared
'
;
import
{
injectHook
,
ref
}
from
'
vue
'
;
const
encode
=
encodeURIComponent
;
function
stringifyQuery
(
obj
,
encodeStr
=
encode
)
{
...
...
@@ -21,6 +21,18 @@ function stringifyQuery(obj, encodeStr = encode) {
return
res
?
`?
${
res
}
`
:
''
;
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
cache
(
fn
)
{
const
cache
=
Object
.
create
(
null
);
return
(
str
)
=>
{
...
...
@@ -129,102 +141,8 @@ function getEventChannel(id) {
return
eventChannelStack
.
shift
();
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
function
getTarget
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
let
key
=
parts
[
0
];
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
));
}
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
getValue
(
dataPath
,
target
)
{
return
get
Target
(
target
||
this
,
dataPath
);
return
get
DataByPath
(
target
||
this
,
dataPath
);
}
function
getClass
(
dynamicClass
,
staticClass
)
{
return
renderClass
(
staticClass
,
dynamicClass
);
...
...
@@ -420,9 +338,6 @@ function initBaseInstance(instance, options) {
}
function
initComponentInstance
(
instance
,
options
)
{
initBaseInstance
(
instance
,
options
);
{
initScopedSlotsParams
(
instance
);
}
const
ctx
=
instance
.
ctx
;
MP_METHODS
.
forEach
((
method
)
=>
{
ctx
[
method
]
=
function
(...
args
)
{
...
...
@@ -469,53 +384,6 @@ function callHook(name, args) {
}
const
hooks
=
this
.
$
[
name
];
return
hooks
&&
invokeArrayFns
(
hooks
,
args
);
}
const
center
=
{};
const
parents
=
{};
function
initScopedSlotsParams
(
instance
)
{
const
ctx
=
instance
.
ctx
;
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
)
{
const
has
=
center
[
vueId
];
if
(
!
has
)
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
return
has
;
};
ctx
.
$getScopedSlotsParams
=
function
(
vueId
,
name
,
key
)
{
const
data
=
center
[
vueId
];
if
(
data
)
{
const
object
=
data
[
name
]
||
{};
return
key
?
object
[
key
]
:
object
;
}
else
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
};
ctx
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueIds
=
instance
.
attrs
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{});
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
;
const
vueId
=
propsData
&&
propsData
.
vueId
;
if
(
vueId
)
{
delete
center
[
vueId
];
delete
parents
[
vueId
];
}
},
instance
);
}
const
PAGE_HOOKS
=
[
...
...
@@ -633,6 +501,85 @@ function initLocale(appVm) {
});
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
const
PROP_TYPES
=
[
String
,
Number
,
Boolean
,
Object
,
Array
,
null
];
function
createObserver
(
name
)
{
return
function
observer
(
newVal
)
{
...
...
@@ -656,7 +603,7 @@ function initDefaultProps(isBehavior = false) {
value
:
''
,
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
newVal
)
{
...
...
@@ -789,252 +736,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) {
componentOptions
.
behaviors
=
initBehaviors
(
vueOptions
,
initBehavior
);
}
function
getExtraValue
(
instance
,
dataPathsArray
)
{
let
context
=
instance
;
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
];
const
value
=
dataPathArray
[
2
];
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
];
const
valuePath
=
dataPathArray
[
3
];
let
vFor
;
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
;
}
else
if
(
!
dataPath
)
{
vFor
=
context
;
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
);
}
else
{
vFor
=
getTarget
(
context
,
dataPath
);
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
;
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
];
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
;
});
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
;
});
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
);
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
);
}
}
});
return
context
;
}
function
processEventExtra
(
instance
,
extra
,
event
)
{
const
extraObj
=
{};
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
;
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
;
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
;
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
];
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
));
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
);
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
);
}
});
}
return
extraObj
;
}
function
getObjByArray
(
arr
)
{
const
obj
=
{};
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
];
obj
[
element
[
0
]]
=
element
[
1
];
}
return
obj
;
}
function
processEventArgs
(
instance
,
event
,
args
=
[],
extra
=
[],
isCustom
,
methodName
)
{
let
isCustomMPEvent
=
false
;
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
;
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
];
}
return
event
.
detail
.
__args__
||
event
.
detail
;
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
);
const
ret
=
[];
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
(
event
.
target
.
value
);
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
]);
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
);
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
));
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
]);
}
else
{
ret
.
push
(
arg
);
}
}
});
return
ret
;
}
function
wrapper
(
event
)
{
event
.
stopPropagation
=
NOOP
;
event
.
preventDefault
=
NOOP
;
event
.
target
=
event
.
target
||
{};
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
return
event
;
}
const
ONCE
=
'
~
'
;
const
CUSTOM
=
'
^
'
;
function
matchEventType
(
eventType
,
optType
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
)));
}
function
handleEvent
(
event
)
{
event
=
wrapper
(
event
);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
;
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
]);
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
;
const
ret
=
[];
eventOpts
.
forEach
((
eventOpt
)
=>
{
let
type
=
eventOpt
[
0
];
const
eventsArray
=
eventOpt
[
1
];
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
;
type
=
isCustom
?
type
.
slice
(
1
)
:
type
;
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
;
type
=
isOnce
?
type
.
slice
(
1
)
:
type
;
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
)
=>
{
const
methodName
=
eventArray
[
0
];
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
;
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
;
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
));
return
;
}
const
handler
=
handlerCtx
[
methodName
];
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
);
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
;
}
handler
.
once
=
true
;
}
let
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
);
params
=
Array
.
isArray
(
params
)
?
params
:
[];
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()))
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
]);
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
));
}
});
}
});
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
];
}
}
function
parseComponent
(
vueOptions
,
{
parse
,
mocks
,
isPage
,
initRelation
,
handleLink
,
initLifetimes
,
})
{
vueOptions
=
vueOptions
.
default
||
vueOptions
;
const
options
=
{
...
...
@@ -1060,7 +761,6 @@ function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handle
},
methods
:
{
__l
:
handleLink
,
__e
:
handleEvent
,
},
};
if
(
__VUE_OPTIONS_API__
)
{
...
...
@@ -1175,7 +875,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
},
{
mpType
:
isPage
(
mpInstance
)
?
'
page
'
:
'
component
'
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
,
options
)
{
initRefs
(
instance
,
mpInstance
);
...
...
packages/uni-mp-qq/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
import
{
isPlainObject
,
hasOwn
,
isArray
,
extend
,
hyphenate
,
isObject
,
toNumber
,
isFunction
,
NOOP
,
camelize
}
from
'
@vue/shared
'
;
import
{
onUnmounted
,
injectHook
,
ref
}
from
'
vue
'
;
import
{
isPlainObject
,
extend
,
hyphenate
,
isObject
,
isArray
,
hasOwn
,
toNumber
,
isFunction
,
camelize
}
from
'
@vue/shared
'
;
import
{
injectHook
,
ref
}
from
'
vue
'
;
const
encode
=
encodeURIComponent
;
function
stringifyQuery
(
obj
,
encodeStr
=
encode
)
{
...
...
@@ -21,6 +21,18 @@ function stringifyQuery(obj, encodeStr = encode) {
return
res
?
`?
${
res
}
`
:
''
;
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
cache
(
fn
)
{
const
cache
=
Object
.
create
(
null
);
return
(
str
)
=>
{
...
...
@@ -129,102 +141,8 @@ function getEventChannel(id) {
return
eventChannelStack
.
shift
();
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
function
getTarget
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
let
key
=
parts
[
0
];
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
));
}
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
getValue
(
dataPath
,
target
)
{
return
get
Target
(
target
||
this
,
dataPath
);
return
get
DataByPath
(
target
||
this
,
dataPath
);
}
function
getClass
(
dynamicClass
,
staticClass
)
{
return
renderClass
(
staticClass
,
dynamicClass
);
...
...
@@ -420,9 +338,6 @@ function initBaseInstance(instance, options) {
}
function
initComponentInstance
(
instance
,
options
)
{
initBaseInstance
(
instance
,
options
);
{
initScopedSlotsParams
(
instance
);
}
const
ctx
=
instance
.
ctx
;
MP_METHODS
.
forEach
((
method
)
=>
{
ctx
[
method
]
=
function
(...
args
)
{
...
...
@@ -469,53 +384,6 @@ function callHook(name, args) {
}
const
hooks
=
this
.
$
[
name
];
return
hooks
&&
invokeArrayFns
(
hooks
,
args
);
}
const
center
=
{};
const
parents
=
{};
function
initScopedSlotsParams
(
instance
)
{
const
ctx
=
instance
.
ctx
;
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
)
{
const
has
=
center
[
vueId
];
if
(
!
has
)
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
return
has
;
};
ctx
.
$getScopedSlotsParams
=
function
(
vueId
,
name
,
key
)
{
const
data
=
center
[
vueId
];
if
(
data
)
{
const
object
=
data
[
name
]
||
{};
return
key
?
object
[
key
]
:
object
;
}
else
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
};
ctx
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueIds
=
instance
.
attrs
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{});
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
;
const
vueId
=
propsData
&&
propsData
.
vueId
;
if
(
vueId
)
{
delete
center
[
vueId
];
delete
parents
[
vueId
];
}
},
instance
);
}
const
PAGE_HOOKS
=
[
...
...
@@ -633,6 +501,85 @@ function initLocale(appVm) {
});
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
const
PROP_TYPES
=
[
String
,
Number
,
Boolean
,
Object
,
Array
,
null
];
function
createObserver
(
name
)
{
return
function
observer
(
newVal
)
{
...
...
@@ -656,7 +603,7 @@ function initDefaultProps(isBehavior = false) {
value
:
''
,
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
newVal
)
{
...
...
@@ -789,252 +736,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) {
componentOptions
.
behaviors
=
initBehaviors
(
vueOptions
,
initBehavior
);
}
function
getExtraValue
(
instance
,
dataPathsArray
)
{
let
context
=
instance
;
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
];
const
value
=
dataPathArray
[
2
];
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
];
const
valuePath
=
dataPathArray
[
3
];
let
vFor
;
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
;
}
else
if
(
!
dataPath
)
{
vFor
=
context
;
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
);
}
else
{
vFor
=
getTarget
(
context
,
dataPath
);
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
;
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
];
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
;
});
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
;
});
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
);
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
);
}
}
});
return
context
;
}
function
processEventExtra
(
instance
,
extra
,
event
)
{
const
extraObj
=
{};
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
;
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
;
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
;
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
];
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
));
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
);
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
);
}
});
}
return
extraObj
;
}
function
getObjByArray
(
arr
)
{
const
obj
=
{};
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
];
obj
[
element
[
0
]]
=
element
[
1
];
}
return
obj
;
}
function
processEventArgs
(
instance
,
event
,
args
=
[],
extra
=
[],
isCustom
,
methodName
)
{
let
isCustomMPEvent
=
false
;
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
;
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
];
}
return
event
.
detail
.
__args__
||
event
.
detail
;
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
);
const
ret
=
[];
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
(
event
.
target
.
value
);
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
]);
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
);
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
));
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
]);
}
else
{
ret
.
push
(
arg
);
}
}
});
return
ret
;
}
function
wrapper
(
event
)
{
event
.
stopPropagation
=
NOOP
;
event
.
preventDefault
=
NOOP
;
event
.
target
=
event
.
target
||
{};
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
return
event
;
}
const
ONCE
=
'
~
'
;
const
CUSTOM
=
'
^
'
;
function
matchEventType
(
eventType
,
optType
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
)));
}
function
handleEvent
(
event
)
{
event
=
wrapper
(
event
);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
;
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
]);
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
;
const
ret
=
[];
eventOpts
.
forEach
((
eventOpt
)
=>
{
let
type
=
eventOpt
[
0
];
const
eventsArray
=
eventOpt
[
1
];
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
;
type
=
isCustom
?
type
.
slice
(
1
)
:
type
;
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
;
type
=
isOnce
?
type
.
slice
(
1
)
:
type
;
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
)
=>
{
const
methodName
=
eventArray
[
0
];
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
;
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
;
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
));
return
;
}
const
handler
=
handlerCtx
[
methodName
];
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
);
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
;
}
handler
.
once
=
true
;
}
let
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
);
params
=
Array
.
isArray
(
params
)
?
params
:
[];
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()))
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
]);
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
));
}
});
}
});
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
];
}
}
function
parseComponent
(
vueOptions
,
{
parse
,
mocks
,
isPage
,
initRelation
,
handleLink
,
initLifetimes
,
})
{
vueOptions
=
vueOptions
.
default
||
vueOptions
;
const
options
=
{
...
...
@@ -1060,7 +761,6 @@ function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handle
},
methods
:
{
__l
:
handleLink
,
__e
:
handleEvent
,
},
};
if
(
__VUE_OPTIONS_API__
)
{
...
...
@@ -1175,7 +875,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
},
{
mpType
:
isPage
(
mpInstance
)
?
'
page
'
:
'
component
'
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
,
options
)
{
initRefs
(
instance
,
mpInstance
);
...
...
packages/uni-mp-toutiao/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
import
{
isPlainObject
,
hasOwn
,
isArray
,
extend
,
hyphenate
,
isObject
,
toNumber
,
isFunction
,
NOOP
,
camelize
}
from
'
@vue/shared
'
;
import
{
onUnmounted
,
injectHook
,
ref
}
from
'
vue
'
;
import
{
isPlainObject
,
extend
,
hyphenate
,
isObject
,
isArray
,
hasOwn
,
toNumber
,
isFunction
,
camelize
}
from
'
@vue/shared
'
;
import
{
injectHook
,
ref
}
from
'
vue
'
;
const
encode
=
encodeURIComponent
;
function
stringifyQuery
(
obj
,
encodeStr
=
encode
)
{
...
...
@@ -21,6 +21,18 @@ function stringifyQuery(obj, encodeStr = encode) {
return
res
?
`?
${
res
}
`
:
''
;
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
cache
(
fn
)
{
const
cache
=
Object
.
create
(
null
);
return
(
str
)
=>
{
...
...
@@ -129,102 +141,8 @@ function getEventChannel(id) {
return
eventChannelStack
.
shift
();
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
function
getTarget
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
let
key
=
parts
[
0
];
if
(
key
.
indexOf
(
'
__$n
'
)
===
0
)
{
//number index
key
=
parseInt
(
key
.
replace
(
'
__$n
'
,
''
));
}
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getTarget
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
getValue
(
dataPath
,
target
)
{
return
get
Target
(
target
||
this
,
dataPath
);
return
get
DataByPath
(
target
||
this
,
dataPath
);
}
function
getClass
(
dynamicClass
,
staticClass
)
{
return
renderClass
(
staticClass
,
dynamicClass
);
...
...
@@ -420,9 +338,6 @@ function initBaseInstance(instance, options) {
}
function
initComponentInstance
(
instance
,
options
)
{
initBaseInstance
(
instance
,
options
);
{
initScopedSlotsParams
(
instance
);
}
const
ctx
=
instance
.
ctx
;
MP_METHODS
.
forEach
((
method
)
=>
{
ctx
[
method
]
=
function
(...
args
)
{
...
...
@@ -469,53 +384,6 @@ function callHook(name, args) {
}
const
hooks
=
this
.
$
[
name
];
return
hooks
&&
invokeArrayFns
(
hooks
,
args
);
}
const
center
=
{};
const
parents
=
{};
function
initScopedSlotsParams
(
instance
)
{
const
ctx
=
instance
.
ctx
;
ctx
.
$hasScopedSlotsParams
=
function
(
vueId
)
{
const
has
=
center
[
vueId
];
if
(
!
has
)
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
return
has
;
};
ctx
.
$getScopedSlotsParams
=
function
(
vueId
,
name
,
key
)
{
const
data
=
center
[
vueId
];
if
(
data
)
{
const
object
=
data
[
name
]
||
{};
return
key
?
object
[
key
]
:
object
;
}
else
{
parents
[
vueId
]
=
this
;
onUnmounted
(()
=>
{
delete
parents
[
vueId
];
},
instance
);
}
};
ctx
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueIds
=
instance
.
attrs
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
(
center
[
vueId
]
=
center
[
vueId
]
||
{});
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
onUnmounted
(
function
()
{
const
propsData
=
instance
.
attrs
;
const
vueId
=
propsData
&&
propsData
.
vueId
;
if
(
vueId
)
{
delete
center
[
vueId
];
delete
parents
[
vueId
];
}
},
instance
);
}
const
PAGE_HOOKS
=
[
...
...
@@ -636,6 +504,85 @@ function initLocale(appVm) {
});
}
function
initBehavior
(
options
)
{
return
Behavior
(
options
);
}
function
initVueIds
(
vueIds
,
mpInstance
)
{
if
(
!
vueIds
)
{
return
;
}
const
ids
=
vueIds
.
split
(
'
,
'
);
const
len
=
ids
.
length
;
if
(
len
===
1
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
}
else
if
(
len
===
2
)
{
mpInstance
.
_$vueId
=
ids
[
0
];
mpInstance
.
_$vuePid
=
ids
[
1
];
}
}
const
EXTRAS
=
[
'
externalClasses
'
];
function
initExtraOptions
(
miniProgramComponentOptions
,
vueOptions
)
{
EXTRAS
.
forEach
((
name
)
=>
{
if
(
hasOwn
(
vueOptions
,
name
))
{
miniProgramComponentOptions
[
name
]
=
vueOptions
[
name
];
}
});
}
function
initWxsCallMethods
(
methods
,
wxsCallMethods
)
{
if
(
!
isArray
(
wxsCallMethods
))
{
return
;
}
wxsCallMethods
.
forEach
((
callMethod
)
=>
{
methods
[
callMethod
]
=
function
(
args
)
{
return
this
.
$vm
[
callMethod
](
args
);
};
});
}
function
selectAllComponents
(
mpInstance
,
selector
,
$refs
)
{
const
components
=
mpInstance
.
selectAllComponents
(
selector
);
components
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
$refs
[
ref
]
=
component
.
$vm
||
component
;
});
}
function
initRefs
(
instance
,
mpInstance
)
{
Object
.
defineProperty
(
instance
,
'
refs
'
,
{
get
()
{
const
$refs
=
{};
selectAllComponents
(
mpInstance
,
'
.v-r
'
,
$refs
);
const
forComponents
=
mpInstance
.
selectAllComponents
(
'
.v-r-i-f
'
);
forComponents
.
forEach
((
component
)
=>
{
const
ref
=
component
.
dataset
.
ref
;
if
(
!
$refs
[
ref
])
{
$refs
[
ref
]
=
[];
}
$refs
[
ref
].
push
(
component
.
$vm
||
component
);
});
return
$refs
;
},
});
}
function
findVmByVueId
(
instance
,
vuePid
)
{
// 标准 vue3 中 没有 $children,定制了内核
const
$children
=
instance
.
$children
;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
childVm
=
$children
[
i
];
if
(
childVm
.
$scope
.
_$vueId
===
vuePid
)
{
return
childVm
;
}
}
// 反向递归查找
let
parentVm
;
for
(
let
i
=
$children
.
length
-
1
;
i
>=
0
;
i
--
)
{
parentVm
=
findVmByVueId
(
$children
[
i
],
vuePid
);
if
(
parentVm
)
{
return
parentVm
;
}
}
}
const
PROP_TYPES
=
[
String
,
Number
,
Boolean
,
Object
,
Array
,
null
];
function
createObserver
(
name
)
{
return
function
observer
(
newVal
)
{
...
...
@@ -665,7 +612,7 @@ function initDefaultProps(isBehavior = false) {
};
}
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties
.
v
ueSlots
=
{
properties
.
v
S
=
{
type
:
null
,
value
:
[],
observer
:
function
(
newVal
)
{
...
...
@@ -798,252 +745,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) {
componentOptions
.
behaviors
=
initBehaviors
(
vueOptions
,
initBehavior
);
}
function
getExtraValue
(
instance
,
dataPathsArray
)
{
let
context
=
instance
;
dataPathsArray
.
forEach
((
dataPathArray
)
=>
{
const
dataPath
=
dataPathArray
[
0
];
const
value
=
dataPathArray
[
2
];
if
(
dataPath
||
typeof
value
!==
'
undefined
'
)
{
// ['','',index,'disable']
const
propPath
=
dataPathArray
[
1
];
const
valuePath
=
dataPathArray
[
3
];
let
vFor
;
if
(
Number
.
isInteger
(
dataPath
))
{
vFor
=
dataPath
;
}
else
if
(
!
dataPath
)
{
vFor
=
context
;
}
else
if
(
typeof
dataPath
===
'
string
'
&&
dataPath
)
{
if
(
dataPath
.
indexOf
(
'
#s#
'
)
===
0
)
{
vFor
=
dataPath
.
substr
(
3
);
}
else
{
vFor
=
getTarget
(
context
,
dataPath
);
}
}
if
(
Number
.
isInteger
(
vFor
))
{
context
=
value
;
}
else
if
(
!
propPath
)
{
context
=
vFor
[
value
];
}
else
{
if
(
isArray
(
vFor
))
{
context
=
vFor
.
find
((
vForItem
)
=>
{
return
getTarget
(
vForItem
,
propPath
)
===
value
;
});
}
else
if
(
isPlainObject
(
vFor
))
{
context
=
Object
.
keys
(
vFor
).
find
((
vForKey
)
=>
{
return
getTarget
(
vFor
[
vForKey
],
propPath
)
===
value
;
});
}
else
{
console
.
error
(
'
v-for 暂不支持循环数据:
'
,
vFor
);
}
}
if
(
valuePath
)
{
context
=
getTarget
(
context
,
valuePath
);
}
}
});
return
context
;
}
function
processEventExtra
(
instance
,
extra
,
event
)
{
const
extraObj
=
{};
if
(
isArray
(
extra
)
&&
extra
.
length
)
{
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra
.
forEach
((
dataPath
,
index
)
=>
{
if
(
typeof
dataPath
===
'
string
'
)
{
if
(
!
dataPath
)
{
// model,prop.sync
extraObj
[
'
$
'
+
index
]
=
instance
;
}
else
{
if
(
dataPath
===
'
$event
'
)
{
// $event
extraObj
[
'
$
'
+
index
]
=
event
;
}
else
if
(
dataPath
===
'
arguments
'
)
{
if
(
event
.
detail
&&
event
.
detail
.
__args__
)
{
extraObj
[
'
$
'
+
index
]
=
event
.
detail
.
__args__
;
}
else
{
extraObj
[
'
$
'
+
index
]
=
[
event
];
}
}
else
if
(
dataPath
.
indexOf
(
'
$event.
'
)
===
0
)
{
// $event.target.value
extraObj
[
'
$
'
+
index
]
=
getTarget
(
event
,
dataPath
.
replace
(
'
$event.
'
,
''
));
}
else
{
extraObj
[
'
$
'
+
index
]
=
getTarget
(
instance
,
dataPath
);
}
}
}
else
{
extraObj
[
'
$
'
+
index
]
=
getExtraValue
(
instance
,
dataPath
);
}
});
}
return
extraObj
;
}
function
getObjByArray
(
arr
)
{
const
obj
=
{};
for
(
let
i
=
1
;
i
<
arr
.
length
;
i
++
)
{
const
element
=
arr
[
i
];
obj
[
element
[
0
]]
=
element
[
1
];
}
return
obj
;
}
function
processEventArgs
(
instance
,
event
,
args
=
[],
extra
=
[],
isCustom
,
methodName
)
{
let
isCustomMPEvent
=
false
;
// wxcomponent 组件,传递原始 event 对象
if
(
isCustom
)
{
// 自定义事件
isCustomMPEvent
=
event
.
currentTarget
&&
event
.
currentTarget
.
dataset
&&
event
.
currentTarget
.
dataset
.
comType
===
'
wx
'
;
if
(
!
args
.
length
)
{
// 无参数,直接传入 event 或 detail 数组
if
(
isCustomMPEvent
)
{
return
[
event
];
}
return
event
.
detail
.
__args__
||
event
.
detail
;
}
}
const
extraObj
=
processEventExtra
(
instance
,
extra
,
event
);
const
ret
=
[];
args
.
forEach
((
arg
)
=>
{
if
(
arg
===
'
$event
'
)
{
if
(
methodName
===
'
__set_model
'
&&
!
isCustom
)
{
// input v-model value
ret
.
push
(
event
.
target
.
value
);
}
else
{
if
(
isCustom
&&
!
isCustomMPEvent
)
{
ret
.
push
(
event
.
detail
.
__args__
[
0
]);
}
else
{
// wxcomponent 组件或内置组件
ret
.
push
(
event
);
}
}
}
else
{
if
(
isArray
(
arg
)
&&
arg
[
0
]
===
'
o
'
)
{
ret
.
push
(
getObjByArray
(
arg
));
}
else
if
(
typeof
arg
===
'
string
'
&&
hasOwn
(
extraObj
,
arg
))
{
ret
.
push
(
extraObj
[
arg
]);
}
else
{
ret
.
push
(
arg
);
}
}
});
return
ret
;
}
function
wrapper
(
event
)
{
event
.
stopPropagation
=
NOOP
;
event
.
preventDefault
=
NOOP
;
event
.
target
=
event
.
target
||
{};
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
return
event
;
}
const
ONCE
=
'
~
'
;
const
CUSTOM
=
'
^
'
;
function
matchEventType
(
eventType
,
optType
)
{
return
(
eventType
===
optType
||
(
optType
===
'
regionchange
'
&&
(
eventType
===
'
begin
'
||
eventType
===
'
end
'
)));
}
function
handleEvent
(
event
)
{
event
=
wrapper
(
event
);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const
dataset
=
(
event
.
currentTarget
||
event
.
target
).
dataset
;
if
(
!
dataset
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
const
eventOpts
=
(
dataset
.
eventOpts
||
dataset
[
'
event-opts
'
]);
// 支付宝 web-view 组件 dataset 非驼峰
if
(
!
eventOpts
)
{
return
console
.
warn
(
'
事件信息不存在
'
);
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const
eventType
=
event
.
type
;
const
ret
=
[];
eventOpts
.
forEach
((
eventOpt
)
=>
{
let
type
=
eventOpt
[
0
];
const
eventsArray
=
eventOpt
[
1
];
const
isCustom
=
type
.
charAt
(
0
)
===
CUSTOM
;
type
=
isCustom
?
type
.
slice
(
1
)
:
type
;
const
isOnce
=
type
.
charAt
(
0
)
===
ONCE
;
type
=
isOnce
?
type
.
slice
(
1
)
:
type
;
if
(
eventsArray
&&
matchEventType
(
eventType
,
type
))
{
eventsArray
.
forEach
((
eventArray
)
=>
{
const
methodName
=
eventArray
[
0
];
if
(
methodName
)
{
let
handlerCtx
=
this
.
$vm
;
if
(
handlerCtx
.
$options
.
generic
&&
handlerCtx
.
$parent
&&
handlerCtx
.
$parent
.
$parent
)
{
// mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx
=
handlerCtx
.
$parent
.
$parent
;
}
if
(
methodName
===
'
$emit
'
)
{
handlerCtx
.
$emit
.
apply
(
handlerCtx
,
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
));
return
;
}
const
handler
=
handlerCtx
[
methodName
];
if
(
!
isFunction
(
handler
))
{
throw
new
Error
(
` _vm.
${
methodName
}
is not a function`
);
}
if
(
isOnce
)
{
if
(
handler
.
once
)
{
return
;
}
handler
.
once
=
true
;
}
let
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
);
params
=
Array
.
isArray
(
params
)
?
params
:
[];
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
if
(
/=
\s
*
\S
+
\.
eventParams
\s
*
\|\|\s
*
\S
+
\[[
'"
]
event-params
[
'"
]\]
/
.
test
(
handler
.
toString
()))
{
// eslint-disable-next-line no-sparse-arrays
params
=
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
]);
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
));
}
});
}
});
if
(
eventType
===
'
input
'
&&
ret
.
length
===
1
&&
typeof
ret
[
0
]
!==
'
undefined
'
)
{
return
ret
[
0
];
}
}
function
parseComponent
(
vueOptions
,
{
parse
,
mocks
,
isPage
,
initRelation
,
handleLink
,
initLifetimes
,
})
{
vueOptions
=
vueOptions
.
default
||
vueOptions
;
const
options
=
{
...
...
@@ -1069,7 +770,6 @@ function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handle
},
methods
:
{
__l
:
handleLink
,
__e
:
handleEvent
,
},
};
if
(
__VUE_OPTIONS_API__
)
{
...
...
@@ -1271,7 +971,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
},
{
mpType
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
,
options
)
{
initRefs
(
instance
,
mpInstance
);
...
...
packages/uni-mp-toutiao/src/runtime/componentLifetimes.ts
浏览文件 @
ae7ec06d
...
...
@@ -43,7 +43,7 @@ export function initLifetimes({
{
mpType
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
// vueSlots
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
:
ComponentInternalInstance
,
...
...
packages/uni-mp-vue/__tests__/withScopedSlot.spec.ts
0 → 100644
浏览文件 @
ae7ec06d
import
{
initScopedSlotDataByPath
}
from
'
../src/helpers/withScopedSlot
'
const
tests
:
Record
<
string
,
Data
>
=
{
a
:
{
a
:
[{
a
:
1
}],
},
'
a.b
'
:
{
a
:
{
b
:
[{
a
:
1
}],
},
},
'
a.0.b
'
:
{
a
:
[
{
b
:
[{
a
:
1
}],
},
],
},
'
a.1.b
'
:
{
a
:
createArrayData
(
1
,
{
b
:
[{
a
:
1
}]
}),
},
'
a.1.b.2.c.b
'
:
{
a
:
createArrayData
(
1
,
{
b
:
createArrayData
(
2
,
{
c
:
{
b
:
[{
a
:
1
}]
}
})
}),
},
}
function
createArrayData
(
index
:
number
,
data
:
Data
)
{
const
arr
=
[]
arr
[
index
]
=
data
return
arr
}
describe
(
'
uni-mp-vue: withScopedSlot
'
,
()
=>
{
Object
.
keys
(
tests
).
forEach
((
path
)
=>
{
test
(
path
,
()
=>
{
const
data
=
{}
initScopedSlotDataByPath
(
path
,
{
a
:
1
},
data
)
expect
(
data
).
toMatchObject
(
tests
[
path
])
})
})
})
packages/uni-mp-vue/build.json
浏览文件 @
ae7ec06d
...
...
@@ -10,7 +10,7 @@
}
]
},
"external"
:
[
"@vue/shared"
],
"external"
:
[
"@vue/shared"
,
"@dcloudio/uni-shared"
],
"replacements"
:
{
"__PLATFORM__"
:
"
\"
mp-weixin
\"
"
}
...
...
packages/uni-mp-vue/dist/vue.runtime.esm.js
浏览文件 @
ae7ec06d
import
{
extend
,
isSymbol
,
isObject
,
toRawType
,
def
,
hasChanged
,
isArray
,
isFunction
,
NOOP
,
remove
,
toHandlerKey
,
camelize
,
capitalize
,
isString
,
normalizeClass
,
normalizeStyle
,
isOn
,
isPromise
,
EMPTY_OBJ
,
isSet
,
isMap
,
isPlainObject
,
invokeArrayFns
,
hasOwn
,
NO
,
isIntegerKey
,
toNumber
,
hyphenate
,
isReservedProp
,
EMPTY_ARR
,
makeMap
,
toTypeString
,
stringifyStyle
as
stringifyStyle$1
}
from
'
@vue/shared
'
;
import
{
extend
,
isSymbol
,
isObject
,
toRawType
,
def
,
hasChanged
,
isArray
,
isFunction
,
NOOP
,
remove
,
toHandlerKey
,
camelize
,
capitalize
,
isString
,
normalizeClass
,
normalizeStyle
,
isOn
,
isPromise
,
EMPTY_OBJ
,
isSet
,
isMap
,
isPlainObject
,
toTypeString
,
invokeArrayFns
,
hasOwn
,
NO
,
isIntegerKey
,
toNumber
,
hyphenate
,
isReservedProp
,
EMPTY_ARR
,
makeMap
,
stringifyStyle
as
stringifyStyle$1
}
from
'
@vue/shared
'
;
export
{
camelize
as
c
,
camelize
,
extend
as
e
,
hyphenate
as
h
,
normalizeClass
as
n
,
normalizeClass
,
normalizeProps
,
normalizeStyle
,
toDisplayString
as
t
,
toDisplayString
,
toHandlerKey
}
from
'
@vue/shared
'
;
// lifecycle
// App and Page
const
ON_SHOW
=
'
onShow
'
;
const
ON_HIDE
=
'
onHide
'
;
//App
const
ON_LAUNCH
=
'
onLaunch
'
;
const
ON_ERROR
=
'
onError
'
;
const
ON_THEME_CHANGE
=
'
onThemeChange
'
;
const
ON_PAGE_NOT_FOUND
=
'
onPageNotFound
'
;
const
ON_UNHANDLE_REJECTION
=
'
onUnhandledRejection
'
;
//Page
const
ON_LOAD
=
'
onLoad
'
;
const
ON_READY
=
'
onReady
'
;
const
ON_UNLOAD
=
'
onUnload
'
;
const
ON_RESIZE
=
'
onResize
'
;
const
ON_BACK_PRESS
=
'
onBackPress
'
;
const
ON_PAGE_SCROLL
=
'
onPageScroll
'
;
const
ON_TAB_ITEM_TAP
=
'
onTabItemTap
'
;
const
ON_REACH_BOTTOM
=
'
onReachBottom
'
;
const
ON_PULL_DOWN_REFRESH
=
'
onPullDownRefresh
'
;
const
ON_SHARE_TIMELINE
=
'
onShareTimeline
'
;
const
ON_ADD_TO_FAVORITES
=
'
onAddToFavorites
'
;
const
ON_SHARE_APP_MESSAGE
=
'
onShareAppMessage
'
;
// navigationBar
const
ON_NAVIGATION_BAR_BUTTON_TAP
=
'
onNavigationBarButtonTap
'
;
const
ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED
=
'
onNavigationBarSearchInputClicked
'
;
const
ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED
=
'
onNavigationBarSearchInputChanged
'
;
const
ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED
=
'
onNavigationBarSearchInputConfirmed
'
;
const
ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
=
'
onNavigationBarSearchInputFocusChanged
'
;
const
PAGE_HOOKS
=
[
ON_SHOW
,
ON_HIDE
,
ON_BACK_PRESS
,
ON_PAGE_SCROLL
,
ON_TAB_ITEM_TAP
,
ON_REACH_BOTTOM
,
ON_PULL_DOWN_REFRESH
,
];
function
isRootHook
(
name
)
{
return
PAGE_HOOKS
.
indexOf
(
name
)
>
-
1
;
}
const
UniLifecycleHooks
=
[
ON_SHOW
,
ON_HIDE
,
ON_LAUNCH
,
ON_ERROR
,
ON_THEME_CHANGE
,
ON_PAGE_NOT_FOUND
,
ON_UNHANDLE_REJECTION
,
ON_LOAD
,
ON_READY
,
ON_UNLOAD
,
ON_RESIZE
,
ON_BACK_PRESS
,
ON_PAGE_SCROLL
,
ON_TAB_ITEM_TAP
,
ON_REACH_BOTTOM
,
ON_PULL_DOWN_REFRESH
,
ON_SHARE_TIMELINE
,
ON_ADD_TO_FAVORITES
,
ON_SHARE_APP_MESSAGE
,
ON_NAVIGATION_BAR_BUTTON_TAP
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
,
];
import
{
isRootHook
,
ON_ERROR
,
UniLifecycleHooks
}
from
'
@dcloudio/uni-shared
'
;
function
warn
(
msg
,
...
args
)
{
console
.
warn
(
`[Vue warn]
${
msg
}
`
,
...
args
);
...
...
@@ -4547,7 +4479,7 @@ function getMPInstanceData(instance, keys) {
});
return
ret
;
}
function
patch
(
instance
,
data
)
{
function
patch
(
instance
,
data
,
oldData
)
{
if
(
!
data
)
{
return
;
}
...
...
@@ -4563,7 +4495,7 @@ function patch(instance, data) {
const
mpInstance
=
ctx
.
$scope
;
const
keys
=
Object
.
keys
(
data
);
// data.__webviewId__ = mpInstance.data.__webviewId__
const
diffData
=
diff
(
data
,
getMPInstanceData
(
mpInstance
,
keys
));
const
diffData
=
diff
(
data
,
oldData
||
getMPInstanceData
(
mpInstance
,
keys
));
if
(
Object
.
keys
(
diffData
).
length
)
{
console
.
log
(
'
[
'
+
+
new
Date
()
+
...
...
@@ -5031,10 +4963,27 @@ function createInvoker(initialValue, instance) {
invoker
.
value
=
initialValue
;
return
invoker
;
}
function
patchMPEvent
(
e
)
{
if
(
e
.
type
&&
e
.
target
)
{
e
.
stopPropagation
=
()
=>
{
};
e
.
preventDefault
=
()
=>
{
};
function
patchMPEvent
(
event
)
{
if
(
event
.
type
&&
event
.
target
)
{
event
.
preventDefault
=
NOOP
;
event
.
stopPropagation
=
NOOP
;
event
.
stopImmediatePropagation
=
NOOP
;
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{};
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{};
event
.
detail
.
markerId
=
event
.
markerId
;
}
// mp-baidu,checked=>value
if
(
isPlainObject
(
event
.
detail
)
&&
hasOwn
(
event
.
detail
,
'
checked
'
)
&&
!
hasOwn
(
event
.
detail
,
'
value
'
))
{
event
.
detail
.
value
=
event
.
detail
.
checked
;
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
);
}
}
}
function
patchStopImmediatePropagation
(
e
,
value
)
{
...
...
@@ -5051,6 +5000,64 @@ function patchStopImmediatePropagation(e, value) {
}
}
function
renderSlot
(
name
,
props
=
{})
{
const
instance
=
getCurrentInstance
();
const
vueIds
=
instance
.
attrs
.
vI
;
if
(
!
vueIds
)
{
return
;
}
const
invoker
=
findScopedSlotInvoker
(
vueIds
.
split
(
'
,
'
)[
0
],
instance
);
if
(
invoker
)
{
invoker
(
name
,
props
);
}
else
{
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
)
{
console
.
error
(
'
scoped slot invoker not found
'
,
vueIds
,
name
,
props
);
}
}
}
function
findScopedSlotInvoker
(
vueId
,
instance
)
{
let
parent
=
instance
.
parent
;
while
(
parent
)
{
const
invokers
=
parent
.
$ssi
;
if
(
invokers
&&
invokers
[
vueId
])
{
return
invokers
[
vueId
];
}
parent
=
parent
.
parent
;
}
}
//@ts-ignore
function
withScopedSlot
(
fn
,
{
name
,
path
,
vueId
,
})
{
fn
.
path
=
path
;
const
instance
=
getCurrentInstance
();
const
scopedSlots
=
(
instance
.
$ssi
||
(
instance
.
$ssi
=
{}));
const
invoker
=
scopedSlots
[
vueId
]
||
(
scopedSlots
[
vueId
]
=
createScopedSlotInvoker
(
instance
));
if
(
!
invoker
.
slots
[
name
])
{
invoker
.
slots
[
name
]
=
{
data
:
{},
fn
,
};
}
else
{
invoker
.
slots
[
name
].
fn
=
fn
;
}
// 返回单元素数组,因为 scoped slot 被转换成了 for 循环
return
[
invoker
.
slots
[
name
].
data
];
}
function
createScopedSlotInvoker
(
instance
)
{
const
invoker
=
(
slotName
,
args
)
=>
{
const
slot
=
invoker
.
slots
[
slotName
];
slot
.
data
=
slot
.
fn
(
args
,
0
,
0
);
// TODO 简单的 forceUpdate,理论上,可以仅对 scoped slot 部分数据 diff 更新
instance
.
proxy
.
$forceUpdate
();
};
invoker
.
slots
=
{};
return
invoker
;
}
function
stringifyStyle
(
value
)
{
if
(
isString
(
value
))
{
return
value
;
...
...
@@ -5068,4 +5075,4 @@ function createApp(rootComponent, rootProps = null) {
}
const
createSSRApp
=
createApp
;
export
{
EffectScope
,
ReactiveEffect
,
callWithAsyncErrorHandling
,
callWithErrorHandling
,
computed
,
createApp
,
createSSRApp
,
createVNode$1
as
createVNode
,
createVueApp
,
customRef
,
defineComponent
,
defineEmits
,
defineExpose
,
defineProps
,
effect
,
effectScope
,
vFor
as
f
,
getCurrentInstance
,
getCurrentScope
,
inject
,
injectHook
,
isInSSRComponentSetup
,
isProxy
,
isReactive
,
isReadonly
,
isRef
,
logError
,
markRaw
,
mergeDefaults
,
mergeProps
,
nextTick
,
vOn
as
o
,
onActivated
,
onBeforeMount
,
onBeforeUnmount
,
onBeforeUpdate
,
onDeactivated
,
onErrorCaptured
,
onMounted
,
onRenderTracked
,
onRenderTriggered
,
onScopeDispose
,
onUnmounted
,
onUpdated
,
p
rovide
,
proxyRefs
,
queuePostFlushCb
,
reactive
,
readonly
,
ref
,
resolveComponent
,
resolveDirective
,
resolveFilter
,
stringifyStyle
as
s
,
setupDevtoolsPlugin
,
shallowReactive
,
shallowReadonly
,
shallowRef
,
stop
,
toHandlers
,
toRaw
,
toRef
,
toRefs
,
triggerRef
,
unref
,
useAttrs
,
useSSRContext
,
useSlots
,
version
,
warn$1
as
warn
,
watch
,
watchEffect
,
watchPostEffect
,
watchSyncEffect
,
withAsyncContext
,
withCtx
,
withDefaults
,
withDirectives
,
withModifiers
,
withScopeId
};
export
{
EffectScope
,
ReactiveEffect
,
callWithAsyncErrorHandling
,
callWithErrorHandling
,
computed
,
createApp
,
createSSRApp
,
createVNode$1
as
createVNode
,
createVueApp
,
customRef
,
defineComponent
,
defineEmits
,
defineExpose
,
defineProps
,
effect
,
effectScope
,
vFor
as
f
,
getCurrentInstance
,
getCurrentScope
,
inject
,
injectHook
,
isInSSRComponentSetup
,
isProxy
,
isReactive
,
isReadonly
,
isRef
,
logError
,
markRaw
,
mergeDefaults
,
mergeProps
,
nextTick
,
vOn
as
o
,
onActivated
,
onBeforeMount
,
onBeforeUnmount
,
onBeforeUpdate
,
onDeactivated
,
onErrorCaptured
,
onMounted
,
onRenderTracked
,
onRenderTriggered
,
onScopeDispose
,
onUnmounted
,
onUpdated
,
p
atch
,
provide
,
proxyRefs
,
queuePostFlushCb
,
renderSlot
as
r
,
reactive
,
readonly
,
ref
,
resolveComponent
,
resolveDirective
,
resolveFilter
,
stringifyStyle
as
s
,
setupDevtoolsPlugin
,
shallowReactive
,
shallowReadonly
,
shallowRef
,
stop
,
toHandlers
,
toRaw
,
toRef
,
toRefs
,
triggerRef
,
unref
,
useAttrs
,
useSSRContext
,
useSlots
,
version
,
withScopedSlot
as
w
,
warn$1
as
warn
,
watch
,
watchEffect
,
watchPostEffect
,
watchSyncEffect
,
withAsyncContext
,
withCtx
,
withDefaults
,
withDirectives
,
withModifiers
,
withScopeId
};
packages/uni-mp-vue/lib/vue.runtime.esm.js
浏览文件 @
ae7ec06d
...
...
@@ -4479,7 +4479,7 @@ function getMPInstanceData(instance, keys) {
});
return
ret
;
}
function
patch
(
instance
,
data
)
{
function
patch
(
instance
,
data
,
oldData
)
{
if
(
!
data
)
{
return
;
}
...
...
@@ -4495,7 +4495,7 @@ function patch(instance, data) {
const
mpInstance
=
ctx
.
$scope
;
const
keys
=
Object
.
keys
(
data
);
// data.__webviewId__ = mpInstance.data.__webviewId__
const
diffData
=
diff
(
data
,
getMPInstanceData
(
mpInstance
,
keys
));
const
diffData
=
diff
(
data
,
oldData
||
getMPInstanceData
(
mpInstance
,
keys
));
if
(
Object
.
keys
(
diffData
).
length
)
{
console
.
log
(
'
[
'
+
+
new
Date
()
+
...
...
@@ -4720,4 +4720,4 @@ function createVueApp(rootComponent, rootProps = null) {
function
withModifiers
()
{
}
function
createVNode$1
()
{
}
export
{
EffectScope
,
ReactiveEffect
,
callWithAsyncErrorHandling
,
callWithErrorHandling
,
computed
,
createVNode$1
as
createVNode
,
createVueApp
,
customRef
,
defineComponent
,
defineEmits
,
defineExpose
,
defineProps
,
effect
,
effectScope
,
getCurrentInstance
,
getCurrentScope
,
inject
,
injectHook
,
isInSSRComponentSetup
,
isProxy
,
isReactive
,
isReadonly
,
isRef
,
logError
,
markRaw
,
mergeDefaults
,
mergeProps
,
nextTick
,
onActivated
,
onBeforeMount
,
onBeforeUnmount
,
onBeforeUpdate
,
onDeactivated
,
onErrorCaptured
,
onMounted
,
onRenderTracked
,
onRenderTriggered
,
onScopeDispose
,
onUnmounted
,
onUpdated
,
provide
,
proxyRefs
,
queuePostFlushCb
,
reactive
,
readonly
,
ref
,
resolveComponent
,
resolveDirective
,
resolveFilter
,
shallowReactive
,
shallowReadonly
,
shallowRef
,
stop
,
toHandlers
,
toRaw
,
toRef
,
toRefs
,
triggerRef
,
unref
,
useAttrs
,
useSSRContext
,
useSlots
,
version
,
warn$1
as
warn
,
watch
,
watchEffect
,
watchPostEffect
,
watchSyncEffect
,
withAsyncContext
,
withCtx
,
withDefaults
,
withDirectives
,
withModifiers
,
withScopeId
};
export
{
EffectScope
,
ReactiveEffect
,
callWithAsyncErrorHandling
,
callWithErrorHandling
,
computed
,
createVNode$1
as
createVNode
,
createVueApp
,
customRef
,
defineComponent
,
defineEmits
,
defineExpose
,
defineProps
,
effect
,
effectScope
,
getCurrentInstance
,
getCurrentScope
,
inject
,
injectHook
,
isInSSRComponentSetup
,
isProxy
,
isReactive
,
isReadonly
,
isRef
,
logError
,
markRaw
,
mergeDefaults
,
mergeProps
,
nextTick
,
onActivated
,
onBeforeMount
,
onBeforeUnmount
,
onBeforeUpdate
,
onDeactivated
,
onErrorCaptured
,
onMounted
,
onRenderTracked
,
onRenderTriggered
,
onScopeDispose
,
onUnmounted
,
onUpdated
,
p
atch
,
p
rovide
,
proxyRefs
,
queuePostFlushCb
,
reactive
,
readonly
,
ref
,
resolveComponent
,
resolveDirective
,
resolveFilter
,
shallowReactive
,
shallowReadonly
,
shallowRef
,
stop
,
toHandlers
,
toRaw
,
toRef
,
toRefs
,
triggerRef
,
unref
,
useAttrs
,
useSSRContext
,
useSlots
,
version
,
warn$1
as
warn
,
watch
,
watchEffect
,
watchPostEffect
,
watchSyncEffect
,
withAsyncContext
,
withCtx
,
withDefaults
,
withDirectives
,
withModifiers
,
withScopeId
};
packages/uni-mp-vue/src/helpers/index.ts
浏览文件 @
ae7ec06d
export
{
vFor
}
from
'
./vFor
'
export
{
vOn
}
from
'
./vOn
'
export
{
renderSlot
}
from
'
./renderSlot
'
export
{
withScopedSlot
}
from
'
./withScopedSlot
'
export
{
stringifyStyle
}
from
'
./style
'
export
{
setupDevtoolsPlugin
}
from
'
./devtools
'
packages/uni-mp-vue/src/helpers/renderSlot.ts
0 → 100644
浏览文件 @
ae7ec06d
import
type
{
ComponentInternalInstance
}
from
'
vue
'
import
type
{
ScopedSlotInvokers
}
from
'
./withScopedSlot
'
import
{
getCurrentInstance
}
from
'
vue
'
export
function
renderSlot
(
name
:
string
,
props
:
Data
=
{})
{
const
instance
=
getCurrentInstance
()
as
ComponentInternalInstance
const
vueIds
=
instance
.
attrs
.
vI
as
string
if
(
!
vueIds
)
{
return
}
const
invoker
=
findScopedSlotInvoker
(
vueIds
.
split
(
'
,
'
)[
0
],
instance
)
if
(
invoker
)
{
invoker
(
name
,
props
)
}
else
{
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
)
{
console
.
error
(
'
scoped slot invoker not found
'
,
vueIds
,
name
,
props
)
}
}
}
function
findScopedSlotInvoker
(
vueId
:
string
,
instance
:
ComponentInternalInstance
)
{
let
parent
=
instance
.
parent
while
(
parent
)
{
const
invokers
=
(
parent
as
any
).
$ssi
as
ScopedSlotInvokers
if
(
invokers
&&
invokers
[
vueId
])
{
return
invokers
[
vueId
]
}
parent
=
parent
.
parent
}
}
packages/uni-mp-vue/src/helpers/vOn.ts
浏览文件 @
ae7ec06d
import
{
isArray
}
from
'
@vue/shared
'
import
{
extend
,
isArray
,
isPlainObject
,
hasOwn
,
NOOP
}
from
'
@vue/shared
'
import
{
callWithAsyncErrorHandling
,
ComponentInternalInstance
,
...
...
@@ -8,7 +8,8 @@ import {
type
EventValue
=
Function
|
Function
[]
interface
Invoker
extends
EventListener
{
interface
Invoker
{
(
evt
:
MPEvent
):
void
value
:
EventValue
}
...
...
@@ -38,17 +39,20 @@ export function vOn(value: EventValue | undefined) {
return
name
}
interface
MPEvent
extends
Event
{
detail
:
{
interface
MPEvent
extends
WechatMiniprogram
.
Base
Event
{
detail
:
Record
<
string
,
any
>
&
{
__args__
?:
unknown
[]
}
preventDefault
:
()
=>
void
stopPropagation
:
()
=>
void
stopImmediatePropagation
:
()
=>
void
}
function
createInvoker
(
initialValue
:
EventValue
,
instance
:
ComponentInternalInstance
|
null
)
{
const
invoker
:
Invoker
=
(
e
:
Event
)
=>
{
const
invoker
:
Invoker
=
(
e
:
MP
Event
)
=>
{
patchMPEvent
(
e
)
let
args
:
unknown
[]
=
[
e
]
if
((
e
as
MPEvent
).
detail
&&
(
e
as
MPEvent
).
detail
.
__args__
)
{
...
...
@@ -65,15 +69,36 @@ function createInvoker(
return
invoker
}
function
patchMPEvent
(
e
:
Event
)
{
if
(
e
.
type
&&
e
.
target
)
{
e
.
stopPropagation
=
()
=>
{}
e
.
preventDefault
=
()
=>
{}
function
patchMPEvent
(
event
:
MPEvent
)
{
if
(
event
.
type
&&
event
.
target
)
{
event
.
preventDefault
=
NOOP
event
.
stopPropagation
=
NOOP
event
.
stopImmediatePropagation
=
NOOP
if
(
!
hasOwn
(
event
,
'
detail
'
))
{
event
.
detail
=
{}
}
if
(
hasOwn
(
event
,
'
markerId
'
))
{
event
.
detail
=
typeof
event
.
detail
===
'
object
'
?
event
.
detail
:
{}
event
.
detail
.
markerId
=
(
event
as
any
).
markerId
}
// mp-baidu,checked=>value
if
(
isPlainObject
(
event
.
detail
)
&&
hasOwn
(
event
.
detail
,
'
checked
'
)
&&
!
hasOwn
(
event
.
detail
,
'
value
'
)
)
{
event
.
detail
.
value
=
event
.
detail
.
checked
}
if
(
isPlainObject
(
event
.
detail
))
{
event
.
target
=
extend
({},
event
.
target
,
event
.
detail
)
}
}
}
function
patchStopImmediatePropagation
(
e
:
Event
,
e
:
MP
Event
,
value
:
EventValue
):
EventValue
{
if
(
isArray
(
value
))
{
...
...
packages/uni-mp-vue/src/helpers/withScopedSlot.ts
0 → 100644
浏览文件 @
ae7ec06d
import
type
{
ComponentInternalInstance
}
from
'
vue
'
//@ts-ignore
import
{
patch
,
getCurrentInstance
}
from
'
vue
'
export
interface
ScopedSlotInvokers
{
[
vueId
:
string
]:
ScopedSlotInvoker
}
interface
ScopedSlotFn
{
(
args
:
Data
,
key
:
number
,
index
:
number
):
Record
<
string
,
any
>
path
:
string
}
interface
ScopedSlotInvoker
{
(
slotName
:
string
,
args
:
Data
):
void
slots
:
{
[
slotName
:
string
]:
{
fn
:
ScopedSlotFn
data
:
Data
}
}
}
export
function
withScopedSlot
(
fn
:
ScopedSlotFn
,
{
name
,
path
,
vueId
,
}:
{
name
:
string
path
:
string
vueId
:
string
}
)
{
fn
.
path
=
path
const
instance
=
getCurrentInstance
()
as
ComponentInternalInstance
const
scopedSlots
=
((
instance
as
any
).
$ssi
||
(((
instance
as
any
).
$ssi
as
ScopedSlotInvokers
)
=
{}))
as
ScopedSlotInvokers
const
invoker
=
scopedSlots
[
vueId
]
||
(
scopedSlots
[
vueId
]
=
createScopedSlotInvoker
(
instance
))
if
(
!
invoker
.
slots
[
name
])
{
invoker
.
slots
[
name
]
=
{
data
:
{},
fn
,
}
}
else
{
invoker
.
slots
[
name
].
fn
=
fn
}
// 返回单元素数组,因为 scoped slot 被转换成了 for 循环
return
[
invoker
.
slots
[
name
].
data
]
}
function
createScopedSlotInvoker
(
instance
:
ComponentInternalInstance
)
{
const
invoker
:
ScopedSlotInvoker
=
(
slotName
:
string
,
args
:
Data
)
=>
{
const
slot
=
invoker
.
slots
[
slotName
]
slot
.
data
=
slot
.
fn
(
args
,
0
,
0
)
// TODO 简单的 forceUpdate,理论上,可以仅对 scoped slot 部分数据 diff 更新
instance
.
proxy
!
.
$forceUpdate
()
}
invoker
.
slots
=
{}
return
invoker
}
const
nubmerRE
=
/^
\d
+$/
function
isInteger
(
str
:
unknown
):
str
is
number
{
return
nubmerRE
.
test
(
str
as
string
)
}
/**
* 暂时没啥用,原本计划仅对 scoped slot 数据部分做 diff 更新,现在还是先简单的 forceUpdate,让宿主整体更新吧
* @param path
* @param scopedSlotData
* @param data
* @returns
*/
export
function
initScopedSlotDataByPath
(
path
:
string
,
scopedSlotData
:
Data
,
data
:
Data
|
Data
[]
):
void
{
const
parts
=
path
.
split
(
'
.
'
)
const
len
=
parts
.
length
const
key
:
string
=
parts
[
0
]
if
(
len
===
1
)
{
;(
data
as
Data
)[
key
]
=
[
scopedSlotData
]
return
}
const
next
:
string
=
parts
[
1
]
let
nextData
:
Data
|
Data
[]
if
(
isInteger
(
next
))
{
// a.0 => {a:[]}
;(
data
as
Data
)[
key
]
=
nextData
=
[]
}
else
{
;(
data
as
Data
)[
key
]
=
nextData
=
{}
}
return
initScopedSlotDataByPath
(
parts
.
slice
(
1
).
join
(
'
.
'
),
scopedSlotData
,
nextData
)
}
packages/uni-mp-vue/src/index.ts
浏览文件 @
ae7ec06d
import
plugin
from
'
./plugin
'
// @ts-ignore
import
{
createVueApp
}
from
'
../lib/vue.runtime.esm.js
'
import
{
createVueApp
}
from
'
vue
'
export
function
createApp
(
rootComponent
:
unknown
,
rootProps
=
null
)
{
rootComponent
&&
((
rootComponent
as
any
).
mpType
=
'
app
'
)
return
createVueApp
(
rootComponent
,
rootProps
).
use
(
plugin
)
...
...
@@ -9,6 +9,8 @@ export const createSSRApp = createApp
export
{
vOn
as
o
,
vFor
as
f
,
renderSlot
as
r
,
withScopedSlot
as
w
,
stringifyStyle
as
s
,
setupDevtoolsPlugin
,
}
from
'
./helpers
'
...
...
@@ -20,4 +22,4 @@ export {
toDisplayString
as
t
,
}
from
'
@vue/shared
'
// @ts-ignore
export
*
from
'
../lib/vue.runtime.esm.js
'
export
*
from
'
vue
'
packages/uni-mp-vue/src/state.ts
已删除
100644 → 0
浏览文件 @
f63216a6
import
{
getCurrentInstance
}
from
'
vue
'
export
function
setState
(
name
:
string
,
value
:
unknown
)
{
const
{
__state
}
=
getCurrentInstance
()
!
}
packages/uni-mp-weixin/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
此差异已折叠。
点击以展开。
packages/uni-mp-weixin/src/runtime/lifetimes.ts
浏览文件 @
ae7ec06d
...
...
@@ -42,7 +42,7 @@ export function initLifetimes({
{
mpType
:
isPage
(
mpInstance
)
?
'
page
'
:
'
component
'
,
mpInstance
,
slots
:
properties
.
v
ueSlots
,
slots
:
properties
.
v
S
,
// vueSlots
parentComponent
:
relationOptions
.
parent
&&
relationOptions
.
parent
.
$
,
onBeforeSetup
(
instance
:
ComponentInternalInstance
,
...
...
packages/uni-quickapp-webview/dist/uni.mp.esm.js
浏览文件 @
ae7ec06d
此差异已折叠。
点击以展开。
packages/uni-shared/dist/uni-shared.cjs.js
浏览文件 @
ae7ec06d
...
...
@@ -413,6 +413,18 @@ function formatAppLog(type, filename, ...args) {
res
&&
console
[
type
](
res
);
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
plusReady
(
callback
)
{
if
(
typeof
callback
!==
'
function
'
)
{
return
;
...
...
@@ -1229,6 +1241,7 @@ exports.formatAppLog = formatAppLog;
exports
.
formatDateTime
=
formatDateTime
;
exports
.
formatLog
=
formatLog
;
exports
.
getCustomDataset
=
getCustomDataset
;
exports
.
getDataByPath
=
getDataByPath
;
exports
.
getEnvLocale
=
getEnvLocale
;
exports
.
getLen
=
getLen
;
exports
.
getValueByDataPath
=
getValueByDataPath
;
...
...
packages/uni-shared/dist/uni-shared.d.ts
浏览文件 @
ae7ec06d
...
...
@@ -181,6 +181,8 @@ export declare function formatLog(module: string, ...args: any[]): string;
export
declare
function
getCustomDataset
(
el
:
HTMLElement
|
HTMLElementWithDataset
):
DOMStringMap
&
Record
<
string
,
any
>
;
export
declare
function
getDataByPath
(
obj
:
Record
<
string
|
number
,
any
>
,
path
:
string
):
unknown
;
export
declare
function
getEnvLocale
():
string
;
export
declare
function
getLen
(
str
?:
string
):
number
;
...
...
packages/uni-shared/dist/uni-shared.es.js
浏览文件 @
ae7ec06d
...
...
@@ -409,6 +409,18 @@ function formatAppLog(type, filename, ...args) {
res
&&
console
[
type
](
res
);
}
function
getDataByPath
(
obj
,
path
)
{
const
parts
=
path
.
split
(
'
.
'
);
const
key
=
parts
[
0
];
if
(
!
obj
)
{
obj
=
{};
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
];
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
));
}
function
plusReady
(
callback
)
{
if
(
typeof
callback
!==
'
function
'
)
{
return
;
...
...
@@ -1118,4 +1130,4 @@ function getEnvLocale() {
return
(
lang
&&
lang
.
replace
(
/
[
.:
]
.*/
,
''
))
||
'
en
'
;
}
export
{
ACTION_TYPE_ADD_EVENT
,
ACTION_TYPE_ADD_WXS_EVENT
,
ACTION_TYPE_CREATE
,
ACTION_TYPE_EVENT
,
ACTION_TYPE_INSERT
,
ACTION_TYPE_PAGE_CREATE
,
ACTION_TYPE_PAGE_CREATED
,
ACTION_TYPE_PAGE_SCROLL
,
ACTION_TYPE_REMOVE
,
ACTION_TYPE_REMOVE_ATTRIBUTE
,
ACTION_TYPE_REMOVE_EVENT
,
ACTION_TYPE_SET_ATTRIBUTE
,
ACTION_TYPE_SET_TEXT
,
ATTR_CHANGE_PREFIX
,
ATTR_CLASS
,
ATTR_INNER_HTML
,
ATTR_STYLE
,
ATTR_TEXT_CONTENT
,
ATTR_V_OWNER_ID
,
ATTR_V_RENDERJS
,
ATTR_V_SHOW
,
BACKGROUND_COLOR
,
BUILT_IN_TAGS
,
COMPONENT_NAME_PREFIX
,
COMPONENT_PREFIX
,
COMPONENT_SELECTOR_PREFIX
,
DATA_RE
,
EventChannel
,
EventModifierFlags
,
I18N_JSON_DELIMITERS
,
JSON_PROTOCOL
,
LINEFEED
,
NAVBAR_HEIGHT
,
NODE_TYPE_COMMENT
,
NODE_TYPE_ELEMENT
,
NODE_TYPE_PAGE
,
NODE_TYPE_TEXT
,
ON_ADD_TO_FAVORITES
,
ON_APP_ENTER_BACKGROUND
,
ON_APP_ENTER_FOREGROUND
,
ON_BACK_PRESS
,
ON_ERROR
,
ON_HIDE
,
ON_KEYBOARD_HEIGHT_CHANGE
,
ON_LAUNCH
,
ON_LOAD
,
ON_NAVIGATION_BAR_BUTTON_TAP
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
,
ON_PAGE_NOT_FOUND
,
ON_PAGE_SCROLL
,
ON_PULL_DOWN_REFRESH
,
ON_REACH_BOTTOM
,
ON_REACH_BOTTOM_DISTANCE
,
ON_READY
,
ON_RESIZE
,
ON_SHARE_APP_MESSAGE
,
ON_SHARE_TIMELINE
,
ON_SHOW
,
ON_TAB_ITEM_TAP
,
ON_THEME_CHANGE
,
ON_UNHANDLE_REJECTION
,
ON_UNLOAD
,
ON_WEB_INVOKE_APP_SERVICE
,
ON_WXS_INVOKE_CALL_METHOD
,
PLUS_RE
,
PRIMARY_COLOR
,
RENDERJS_MODULES
,
RESPONSIVE_MIN_WIDTH
,
SCHEME_RE
,
SELECTED_COLOR
,
TABBAR_HEIGHT
,
TAGS
,
UNI_SSR
,
UNI_SSR_DATA
,
UNI_SSR_GLOBAL_DATA
,
UNI_SSR_STORE
,
UNI_SSR_TITLE
,
UniBaseNode
,
UniCommentNode
,
UniElement
,
UniEvent
,
UniInputElement
,
UniLifecycleHooks
,
UniNode
,
UniTextAreaElement
,
UniTextNode
,
WEB_INVOKE_APPSERVICE
,
WXS_MODULES
,
WXS_PROTOCOL
,
addFont
,
cache
,
cacheStringFunction
,
callOptions
,
createRpx2Unit
,
createUniEvent
,
debounce
,
decode
,
decodedQuery
,
defaultMiniProgramRpx2Unit
,
defaultRpx2Unit
,
formatAppLog
,
formatDateTime
,
formatLog
,
getCustomDataset
,
getEnvLocale
,
getLen
,
getValueByDataPath
,
initCustomDataset
,
invokeArrayFns
,
isBuiltInComponent
,
isComponentTag
,
isCustomElement
,
isH5CustomElement
,
isH5NativeTag
,
isNativeTag
,
isRootHook
,
normalizeDataset
,
normalizeEventType
,
normalizeTarget
,
once
,
parseEventName
,
parseQuery
,
parseUrl
,
passive
,
plusReady
,
removeLeadingSlash
,
resolveOwnerEl
,
resolveOwnerVm
,
sanitise
,
scrollTo
,
stringifyQuery
,
updateElementStyle
};
export
{
ACTION_TYPE_ADD_EVENT
,
ACTION_TYPE_ADD_WXS_EVENT
,
ACTION_TYPE_CREATE
,
ACTION_TYPE_EVENT
,
ACTION_TYPE_INSERT
,
ACTION_TYPE_PAGE_CREATE
,
ACTION_TYPE_PAGE_CREATED
,
ACTION_TYPE_PAGE_SCROLL
,
ACTION_TYPE_REMOVE
,
ACTION_TYPE_REMOVE_ATTRIBUTE
,
ACTION_TYPE_REMOVE_EVENT
,
ACTION_TYPE_SET_ATTRIBUTE
,
ACTION_TYPE_SET_TEXT
,
ATTR_CHANGE_PREFIX
,
ATTR_CLASS
,
ATTR_INNER_HTML
,
ATTR_STYLE
,
ATTR_TEXT_CONTENT
,
ATTR_V_OWNER_ID
,
ATTR_V_RENDERJS
,
ATTR_V_SHOW
,
BACKGROUND_COLOR
,
BUILT_IN_TAGS
,
COMPONENT_NAME_PREFIX
,
COMPONENT_PREFIX
,
COMPONENT_SELECTOR_PREFIX
,
DATA_RE
,
EventChannel
,
EventModifierFlags
,
I18N_JSON_DELIMITERS
,
JSON_PROTOCOL
,
LINEFEED
,
NAVBAR_HEIGHT
,
NODE_TYPE_COMMENT
,
NODE_TYPE_ELEMENT
,
NODE_TYPE_PAGE
,
NODE_TYPE_TEXT
,
ON_ADD_TO_FAVORITES
,
ON_APP_ENTER_BACKGROUND
,
ON_APP_ENTER_FOREGROUND
,
ON_BACK_PRESS
,
ON_ERROR
,
ON_HIDE
,
ON_KEYBOARD_HEIGHT_CHANGE
,
ON_LAUNCH
,
ON_LOAD
,
ON_NAVIGATION_BAR_BUTTON_TAP
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED
,
ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
,
ON_PAGE_NOT_FOUND
,
ON_PAGE_SCROLL
,
ON_PULL_DOWN_REFRESH
,
ON_REACH_BOTTOM
,
ON_REACH_BOTTOM_DISTANCE
,
ON_READY
,
ON_RESIZE
,
ON_SHARE_APP_MESSAGE
,
ON_SHARE_TIMELINE
,
ON_SHOW
,
ON_TAB_ITEM_TAP
,
ON_THEME_CHANGE
,
ON_UNHANDLE_REJECTION
,
ON_UNLOAD
,
ON_WEB_INVOKE_APP_SERVICE
,
ON_WXS_INVOKE_CALL_METHOD
,
PLUS_RE
,
PRIMARY_COLOR
,
RENDERJS_MODULES
,
RESPONSIVE_MIN_WIDTH
,
SCHEME_RE
,
SELECTED_COLOR
,
TABBAR_HEIGHT
,
TAGS
,
UNI_SSR
,
UNI_SSR_DATA
,
UNI_SSR_GLOBAL_DATA
,
UNI_SSR_STORE
,
UNI_SSR_TITLE
,
UniBaseNode
,
UniCommentNode
,
UniElement
,
UniEvent
,
UniInputElement
,
UniLifecycleHooks
,
UniNode
,
UniTextAreaElement
,
UniTextNode
,
WEB_INVOKE_APPSERVICE
,
WXS_MODULES
,
WXS_PROTOCOL
,
addFont
,
cache
,
cacheStringFunction
,
callOptions
,
createRpx2Unit
,
createUniEvent
,
debounce
,
decode
,
decodedQuery
,
defaultMiniProgramRpx2Unit
,
defaultRpx2Unit
,
formatAppLog
,
formatDateTime
,
formatLog
,
getCustomDataset
,
get
DataByPath
,
get
EnvLocale
,
getLen
,
getValueByDataPath
,
initCustomDataset
,
invokeArrayFns
,
isBuiltInComponent
,
isComponentTag
,
isCustomElement
,
isH5CustomElement
,
isH5NativeTag
,
isNativeTag
,
isRootHook
,
normalizeDataset
,
normalizeEventType
,
normalizeTarget
,
once
,
parseEventName
,
parseQuery
,
parseUrl
,
passive
,
plusReady
,
removeLeadingSlash
,
resolveOwnerEl
,
resolveOwnerVm
,
sanitise
,
scrollTo
,
stringifyQuery
,
updateElementStyle
};
packages/uni-shared/src/data.ts
0 → 100644
浏览文件 @
ae7ec06d
export
function
getDataByPath
(
obj
:
Record
<
string
|
number
,
any
>
,
path
:
string
):
unknown
{
const
parts
=
path
.
split
(
'
.
'
)
const
key
:
number
|
string
=
parts
[
0
]
if
(
!
obj
)
{
obj
=
{}
}
if
(
parts
.
length
===
1
)
{
return
obj
[
key
]
}
return
getDataByPath
(
obj
[
key
],
parts
.
slice
(
1
).
join
(
'
.
'
))
}
packages/uni-shared/src/index.ts
浏览文件 @
ae7ec06d
...
...
@@ -3,6 +3,7 @@ export * from './log'
export
*
from
'
./dom
'
export
*
from
'
./url
'
export
*
from
'
./hbx
'
export
*
from
'
./data
'
export
*
from
'
./plus
'
export
*
from
'
./tags
'
export
*
from
'
./vdom
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录