@mpxjs/core 2.9.0-beta.2 → 2.9.0-beta.4

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/@types/index.d.ts CHANGED
@@ -31,18 +31,22 @@ type ArrayType<T extends any[]> = T extends Array<infer R> ? R : never;
31
31
  // Mpx types
32
32
  type Data = object | (() => object)
33
33
 
34
- type PropType = StringConstructor | NumberConstructor | BooleanConstructor | ObjectConstructor | ArrayConstructor | null
34
+ type PropConstructor<T = any> = {
35
+ new (...args: any[]): T & {};
36
+ } | {
37
+ (): T;
38
+ }
35
39
 
36
- interface PropOpt {
37
- type: PropType
38
- optionalTypes?: Array<PropType>
39
- value?: any
40
+ export type PropType<T> = PropConstructor<T>
40
41
 
41
- observer? (value: any, old: any, changedPath: string): void
42
+ type FullPropType<T> = {
43
+ type: PropType<T>;
44
+ value?: T;
45
+ optionalTypes?: PropType<T>[];
42
46
  }
43
47
 
44
48
  interface Properties {
45
- [key: string]: WechatMiniprogram.Component.AllProperty
49
+ [key: string]: WechatMiniprogram.Component.AllProperty | PropType<any> | FullPropType<any>
46
50
  }
47
51
 
48
52
  interface Methods {
@@ -78,8 +82,12 @@ type PropValueType<Def> = Def extends {
78
82
  }
79
83
  ? T
80
84
  : Def extends (...args: any[]) => infer T
81
- ? T
82
- : any;
85
+ ? T
86
+ : Def extends FullPropType<infer T>
87
+ ? T
88
+ : Def extends PropType<infer T>
89
+ ? T
90
+ : any;
83
91
 
84
92
  type GetPropsType<T> = {
85
93
  readonly [K in keyof T]: PropValueType<T[K]>
@@ -242,6 +250,11 @@ interface AnyConstructor {
242
250
  prototype: any
243
251
  }
244
252
 
253
+ interface WebviewConfig {
254
+ hostWhitelists?: Array<string>
255
+ apiImplementations?: object
256
+ }
257
+
245
258
  interface MpxConfig {
246
259
  useStrictDiff: boolean
247
260
  ignoreWarning: boolean | string | RegExp | ((msg: string, location: string, e: Error) => boolean)
@@ -251,7 +264,8 @@ interface MpxConfig {
251
264
  proxyEventHandler: (e: Event) => any | null
252
265
  setDataHandler: (data: object, target: ComponentIns<{}, {}, {}, {}, []>) => any | null
253
266
  forceFlushSync: boolean,
254
- webRouteConfig: object
267
+ webRouteConfig: object,
268
+ webviewConfig?: WebviewConfig
255
269
  }
256
270
 
257
271
  type SupportedMode = 'wx' | 'ali' | 'qq' | 'swan' | 'tt' | 'web' | 'qa'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/core",
3
- "version": "2.9.0-beta.2",
3
+ "version": "2.9.0-beta.4",
4
4
  "description": "mpx runtime core",
5
5
  "keywords": [
6
6
  "miniprogram",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "main": "src/index.js",
21
21
  "dependencies": {
22
- "@mpxjs/utils": "^2.9.0-beta.1",
22
+ "@mpxjs/utils": "^2.9.0-beta.4",
23
23
  "lodash": "^4.1.1",
24
24
  "miniprogram-api-typings": "^3.10.0"
25
25
  },
@@ -47,5 +47,5 @@
47
47
  "url": "https://github.com/didi/mpx/issues"
48
48
  },
49
49
  "sideEffects": false,
50
- "gitHead": "2d61bab77c50eccb7470b9b9bd644e7bd6510467"
50
+ "gitHead": "300107cbcf0d6847e1d27896ea71ad4ce1387dd5"
51
51
  }
@@ -19,7 +19,7 @@ export function injectMixins (mixins, options = {}) {
19
19
  }
20
20
  }
21
21
 
22
- let types = options.types || ['app', 'page', 'component']
22
+ let types = options.types || ['page', 'component']
23
23
  const stage = options.stage || -1
24
24
 
25
25
  if (typeof types === 'string') {
@@ -314,17 +314,19 @@ export function mergeToArray (parent, child, key) {
314
314
  function composeHooks (target, includes) {
315
315
  Object.keys(target).forEach(key => {
316
316
  if (!includes || includes[key]) {
317
- const hooksArr = target[key]
318
- hooksArr && (target[key] = function (...args) {
319
- let result
320
- for (let i = 0; i < hooksArr.length; i++) {
321
- if (typeof hooksArr[i] === 'function') {
322
- const data = hooksArr[i].apply(this, args)
323
- data !== undefined && (result = data)
317
+ const hooks = target[key]
318
+ if (Array.isArray(hooks)) {
319
+ target[key] = function (...args) {
320
+ let result
321
+ for (let i = 0; i < hooks.length; i++) {
322
+ if (typeof hooks[i] === 'function') {
323
+ const data = hooks[i].apply(this, args)
324
+ data !== undefined && (result = data)
325
+ }
324
326
  }
327
+ return result
325
328
  }
326
- return result
327
- })
329
+ }
328
330
  }
329
331
  })
330
332
  }
package/src/core/proxy.js CHANGED
@@ -26,7 +26,8 @@ import {
26
26
  getFirstKey,
27
27
  callWithErrorHandling,
28
28
  warn,
29
- error
29
+ error,
30
+ getEnvObj
30
31
  } from '@mpxjs/utils'
31
32
  import {
32
33
  BEFORECREATE,
@@ -46,6 +47,8 @@ import {
46
47
 
47
48
  let uid = 0
48
49
 
50
+ const envObj = getEnvObj()
51
+
49
52
  class RenderTask {
50
53
  resolved = false
51
54
 
@@ -236,14 +239,14 @@ export default class MpxProxy {
236
239
  const setupResult = callWithErrorHandling(setup, this, 'setup function', [
237
240
  this.props,
238
241
  {
239
- triggerEvent: this.target.triggerEvent.bind(this.target),
242
+ triggerEvent: this.target.triggerEvent ? this.target.triggerEvent.bind(this.target) : noop,
240
243
  refs: this.target.$refs,
241
244
  asyncRefs: this.target.$asyncRefs,
242
245
  forceUpdate: this.forceUpdate.bind(this),
243
246
  selectComponent: this.target.selectComponent.bind(this.target),
244
247
  selectAllComponents: this.target.selectAllComponents.bind(this.target),
245
- createSelectorQuery: this.target.createSelectorQuery.bind(this.target),
246
- createIntersectionObserver: this.target.createIntersectionObserver.bind(this.target)
248
+ createSelectorQuery: this.target.createSelectorQuery ? this.target.createSelectorQuery.bind(this.target) : envObj.createSelectorQuery.bind(envObj),
249
+ createIntersectionObserver: this.target.createIntersectionObserver ? this.target.createIntersectionObserver.bind(this.target) : envObj.createIntersectionObserver.bind(envObj)
247
250
  }
248
251
  ])
249
252
  if (!isObject(setupResult)) {
@@ -309,7 +312,16 @@ export default class MpxProxy {
309
312
  watch (source, cb, options) {
310
313
  const target = this.target
311
314
  const getter = isString(source)
312
- ? () => getByPath(target, source)
315
+ ? () => {
316
+ // for watch multi path string like 'a.b,c,d'
317
+ if (source.indexOf(',') > -1) {
318
+ return source.split(',').map(path => {
319
+ return getByPath(target, path.trim())
320
+ })
321
+ } else {
322
+ return getByPath(target, source)
323
+ }
324
+ }
313
325
  : source.bind(target)
314
326
 
315
327
  if (isObject(cb)) {
@@ -527,6 +539,9 @@ export default class MpxProxy {
527
539
  initRender () {
528
540
  if (this.options.__nativeRender__) return this.doRender()
529
541
 
542
+ const _i = this.target._i.bind(this.target)
543
+ const _c = this.target._c.bind(this.target)
544
+ const _r = this.target._r.bind(this.target)
530
545
  const effect = this.effect = new ReactiveEffect(() => {
531
546
  // pre render for props update
532
547
  if (this.propsUpdatedFlag) {
@@ -535,7 +550,7 @@ export default class MpxProxy {
535
550
 
536
551
  if (this.target.__injectedRender) {
537
552
  try {
538
- return this.target.__injectedRender()
553
+ return this.target.__injectedRender(_i, _c, _r)
539
554
  } catch (e) {
540
555
  warn('Failed to execute render function, degrade to full-set-data mode.', this.options.mpxFileResource, e)
541
556
  this.render()
@@ -605,7 +620,9 @@ export default class MpxProxy {
605
620
 
606
621
  export let currentInstance = null
607
622
 
608
- export const getCurrentInstance = () => currentInstance?.target
623
+ export const getCurrentInstance = () => {
624
+ return currentInstance && { proxy: currentInstance?.target }
625
+ }
609
626
 
610
627
  export const setCurrentInstance = (instance) => {
611
628
  currentInstance = instance
package/src/index.js CHANGED
@@ -137,7 +137,13 @@ Mpx.config = {
137
137
  proxyEventHandler: null,
138
138
  setDataHandler: null,
139
139
  forceFlushSync: false,
140
- webRouteConfig: {}
140
+ webRouteConfig: {},
141
+ /*
142
+ 支持两个属性
143
+ hostWhitelists Array 类型 支持h5域名白名单安全校验
144
+ apiImplementations webview JSSDK接口 例如getlocation
145
+ */
146
+ webviewConfig: {}
141
147
  }
142
148
 
143
149
  global.__mpx = Mpx
@@ -1,4 +1,4 @@
1
- import { setByPath, error, hasOwn } from '@mpxjs/utils'
1
+ import { setByPath, error, hasOwn, dash2hump } from '@mpxjs/utils'
2
2
  import Mpx from '../../index'
3
3
 
4
4
  const datasetReg = /^data-(.+)$/
@@ -36,6 +36,8 @@ export default function proxyEventMixin () {
36
36
  if (type === 'begin' || type === 'end') {
37
37
  // 地图的 regionchange 事件会派发 e.type 为 begin 和 end 的事件
38
38
  fallbackType = 'regionchange'
39
+ } else if (/-([a-z])/.test(type)) {
40
+ fallbackType = dash2hump(type)
39
41
  } else if (__mpx_mode__ === 'ali') {
40
42
  fallbackType = type.replace(/^./, i => i.toLowerCase())
41
43
  }
@@ -99,15 +101,8 @@ export default function proxyEventMixin () {
99
101
  const eventObj = {
100
102
  type: eventName,
101
103
  timeStamp,
102
- target: {
103
- id,
104
- dataset,
105
- targetDataset: dataset
106
- },
107
- currentTarget: {
108
- id,
109
- dataset
110
- },
104
+ target: { id, dataset, targetDataset: dataset },
105
+ currentTarget: { id, dataset },
111
106
  detail: eventDetail
112
107
  }
113
108
  handler.call(this, eventObj)
@@ -8,7 +8,7 @@ function getEl (ref) {
8
8
 
9
9
  function processRefs (refs) {
10
10
  Object.keys(refs).forEach((key) => {
11
- const matched = /^__mpx_ref_([^_]+)__$/.exec(key)
11
+ const matched = /^__mpx_ref_(.+)__$/.exec(key)
12
12
  const rKey = matched && matched[1]
13
13
  if (rKey) {
14
14
  const ref = refs[key]
@@ -1,4 +1,4 @@
1
- import { isObject } from '@mpxjs/utils'
1
+ import { isObject, getByPath, hasOwn } from '@mpxjs/utils'
2
2
 
3
3
  export default function renderHelperMixin () {
4
4
  return {
@@ -22,6 +22,12 @@ export default function renderHelperMixin () {
22
22
  }
23
23
  },
24
24
  _c (key, value) {
25
+ if (hasOwn(this.__mpxProxy.renderData, key)) {
26
+ return this.__mpxProxy.renderData[key]
27
+ }
28
+ if (value === undefined) {
29
+ value = getByPath(this, key)
30
+ }
25
31
  this.__mpxProxy.renderData[key] = value
26
32
  return value
27
33
  },
@@ -2,10 +2,11 @@ import transferOptions from '../core/transferOptions'
2
2
  import mergeOptions from '../core/mergeOptions'
3
3
  import builtInKeysMap from './patch/builtInKeysMap'
4
4
  import { makeMap, spreadProp, isBrowser } from '@mpxjs/utils'
5
+ import { mergeLifecycle } from '../convertor/mergeLifecycle'
5
6
  import * as webLifecycle from '../platform/patch/web/lifecycle'
6
7
  import Mpx from '../index'
7
8
 
8
- const webAppHooksMap = makeMap(webLifecycle.LIFECYCLE.APP_HOOKS)
9
+ const webAppHooksMap = makeMap(mergeLifecycle(webLifecycle.LIFECYCLE).app)
9
10
 
10
11
  function filterOptions (options, appData) {
11
12
  const newOptions = {}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  effectScope as vueEffectScope,
3
- getCurrentScope as getCurrentVueScope,
3
+ getCurrentScope as vueGetCurrentScope,
4
4
  onScopeDispose
5
5
  } from 'vue'
6
6
 
@@ -42,7 +42,7 @@ const fixEffectScope = (scope) => {
42
42
  }
43
43
 
44
44
  const effectScope = (detached) => fixEffectScope(vueEffectScope(detached))
45
- const getCurrentScope = () => fixEffectScope(getCurrentVueScope())
45
+ const getCurrentScope = () => fixEffectScope(vueGetCurrentScope())
46
46
 
47
47
  export {
48
48
  // effectScope
@@ -1,7 +1,7 @@
1
1
  import MpxProxy from '../../../core/proxy'
2
2
  import builtInKeysMap from '../builtInKeysMap'
3
3
  import mergeOptions from '../../../core/mergeOptions'
4
- import { isFunction, error, diffAndCloneA, hasOwn } from '@mpxjs/utils'
4
+ import { isFunction, error, diffAndCloneA, hasOwn, noop } from '@mpxjs/utils'
5
5
 
6
6
  function transformApiForProxy (context, currentInject) {
7
7
  const rawSetData = context.setData.bind(context)
@@ -45,16 +45,14 @@ function transformApiForProxy (context, currentInject) {
45
45
  }
46
46
  })
47
47
  if (currentInject) {
48
- if (currentInject.render) {
49
- Object.defineProperties(context, {
50
- __injectedRender: {
51
- get () {
52
- return currentInject.render.bind(context)
53
- },
54
- configurable: false
55
- }
56
- })
57
- }
48
+ Object.defineProperties(context, {
49
+ __injectedRender: {
50
+ get () {
51
+ return currentInject.render || noop
52
+ },
53
+ configurable: false
54
+ }
55
+ })
58
56
  if (currentInject.getRefsData) {
59
57
  Object.defineProperties(context, {
60
58
  __getRefsData: {
@@ -9,7 +9,8 @@ const COMPONENT_HOOKS = [
9
9
  'deactivated',
10
10
  'beforeDestroy',
11
11
  'destroyed',
12
- 'errorCaptured'
12
+ 'errorCaptured',
13
+ 'serverPrefetch'
13
14
  ]
14
15
 
15
16
  const PAGE_HOOKS = [
@@ -1,4 +1,4 @@
1
- import { hasOwn } from '@mpxjs/utils'
1
+ import { hasOwn, noop } from '@mpxjs/utils'
2
2
  import MpxProxy from '../../../core/proxy'
3
3
  import builtInKeysMap from '../builtInKeysMap'
4
4
  import mergeOptions from '../../../core/mergeOptions'
@@ -83,16 +83,14 @@ function transformApiForProxy (context, currentInject) {
83
83
 
84
84
  // 绑定注入的render
85
85
  if (currentInject) {
86
- if (currentInject.render) {
87
- Object.defineProperties(context, {
88
- __injectedRender: {
89
- get () {
90
- return currentInject.render
91
- },
92
- configurable: false
93
- }
94
- })
95
- }
86
+ Object.defineProperties(context, {
87
+ __injectedRender: {
88
+ get () {
89
+ return currentInject.render || noop
90
+ },
91
+ configurable: false
92
+ }
93
+ })
96
94
  if (currentInject.getRefsData) {
97
95
  Object.defineProperties(context, {
98
96
  __getRefsData: {
package/src/vuePlugin.js CHANGED
@@ -1,12 +1,34 @@
1
- import { walkChildren, parseSelector, error } from '@mpxjs/utils'
1
+ import { walkChildren, parseSelector, error, hasOwn } from '@mpxjs/utils'
2
2
  import * as webApi from '@mpxjs/api-proxy/src/web/api'
3
+ const datasetReg = /^data-(.+)$/
4
+
5
+ function collectDataset (attrs) {
6
+ const dataset = {}
7
+ for (const key in attrs) {
8
+ if (hasOwn(attrs, key)) {
9
+ const matched = datasetReg.exec(key)
10
+ if (matched) {
11
+ dataset[matched[1]] = attrs[key]
12
+ }
13
+ }
14
+ }
15
+ return dataset
16
+ }
3
17
 
4
18
  export default function install (Vue) {
5
19
  Vue.prototype.triggerEvent = function (eventName, eventDetail) {
6
- return this.$emit(eventName, {
20
+ let eventObj = {}
21
+ const dataset = collectDataset(this.$attrs)
22
+ const id = this.$attrs.id || ''
23
+ const timeStamp = +new Date()
24
+ eventObj = {
7
25
  type: eventName,
26
+ timeStamp,
27
+ target: { id, dataset, targetDataset: dataset },
28
+ currentTarget: { id, dataset },
8
29
  detail: eventDetail
9
- })
30
+ }
31
+ return this.$emit(eventName, eventObj)
10
32
  }
11
33
  Vue.prototype.selectComponent = function (selector, all) {
12
34
  const result = []