@mpxjs/core 2.9.38 → 2.9.41-react.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +37 -3
- package/src/convertor/convertor.js +4 -1
- package/src/convertor/getConvertMode.js +3 -1
- package/src/convertor/wxToReact.js +31 -0
- package/src/core/proxy.js +75 -7
- package/src/core/transferOptions.js +9 -1
- package/src/dynamic/astCache.js +25 -0
- package/src/dynamic/dynamicRenderMixin.js +77 -0
- package/src/dynamic/vnode/context.js +17 -0
- package/src/dynamic/vnode/css-select/cssauron.js +445 -0
- package/src/dynamic/vnode/css-select/index.js +116 -0
- package/src/dynamic/vnode/css-select/through.js +19 -0
- package/src/dynamic/vnode/css-select/tokenizer.js +371 -0
- package/src/dynamic/vnode/interpreter.js +449 -0
- package/src/dynamic/vnode/render.js +289 -0
- package/src/{vuePlugin.js → external/vuePlugin.js} +1 -1
- package/src/index.js +8 -2
- package/src/platform/builtInMixins/directiveHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +15 -0
- package/src/platform/builtInMixins/directiveHelperMixin.js +3 -0
- package/src/platform/builtInMixins/index.js +20 -2
- package/src/platform/builtInMixins/proxyEventMixin.android.js +2 -0
- package/src/platform/builtInMixins/proxyEventMixin.ios.js +49 -0
- package/src/platform/builtInMixins/proxyEventMixin.js +12 -14
- package/src/platform/builtInMixins/refsMixin.android.js +2 -0
- package/src/platform/builtInMixins/refsMixin.ios.js +311 -0
- package/src/platform/builtInMixins/renderHelperMixin.js +2 -2
- package/src/platform/builtInMixins/styleHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +141 -0
- package/src/platform/builtInMixins/styleHelperMixin.js +3 -0
- package/src/platform/createApp.android.js +2 -0
- package/src/platform/createApp.ios.js +103 -0
- package/src/platform/createApp.js +3 -5
- package/src/platform/export/api.web.js +1 -1
- package/src/platform/patch/ali/getDefaultOptions.js +24 -4
- package/src/platform/patch/index.js +9 -6
- package/src/platform/patch/react/getDefaultOptions.android.js +1 -0
- package/src/platform/patch/react/getDefaultOptions.ios.js +270 -0
- package/src/platform/patch/react/getDefaultOptions.js +1 -0
- package/src/platform/patch/swan/getDefaultOptions.js +1 -1
- package/src/platform/patch/web/getDefaultOptions.js +13 -3
- package/src/platform/patch/wx/getDefaultOptions.js +21 -1
- /package/src/{vue.js → external/vue.js} +0 -0
- /package/src/{vue.web.js → external/vue.web.js} +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import cssSelect from './css-select'
|
|
2
|
+
// todo: stringify wxs 模块只能放到逻辑层执行,主要还是因为生成 vdom tree 需要根据 class 去做匹配,需要看下这个代码从哪引入
|
|
3
|
+
import stringify from '@mpxjs/webpack-plugin/lib/runtime/stringify.wxs'
|
|
4
|
+
import Interpreter from './interpreter'
|
|
5
|
+
import { dash2hump, isString, error } from '@mpxjs/utils'
|
|
6
|
+
|
|
7
|
+
const deepCloneNode = function (val) {
|
|
8
|
+
return JSON.parse(JSON.stringify(val))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function simpleNormalizeChildren (children) {
|
|
12
|
+
for (let i = 0; i < children.length; i++) {
|
|
13
|
+
if (Array.isArray(children[i])) {
|
|
14
|
+
return Array.prototype.concat.apply([], children)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return children
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function _genVnodeTree (astData, contextScope, options) {
|
|
21
|
+
const { template = {}, styles = [] } = astData || {}
|
|
22
|
+
const { moduleId, location } = options || {}
|
|
23
|
+
// 解除引用
|
|
24
|
+
const templateAst = deepCloneNode(template)
|
|
25
|
+
// 获取实例 uid
|
|
26
|
+
const uid = contextScope[0]?.__mpxProxy?.uid || contextScope[0]?.uid
|
|
27
|
+
// 动态化组件 slots 通过上下文传递,相当于 props
|
|
28
|
+
const slots = contextScope[0]?.slots || {}
|
|
29
|
+
|
|
30
|
+
function createEmptyNode () {
|
|
31
|
+
return createNode('block')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function genVnodeTree (node) {
|
|
35
|
+
if (node.type === 1) {
|
|
36
|
+
// wxs 模块不需要动态渲染
|
|
37
|
+
if (node.tag === 'wxs') {
|
|
38
|
+
return createEmptyNode()
|
|
39
|
+
} else if (node.for && !node.forProcessed) {
|
|
40
|
+
return genFor(node)
|
|
41
|
+
} else if (node.if && !node.ifProcessed) {
|
|
42
|
+
return genIf(node)
|
|
43
|
+
} else if (node.tag === 'slot') {
|
|
44
|
+
return genSlot(node)
|
|
45
|
+
} else {
|
|
46
|
+
const data = genData(node)
|
|
47
|
+
let children = genChildren(node)
|
|
48
|
+
// 运行时组件的子组件都通过 slots 属性传递,样式规则在当前组件内匹配后挂载
|
|
49
|
+
if (node.dynamic) {
|
|
50
|
+
data.slots = resolveSlot(children.map(item => genVnodeWithStaticCss(deepCloneNode(item))))
|
|
51
|
+
children = []
|
|
52
|
+
}
|
|
53
|
+
return createNode(node.tag, data, children)
|
|
54
|
+
}
|
|
55
|
+
} else if (node.type === 3) {
|
|
56
|
+
return genText(node)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function evalExps (exps) {
|
|
61
|
+
const interpreter = new Interpreter(contextScope)
|
|
62
|
+
// 消除引用关系
|
|
63
|
+
let value
|
|
64
|
+
try {
|
|
65
|
+
value = interpreter.eval(JSON.parse(JSON.stringify(exps)))
|
|
66
|
+
} catch (e) {
|
|
67
|
+
const errmsg = e.message
|
|
68
|
+
console.warn(errmsg)
|
|
69
|
+
error('interprete the expression wrong: ', location, {
|
|
70
|
+
errType: 'mpx-dynamic-interprete',
|
|
71
|
+
errmsg
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
return value
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function createNode (tag, data = {}, children = []) {
|
|
78
|
+
if (Array.isArray(data)) {
|
|
79
|
+
children = data
|
|
80
|
+
data = {}
|
|
81
|
+
}
|
|
82
|
+
if (typeof tag === 'object') {
|
|
83
|
+
return tag
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 处理 for 循环产生的数组,同时清除空节点
|
|
87
|
+
children = simpleNormalizeChildren(children).filter(node => !!node?.nt)
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
nt: tag,
|
|
91
|
+
d: data,
|
|
92
|
+
c: children
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* 样式隔离的匹配策略优化:
|
|
99
|
+
*
|
|
100
|
+
* 条件1: 子组件不能影响到父组件的样式
|
|
101
|
+
* 条件2: slot 的内容必须在父组件的上下文当中完成样式匹配
|
|
102
|
+
* 条件3: 匹配过程只能进行一次
|
|
103
|
+
*
|
|
104
|
+
* 方案一:根据 moduleId 即作用域来进行匹配
|
|
105
|
+
* 方案二:根据虚拟树来进行匹配
|
|
106
|
+
*/
|
|
107
|
+
// function createDynamicNode (moduleId, data = {}, children = []) {
|
|
108
|
+
// const { template = {}, styles = [] } = staticMap[moduleId]
|
|
109
|
+
// data.$slots = resolveSlot(children) // 将 slot 通过上下文传递到子组件的渲染流程中
|
|
110
|
+
// const vnodeTree = _genVnodeTree(template, [data], styles, moduleId)
|
|
111
|
+
// return vnodeTree
|
|
112
|
+
// }
|
|
113
|
+
|
|
114
|
+
function resolveSlot (children) {
|
|
115
|
+
const slots = {}
|
|
116
|
+
if (children.length) {
|
|
117
|
+
for (let i = 0; i < children.length; i++) {
|
|
118
|
+
const child = children[i]
|
|
119
|
+
const name = child.d?.slot
|
|
120
|
+
if (name) {
|
|
121
|
+
const slot = (slots[name] || (slots[name] = []))
|
|
122
|
+
if (child.tag === 'template') {
|
|
123
|
+
slot.push.apply(slot, child.children || [])
|
|
124
|
+
} else {
|
|
125
|
+
slot.push(child)
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
(slots.default || (slots.default = [])).push(child)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return slots
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function genData (node) {
|
|
136
|
+
const res = {
|
|
137
|
+
uid,
|
|
138
|
+
moduleId
|
|
139
|
+
}
|
|
140
|
+
if (!node.attrsList) {
|
|
141
|
+
return res
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
node.attrsList.forEach((attr) => {
|
|
145
|
+
if (attr.name === 'class' || attr.name === 'style') {
|
|
146
|
+
// class/style 的表达式为数组形式,class/style的计算过程需要放到逻辑层,主要是因为有逻辑匹配的过程去生成 vnodeTree
|
|
147
|
+
const helper = attr.name === 'class' ? stringify.stringifyClass : stringify.stringifyStyle
|
|
148
|
+
let value = ''
|
|
149
|
+
if (attr.__exp) {
|
|
150
|
+
let valueArr = evalExps(attr.__exp)
|
|
151
|
+
valueArr = Array.isArray(valueArr) ? valueArr : [valueArr]
|
|
152
|
+
value = helper(...valueArr)
|
|
153
|
+
// dynamic style + wx:show
|
|
154
|
+
const showStyle = valueArr[2]
|
|
155
|
+
if (showStyle) {
|
|
156
|
+
value = value + ';' + showStyle
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
value = attr.value
|
|
160
|
+
}
|
|
161
|
+
res[attr.name] = value
|
|
162
|
+
} else {
|
|
163
|
+
res[dash2hump(attr.name)] = attr.__exp
|
|
164
|
+
? evalExps(attr.__exp)
|
|
165
|
+
: attr.value
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
return res
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function genChildren (node) {
|
|
173
|
+
const res = []
|
|
174
|
+
const children = node.children || []
|
|
175
|
+
if (children.length) {
|
|
176
|
+
children.forEach((item) => {
|
|
177
|
+
res.push(genNode(item))
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
return res
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function genNode (node) {
|
|
184
|
+
if (node.type === 1) {
|
|
185
|
+
return genVnodeTree(node)
|
|
186
|
+
} else if (node.type === 3 && node.isComment) {
|
|
187
|
+
return ''
|
|
188
|
+
// TODO: 注释暂不处理
|
|
189
|
+
// return _genComment(node)
|
|
190
|
+
} else {
|
|
191
|
+
return genText(node) // 文本节点统一通过 _genText 来生成,type = 2(带有表达式的文本,在 mpx 统一处理为了3) || type = 3(纯文本,非注释)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function genText (node) {
|
|
196
|
+
return {
|
|
197
|
+
nt: '#text',
|
|
198
|
+
ct: node.__exp ? evalExps(node.__exp) : node.text
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function genFor (node) {
|
|
203
|
+
node.forProcessed = true
|
|
204
|
+
|
|
205
|
+
const itemKey = node.for.item || 'item'
|
|
206
|
+
const indexKey = node.for.index || 'index'
|
|
207
|
+
const scope = {
|
|
208
|
+
[itemKey]: null,
|
|
209
|
+
[indexKey]: null
|
|
210
|
+
}
|
|
211
|
+
const forExp = node.for
|
|
212
|
+
const res = []
|
|
213
|
+
let forValue = evalExps(forExp.__exp)
|
|
214
|
+
|
|
215
|
+
// 和微信的模版渲染策略保持一致:当 wx:for 的值为字符串时,会将字符串解析成字符串数组
|
|
216
|
+
if (isString(forValue)) {
|
|
217
|
+
forValue = forValue.split('')
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (Array.isArray(forValue)) {
|
|
221
|
+
forValue.forEach((item, index) => {
|
|
222
|
+
// item、index 模板当中如果没申明,需要给到默认值
|
|
223
|
+
scope[itemKey] = item
|
|
224
|
+
scope[indexKey] = index
|
|
225
|
+
|
|
226
|
+
contextScope.push(scope)
|
|
227
|
+
|
|
228
|
+
// 针对 for 循环避免每次都操作的同一个 node 导致数据的污染的问题
|
|
229
|
+
res.push(deepCloneNode(genVnodeTree(deepCloneNode(node))))
|
|
230
|
+
|
|
231
|
+
contextScope.pop()
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return res
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// 对于 if 而言最终生成 <= 1 节点
|
|
239
|
+
function genIf (node) {
|
|
240
|
+
if (!node.ifConditions) {
|
|
241
|
+
node.ifConditions = []
|
|
242
|
+
return {} // 一个空节点
|
|
243
|
+
}
|
|
244
|
+
node.ifProcessed = true
|
|
245
|
+
|
|
246
|
+
const ifConditions = node.ifConditions.slice()
|
|
247
|
+
|
|
248
|
+
let res = {} // 空节点
|
|
249
|
+
for (let i = 0; i < ifConditions.length; i++) {
|
|
250
|
+
const condition = ifConditions[i]
|
|
251
|
+
// 非 else 节点
|
|
252
|
+
if (condition.ifExp) {
|
|
253
|
+
const identifierValue = evalExps(condition.__exp)
|
|
254
|
+
if (identifierValue) {
|
|
255
|
+
res = genVnodeTree(condition.block === 'self' ? node : condition.block)
|
|
256
|
+
break
|
|
257
|
+
}
|
|
258
|
+
} else { // else 节点
|
|
259
|
+
res = genVnodeTree(condition.block)
|
|
260
|
+
break
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return res
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// 暂时不支持作用域插槽
|
|
267
|
+
function genSlot (node) {
|
|
268
|
+
const data = genData(node) // 计算属性值
|
|
269
|
+
const slotName = data.name || 'default'
|
|
270
|
+
return slots[slotName] || null
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function genVnodeWithStaticCss (vnodeTree) {
|
|
274
|
+
styles.forEach((item) => {
|
|
275
|
+
const [selector, style] = item
|
|
276
|
+
const nodes = cssSelect(selector, { moduleId })(vnodeTree)
|
|
277
|
+
nodes?.forEach((node) => {
|
|
278
|
+
// todo style 合并策略问题:合并过程中缺少了权重关系 style, class 的判断,需要优化
|
|
279
|
+
node.d.style = node.d.style ? style + node.d.style : style
|
|
280
|
+
})
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
return vnodeTree
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const interpreteredVnodeTree = genVnodeTree(templateAst)
|
|
287
|
+
|
|
288
|
+
return genVnodeWithStaticCss(interpreteredVnodeTree)
|
|
289
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { walkChildren, parseSelector, error, hasOwn, collectDataset } from '@mpxjs/utils'
|
|
2
2
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
3
3
|
import { EffectScope } from 'vue'
|
|
4
|
-
import { PausedState } from '
|
|
4
|
+
import { PausedState } from '../helper/const'
|
|
5
5
|
|
|
6
6
|
const hackEffectScope = () => {
|
|
7
7
|
EffectScope.prototype.pause = function () {
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Vue from './vue'
|
|
1
|
+
import Vue from './external/vue'
|
|
2
2
|
import { error, diffAndCloneA, hasOwn, makeMap } from '@mpxjs/utils'
|
|
3
3
|
import { APIs, InstanceAPIs } from './platform/export/api'
|
|
4
4
|
|
|
@@ -60,6 +60,8 @@ export {
|
|
|
60
60
|
|
|
61
61
|
export { getMixin } from './core/mergeOptions'
|
|
62
62
|
|
|
63
|
+
export { dynamic } from './dynamic/astCache'
|
|
64
|
+
|
|
63
65
|
export function toPureObject (obj) {
|
|
64
66
|
return diffAndCloneA(obj).clone
|
|
65
67
|
}
|
|
@@ -143,7 +145,11 @@ Mpx.config = {
|
|
|
143
145
|
hostWhitelists Array 类型 支持h5域名白名单安全校验
|
|
144
146
|
apiImplementations webview JSSDK接口 例如getlocation
|
|
145
147
|
*/
|
|
146
|
-
webviewConfig: {}
|
|
148
|
+
webviewConfig: {},
|
|
149
|
+
/**
|
|
150
|
+
* react-native 相关配置,用于挂载事件等,如 onShareAppMessage
|
|
151
|
+
*/
|
|
152
|
+
rnConfig: {}
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
global.__mpx = Mpx
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { warn, type } from '@mpxjs/utils'
|
|
2
|
+
export default function directiveHelperMixin () {
|
|
3
|
+
return {
|
|
4
|
+
methods: {
|
|
5
|
+
__getWxKey (item, key) {
|
|
6
|
+
const value = key === '*this' ? item : item[key]
|
|
7
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
8
|
+
return value
|
|
9
|
+
} else {
|
|
10
|
+
warn(`wx:key's value should return a string or a number, received: ${type(value)}`, this.__mpxProxy.options.mpxFileResource)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -10,10 +10,21 @@ import pageScrollMixin from './pageScrollMixin'
|
|
|
10
10
|
import componentGenericsMixin from './componentGenericsMixin'
|
|
11
11
|
import getTabBarMixin from './getTabBarMixin'
|
|
12
12
|
import pageRouteMixin from './pageRouteMixin'
|
|
13
|
+
import { dynamicRefsMixin, dynamicRenderHelperMixin, dynamicSlotMixin } from '../../dynamic/dynamicRenderMixin'
|
|
14
|
+
import styleHelperMixin from './styleHelperMixin'
|
|
15
|
+
import directiveHelperMixin from './directiveHelperMixin'
|
|
16
|
+
import { isReact } from '@mpxjs/utils'
|
|
13
17
|
|
|
14
18
|
export default function getBuiltInMixins (options, type) {
|
|
15
|
-
let bulitInMixins
|
|
16
|
-
if (
|
|
19
|
+
let bulitInMixins
|
|
20
|
+
if (isReact) {
|
|
21
|
+
bulitInMixins = [
|
|
22
|
+
proxyEventMixin(),
|
|
23
|
+
directiveHelperMixin(),
|
|
24
|
+
styleHelperMixin(type),
|
|
25
|
+
refsMixin()
|
|
26
|
+
]
|
|
27
|
+
} else if (__mpx_mode__ === 'web') {
|
|
17
28
|
bulitInMixins = [
|
|
18
29
|
proxyEventMixin(),
|
|
19
30
|
refsMixin(),
|
|
@@ -41,6 +52,13 @@ export default function getBuiltInMixins (options, type) {
|
|
|
41
52
|
showMixin(type),
|
|
42
53
|
i18nMixin()
|
|
43
54
|
])
|
|
55
|
+
if (__mpx_dynamic_runtime__) {
|
|
56
|
+
bulitInMixins = bulitInMixins.concat([
|
|
57
|
+
dynamicRenderHelperMixin(),
|
|
58
|
+
dynamicSlotMixin(),
|
|
59
|
+
dynamicRefsMixin()
|
|
60
|
+
])
|
|
61
|
+
}
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
return bulitInMixins.filter(item => item)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { error } from '@mpxjs/utils'
|
|
2
|
+
import Mpx from '../../index'
|
|
3
|
+
|
|
4
|
+
export default function proxyEventMixin () {
|
|
5
|
+
const methods = {
|
|
6
|
+
__invoke (rawEvent, eventConfig = []) {
|
|
7
|
+
if (typeof Mpx.config.proxyEventHandler === 'function') {
|
|
8
|
+
try {
|
|
9
|
+
Mpx.config.proxyEventHandler(rawEvent)
|
|
10
|
+
} catch (e) {
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const location = this.__mpxProxy.options.mpxFileResource
|
|
14
|
+
|
|
15
|
+
let returnedValue
|
|
16
|
+
eventConfig.forEach((item) => {
|
|
17
|
+
const callbackName = item[0]
|
|
18
|
+
if (callbackName) {
|
|
19
|
+
const params = item.length > 1
|
|
20
|
+
? item.slice(1).map(item => {
|
|
21
|
+
if (item === '__mpx_event__') {
|
|
22
|
+
return rawEvent
|
|
23
|
+
} else {
|
|
24
|
+
return item
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
: [rawEvent]
|
|
28
|
+
if (typeof this[callbackName] === 'function') {
|
|
29
|
+
returnedValue = this[callbackName].apply(this, params)
|
|
30
|
+
} else {
|
|
31
|
+
error(`Instance property [${callbackName}] is not function, please check.`, location)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
return returnedValue
|
|
36
|
+
}
|
|
37
|
+
// __model (expr, $event, valuePath = ['value'], filterMethod) {
|
|
38
|
+
// const innerFilter = {
|
|
39
|
+
// trim: val => typeof val === 'string' && val.trim()
|
|
40
|
+
// }
|
|
41
|
+
// const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail)
|
|
42
|
+
// const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' ? this[filterMethod](originValue) : originValue) : originValue
|
|
43
|
+
// setByPath(this, expr, value)
|
|
44
|
+
// }
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
methods
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { setByPath, error, dash2hump, collectDataset } from '@mpxjs/utils'
|
|
2
2
|
import Mpx from '../../index'
|
|
3
|
+
import contextMap from '../../dynamic/vnode/context'
|
|
4
|
+
|
|
5
|
+
function logCallbackNotFound (context, callbackName) {
|
|
6
|
+
const location = context.__mpxProxy && context.__mpxProxy.options.mpxFileResource
|
|
7
|
+
error(`Instance property [${callbackName}] is not function, please check.`, location)
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
export default function proxyEventMixin () {
|
|
5
11
|
const methods = {
|
|
@@ -12,7 +18,6 @@ export default function proxyEventMixin () {
|
|
|
12
18
|
}
|
|
13
19
|
const location = this.__mpxProxy.options.mpxFileResource
|
|
14
20
|
const type = $event.type
|
|
15
|
-
const emitMode = $event.detail && $event.detail.mpxEmit
|
|
16
21
|
if (!type) {
|
|
17
22
|
error('Event object must have [type] property!', location)
|
|
18
23
|
return
|
|
@@ -33,22 +38,15 @@ export default function proxyEventMixin () {
|
|
|
33
38
|
}
|
|
34
39
|
const eventConfigs = target.dataset.eventconfigs || {}
|
|
35
40
|
const curEventConfig = eventConfigs[type] || eventConfigs[fallbackType] || []
|
|
41
|
+
// 如果有 mpxuid 说明是运行时组件,那么需要设置对应的上下文
|
|
42
|
+
const rootRuntimeContext = contextMap.get(target.dataset.mpxuid)
|
|
43
|
+
const context = rootRuntimeContext || this
|
|
36
44
|
let returnedValue
|
|
37
45
|
curEventConfig.forEach((item) => {
|
|
38
46
|
const callbackName = item[0]
|
|
39
|
-
if (emitMode) {
|
|
40
|
-
$event = $event.detail.data
|
|
41
|
-
}
|
|
42
47
|
if (callbackName) {
|
|
43
48
|
const params = item.length > 1
|
|
44
49
|
? item.slice(1).map(item => {
|
|
45
|
-
// 暂不支持$event.xxx的写法
|
|
46
|
-
// if (/^\$event/.test(item)) {
|
|
47
|
-
// this.__mpxTempEvent = $event
|
|
48
|
-
// const value = getByPath(this, item.replace('$event', '__mpxTempEvent'))
|
|
49
|
-
// // 删除临时变量
|
|
50
|
-
// delete this.__mpxTempEvent
|
|
51
|
-
// return value
|
|
52
50
|
if (item === '__mpx_event__') {
|
|
53
51
|
return $event
|
|
54
52
|
} else {
|
|
@@ -56,10 +54,10 @@ export default function proxyEventMixin () {
|
|
|
56
54
|
}
|
|
57
55
|
})
|
|
58
56
|
: [$event]
|
|
59
|
-
if (typeof
|
|
60
|
-
returnedValue =
|
|
57
|
+
if (typeof context[callbackName] === 'function') {
|
|
58
|
+
returnedValue = context[callbackName].apply(context, params)
|
|
61
59
|
} else {
|
|
62
|
-
|
|
60
|
+
logCallbackNotFound(context, callbackName)
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
})
|