@mpxjs/webpack-plugin 2.10.17-beta.7 → 2.10.17-beta.8
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/lib/index.js +1 -0
- package/lib/json-compiler/index.js +18 -1
- package/lib/react/processJSON.js +20 -1
- package/lib/react/processScript.js +1 -0
- package/lib/react/script-helper.js +0 -1
- package/lib/runtime/components/ali/mpx-recycle-view.mpx +518 -0
- package/lib/runtime/components/ali/mpx-sticky-header.mpx +212 -0
- package/lib/runtime/components/ali/mpx-sticky-section.mpx +17 -0
- package/lib/runtime/components/react/dist/mpx-recycle-view.d.ts +45 -0
- package/lib/runtime/components/react/dist/mpx-recycle-view.jsx +272 -0
- package/lib/runtime/components/react/mpx-recycle-view.tsx +398 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +1 -0
- package/lib/runtime/components/react/mpx-sticky-section.tsx +1 -1
- package/lib/runtime/components/web/mpx-recycle-view.vue +508 -0
- package/lib/runtime/components/wx/mpx-list-header-default.mpx +21 -0
- package/lib/runtime/components/wx/mpx-recycle-item-default.mpx +21 -0
- package/lib/runtime/components/wx/mpx-recycle-view.mpx +193 -0
- package/lib/runtime/components/wx/mpx-section-header-default.mpx +21 -0
- package/lib/template-compiler/compiler.js +8 -3
- package/lib/utils/const.js +17 -0
- package/lib/utils/process-extend-components.js +43 -0
- package/lib/web/processJSON.js +20 -2
- package/package.json +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<scroll-view wx:ref="recycleViewRef" class="mpx-recycle-view" scroll-y wx:style="{{ scrollViewStyle }}" type="custom"
|
|
3
|
+
enhanced="{{ enhanced }}" scroll-with-animation="{{ scrollWithAnimation }}" bounces="{{ bounces }}"
|
|
4
|
+
show-scrollbar="{{ showScrollbar }}" refresher-enabled="{{ refresherEnabled }}"
|
|
5
|
+
refresher-triggered="{{ refresherTriggered }}" bindscroll="onScroll" bindrefresherrefresh="onRefresh"
|
|
6
|
+
scroll-into-view="{{ scrollIntoViewId }}" scroll-into-view-alignment="{{ viewPosition }}">
|
|
7
|
+
<block wx:if="{{ useListHeader }}">
|
|
8
|
+
<list-header listHeaderData="{{ listHeaderData }}"></list-header>
|
|
9
|
+
</block>
|
|
10
|
+
<block wx:for="{{ convertedListData }}" wx:key="index">
|
|
11
|
+
<sticky-section>
|
|
12
|
+
<!-- section header -->
|
|
13
|
+
<block wx:if="{{ item.hasSectionHeader }}">
|
|
14
|
+
<block wx:if="{{ enableSticky }}">
|
|
15
|
+
<sticky-header>
|
|
16
|
+
<section-header itemData="{{ item.headerData }}" id="{{ item._domId }}"></section-header>
|
|
17
|
+
</sticky-header>
|
|
18
|
+
</block>
|
|
19
|
+
<block wx:else>
|
|
20
|
+
<section-header itemData="{{ item.headerData }}" id="{{ item._domId }}"></section-header>
|
|
21
|
+
</block>
|
|
22
|
+
|
|
23
|
+
</block>
|
|
24
|
+
<block wx:for="{{ item.data }}" wx:for-item="subItem" wx:key="subIndex">
|
|
25
|
+
<!-- section items -->
|
|
26
|
+
<recycle-item itemData="{{ subItem.itemData }}" id="{{ subItem._domId }}"></recycle-item>
|
|
27
|
+
</block>
|
|
28
|
+
</sticky-section>
|
|
29
|
+
</block>
|
|
30
|
+
</scroll-view>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script>
|
|
34
|
+
import { createComponent } from '@mpxjs/core'
|
|
35
|
+
|
|
36
|
+
createComponent({
|
|
37
|
+
properties: {
|
|
38
|
+
height: {
|
|
39
|
+
type: Number,
|
|
40
|
+
value: null
|
|
41
|
+
},
|
|
42
|
+
width: {
|
|
43
|
+
type: Number,
|
|
44
|
+
value: null
|
|
45
|
+
},
|
|
46
|
+
listData: {
|
|
47
|
+
type: Array,
|
|
48
|
+
value: []
|
|
49
|
+
},
|
|
50
|
+
enableSticky: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
value: false
|
|
53
|
+
},
|
|
54
|
+
showScrollbar: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
value: false
|
|
57
|
+
},
|
|
58
|
+
enhanced: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
value: false
|
|
61
|
+
},
|
|
62
|
+
bounces: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
value: false
|
|
65
|
+
},
|
|
66
|
+
refresherEnabled: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
value: false
|
|
69
|
+
},
|
|
70
|
+
refresherTriggered: {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
value: false
|
|
73
|
+
},
|
|
74
|
+
listHeaderData: {
|
|
75
|
+
type: Object,
|
|
76
|
+
value: null
|
|
77
|
+
},
|
|
78
|
+
scrollWithAnimation: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
value: false
|
|
81
|
+
},
|
|
82
|
+
useListHeader: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
value: false
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
data: {
|
|
88
|
+
convertedListData: [],
|
|
89
|
+
scrollIntoViewId: '',
|
|
90
|
+
viewPosition: 'start'
|
|
91
|
+
},
|
|
92
|
+
computed: {
|
|
93
|
+
scrollViewStyle() {
|
|
94
|
+
return `height: ${this.formatDimension(this.height)};width: ${this.formatDimension(this.width)}`
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
watch: {
|
|
98
|
+
listData: {
|
|
99
|
+
handler(newVal) {
|
|
100
|
+
this.convertedListData = this.convertToSectionListData(newVal)
|
|
101
|
+
},
|
|
102
|
+
immediate: true
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
methods: {
|
|
106
|
+
formatDimension(value) {
|
|
107
|
+
return typeof value === 'number' ? `${value}px` : value || '100%'
|
|
108
|
+
},
|
|
109
|
+
onScroll(e) {
|
|
110
|
+
this.triggerEvent('scroll', e)
|
|
111
|
+
},
|
|
112
|
+
onRefresh(e) {
|
|
113
|
+
this.triggerEvent('refresh', e)
|
|
114
|
+
},
|
|
115
|
+
scrollToIndex({ index, animated, viewPosition = 0 }) {
|
|
116
|
+
if (index >= 0) {
|
|
117
|
+
this.scrollIntoViewId = `mpx-recycle-item-${index}`
|
|
118
|
+
switch (viewPosition) {
|
|
119
|
+
case 0:
|
|
120
|
+
this.viewPosition = 'start'
|
|
121
|
+
break
|
|
122
|
+
case 0.5:
|
|
123
|
+
this.viewPosition = 'center'
|
|
124
|
+
break
|
|
125
|
+
case 1:
|
|
126
|
+
this.viewPosition = 'end'
|
|
127
|
+
break
|
|
128
|
+
default:
|
|
129
|
+
this.viewPosition = 'start'
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
convertToSectionListData(data) {
|
|
134
|
+
const sections = []
|
|
135
|
+
let currentSection = null
|
|
136
|
+
|
|
137
|
+
data.forEach((item, index) => {
|
|
138
|
+
if (item.isSectionHeader) {
|
|
139
|
+
// 如果已经存在一个 section,先把它添加到 sections 中
|
|
140
|
+
if (currentSection) {
|
|
141
|
+
sections.push(currentSection)
|
|
142
|
+
}
|
|
143
|
+
// 创建新的 section
|
|
144
|
+
currentSection = {
|
|
145
|
+
headerData: item,
|
|
146
|
+
data: [],
|
|
147
|
+
hasSectionHeader: true,
|
|
148
|
+
_domId: `mpx-recycle-item-${index}`
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
// 如果没有当前 section,创建一个默认的
|
|
152
|
+
if (!currentSection) {
|
|
153
|
+
// 创建默认section (无header的section)
|
|
154
|
+
currentSection = {
|
|
155
|
+
headerData: null,
|
|
156
|
+
data: [],
|
|
157
|
+
hasSectionHeader: false
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
currentSection.data.push({
|
|
161
|
+
itemData: item,
|
|
162
|
+
_domId: `mpx-recycle-item-${index}`
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// 添加最后一个 section
|
|
168
|
+
if (currentSection) {
|
|
169
|
+
sections.push(currentSection)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return sections
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
</script>
|
|
177
|
+
|
|
178
|
+
<script type="application/json">
|
|
179
|
+
{
|
|
180
|
+
"component": true,
|
|
181
|
+
"componentGenerics": {
|
|
182
|
+
"recycle-item": {
|
|
183
|
+
"default": "./mpx-recycle-item-default"
|
|
184
|
+
},
|
|
185
|
+
"section-header": {
|
|
186
|
+
"default": "./mpx-section-header-default"
|
|
187
|
+
},
|
|
188
|
+
"list-header": {
|
|
189
|
+
"default": "./mpx-list-header-default"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
</script>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="mpx-section-header-default">
|
|
3
|
+
<view class="mpx-default-content">section-header-default</view>
|
|
4
|
+
</view>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<style lang="stylus" scoped>
|
|
8
|
+
.mpx-section-header-default
|
|
9
|
+
margin 4px 16px
|
|
10
|
+
padding 16px
|
|
11
|
+
background #fff
|
|
12
|
+
border-radius 8px
|
|
13
|
+
box-shadow 0 2px 4px rgba(0,0,0,0.1)
|
|
14
|
+
|
|
15
|
+
.mpx-default-content
|
|
16
|
+
display flex
|
|
17
|
+
flex-direction column
|
|
18
|
+
font-size 14px
|
|
19
|
+
color #666
|
|
20
|
+
|
|
21
|
+
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const JSON5 = require('json5')
|
|
2
2
|
const he = require('he')
|
|
3
3
|
const config = require('../config')
|
|
4
|
-
const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID, PARENT_MODULE_ID, MPX_TAG_PAGE_SELECTOR } = require('../utils/const')
|
|
4
|
+
const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID, PARENT_MODULE_ID, MPX_TAG_PAGE_SELECTOR, EXTEND_COMPONENT_CONFIG } = require('../utils/const')
|
|
5
5
|
const normalize = require('../utils/normalize')
|
|
6
6
|
const { normalizeCondition } = require('../utils/match-condition')
|
|
7
7
|
const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
|
|
@@ -728,6 +728,7 @@ function parse (template, options) {
|
|
|
728
728
|
processElement(element, root, options, meta)
|
|
729
729
|
|
|
730
730
|
tagNames.add(element.tag)
|
|
731
|
+
|
|
731
732
|
// 统计通过抽象节点方式使用的组件
|
|
732
733
|
element.attrsList.forEach((attr) => {
|
|
733
734
|
if (genericRE.test(attr.name)) {
|
|
@@ -2432,7 +2433,11 @@ function isRealNode (el) {
|
|
|
2432
2433
|
}
|
|
2433
2434
|
|
|
2434
2435
|
function isComponentNode (el) {
|
|
2435
|
-
return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' || componentGenerics[el.tag]
|
|
2436
|
+
return usingComponents.indexOf(el.tag) !== -1 || el.tag === 'component' || componentGenerics[el.tag] || isExtendComponentNode(el)
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
function isExtendComponentNode (el) {
|
|
2440
|
+
return EXTEND_COMPONENT_CONFIG[el.tag]?.[mode]
|
|
2436
2441
|
}
|
|
2437
2442
|
|
|
2438
2443
|
function getComponentInfo (el) {
|
|
@@ -2440,7 +2445,7 @@ function getComponentInfo (el) {
|
|
|
2440
2445
|
}
|
|
2441
2446
|
|
|
2442
2447
|
function isReactComponent (el) {
|
|
2443
|
-
return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn
|
|
2448
|
+
return !isComponentNode(el) && isRealNode(el) && !el.isBuiltIn && !isExtendComponentNode(el)
|
|
2444
2449
|
}
|
|
2445
2450
|
|
|
2446
2451
|
function processExternalClasses (el, options) {
|
package/lib/utils/const.js
CHANGED
|
@@ -7,5 +7,22 @@ module.exports = {
|
|
|
7
7
|
MPX_ROOT_VIEW: 'mpx-root-view', // 根节点类名
|
|
8
8
|
MPX_APP_MODULE_ID: 'mpx-app-scope', // app文件moduleId
|
|
9
9
|
PARENT_MODULE_ID: '__pid',
|
|
10
|
+
// 扩展组件的平台配置:声明哪些组件在哪些平台有专用实现,哪些使用公共组件
|
|
11
|
+
EXTEND_COMPONENT_CONFIG: {
|
|
12
|
+
'recycle-view': {
|
|
13
|
+
wx: 'runtime/components/wx/mpx-recycle-view.mpx',
|
|
14
|
+
ali: 'runtime/components/ali/mpx-recycle-view.mpx',
|
|
15
|
+
web: 'runtime/components/web/mpx-recycle-view.vue',
|
|
16
|
+
ios: 'runtime/components/react/dist/mpx-recycle-view.jsx',
|
|
17
|
+
android: 'runtime/components/react/dist/mpx-recycle-view.jsx',
|
|
18
|
+
harmony: 'runtime/components/react/dist/mpx-recycle-view.jsx'
|
|
19
|
+
},
|
|
20
|
+
'sticky-header': {
|
|
21
|
+
ali: 'runtime/components/ali/mpx-sticky-header.mpx'
|
|
22
|
+
},
|
|
23
|
+
'sticky-section': {
|
|
24
|
+
ali: 'runtime/components/ali/mpx-sticky-section.mpx'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
10
27
|
MPX_TAG_PAGE_SELECTOR: 'mpx-page'
|
|
11
28
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { EXTEND_COMPONENT_CONFIG } = require('./const')
|
|
2
|
+
const normalize = require('./normalize')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 处理扩展组件的公共方法
|
|
6
|
+
* @param {Object} options 配置选项
|
|
7
|
+
* @param {Object} options.useExtendComponents 使用的扩展组件配置
|
|
8
|
+
* @param {string} options.mode 当前模式 (wx, ali, web, rn 等)
|
|
9
|
+
* @param {Function} options.emitWarning 警告函数
|
|
10
|
+
* @returns {Object} 扩展组件映射对象
|
|
11
|
+
*/
|
|
12
|
+
function processExtendComponents (options) {
|
|
13
|
+
const {
|
|
14
|
+
useExtendComponents = {},
|
|
15
|
+
mode,
|
|
16
|
+
emitWarning
|
|
17
|
+
} = options
|
|
18
|
+
|
|
19
|
+
if (!useExtendComponents[mode]) {
|
|
20
|
+
return {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const extendComponents = {}
|
|
24
|
+
|
|
25
|
+
useExtendComponents[mode].forEach((name) => {
|
|
26
|
+
// 从配置中获取该组件在当前平台的具体路径
|
|
27
|
+
const componentConfig = EXTEND_COMPONENT_CONFIG[name]
|
|
28
|
+
|
|
29
|
+
if (componentConfig && componentConfig[mode]) {
|
|
30
|
+
extendComponents[name] = normalize.lib(componentConfig[mode])
|
|
31
|
+
} else if (componentConfig) {
|
|
32
|
+
emitWarning('extend component ' + name + ' is not configured for ' + mode + ' environment!')
|
|
33
|
+
} else {
|
|
34
|
+
emitWarning('extend component ' + name + ' is not supported in any environment!')
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return extendComponents
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
processExtendComponents
|
|
43
|
+
}
|
package/lib/web/processJSON.js
CHANGED
|
@@ -11,6 +11,7 @@ const resolve = require('../utils/resolve')
|
|
|
11
11
|
const createJSONHelper = require('../json-compiler/helper')
|
|
12
12
|
const getRulesRunner = require('../platform/index')
|
|
13
13
|
const { RESOLVE_IGNORED_ERR } = require('../utils/const')
|
|
14
|
+
const { processExtendComponents } = require('../utils/process-extend-components')
|
|
14
15
|
const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
|
|
15
16
|
|
|
16
17
|
module.exports = function (jsonContent, {
|
|
@@ -30,11 +31,19 @@ module.exports = function (jsonContent, {
|
|
|
30
31
|
mode,
|
|
31
32
|
srcMode,
|
|
32
33
|
env,
|
|
33
|
-
projectRoot
|
|
34
|
+
projectRoot,
|
|
35
|
+
useExtendComponents = {},
|
|
36
|
+
appInfo
|
|
34
37
|
} = mpx
|
|
35
38
|
|
|
36
39
|
const context = loaderContext.context
|
|
37
40
|
|
|
41
|
+
let hasApp = true
|
|
42
|
+
|
|
43
|
+
if (!appInfo.name) {
|
|
44
|
+
hasApp = false
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
const emitWarning = (msg) => {
|
|
39
48
|
loaderContext.emitWarning(
|
|
40
49
|
new Error('[Mpx json warning][' + loaderContext.resource + ']: ' + msg)
|
|
@@ -116,7 +125,16 @@ module.exports = function (jsonContent, {
|
|
|
116
125
|
if (ctorType !== 'app') {
|
|
117
126
|
rulesRunnerOptions.mainKey = ctorType
|
|
118
127
|
}
|
|
119
|
-
|
|
128
|
+
if (!hasApp || ctorType === 'app') {
|
|
129
|
+
if (useExtendComponents[mode]) {
|
|
130
|
+
const extendComponents = processExtendComponents({
|
|
131
|
+
useExtendComponents,
|
|
132
|
+
mode,
|
|
133
|
+
emitWarning
|
|
134
|
+
})
|
|
135
|
+
jsonObj.usingComponents = Object.assign({}, extendComponents, jsonObj.usingComponents)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
120
138
|
const rulesRunner = getRulesRunner(rulesRunnerOptions)
|
|
121
139
|
|
|
122
140
|
if (rulesRunner) {
|