@soei/flyweight 0.0.10 → 0.0.11
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/{dist/Flyweight.cjs → Flyweight.cjs} +0 -0
- package/{dist/Flyweight.js → Flyweight.js} +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/package.json +8 -7
- package/{dist/style.css → style.css} +0 -0
- package/src/Flyweight.vue +0 -329
|
File without changes
|
|
File without changes
|
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -2,23 +2,24 @@
|
|
|
2
2
|
"name": "@soei/flyweight",
|
|
3
3
|
"private": false,
|
|
4
4
|
"description": "Vue组件, 列表de享元模式~减少DOM节点 flyweight",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.11",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "
|
|
8
|
-
"module": "
|
|
7
|
+
"main": "Flyweight.cjs",
|
|
8
|
+
"module": "Flyweight.js",
|
|
9
9
|
"files": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
10
|
+
"Flyweight.cjs",
|
|
11
|
+
"Flyweight.js",
|
|
12
|
+
"style.css",
|
|
13
13
|
"src/Flyweight.vue"
|
|
14
14
|
],
|
|
15
|
+
"homepage": "https://alwbg.github.io",
|
|
15
16
|
"scripts": {
|
|
16
17
|
"dev": "vite",
|
|
17
18
|
"build": "vite build",
|
|
18
19
|
"preview": "vite preview"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@soei/util": "^1.1.
|
|
22
|
+
"@soei/util": "^1.1.8"
|
|
22
23
|
},
|
|
23
24
|
"keywords": [
|
|
24
25
|
"Flyweight",
|
|
File without changes
|
package/src/Flyweight.vue
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div ref="flyweight" class="flyweight" :class="{
|
|
3
|
-
'flyweight-active': actice
|
|
4
|
-
}" :style="{
|
|
5
|
-
'--width': realW + 'px',
|
|
6
|
-
'--height': realH + 'px'
|
|
7
|
-
}" @scroll="scroll">
|
|
8
|
-
<div class="flyweight-all" :style="{
|
|
9
|
-
'--flyweight-height': Height + 'px'
|
|
10
|
-
}">
|
|
11
|
-
<div v-for="(item, index) in flyweights" :key="index" :data="item.top" :style="{
|
|
12
|
-
top: item.top + 'px',
|
|
13
|
-
left: item.left + 'px',
|
|
14
|
-
}">
|
|
15
|
-
<slot :data="item.data" :index="item.index"></slot>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
<slot name="end" v-if="flyweights.length"></slot>
|
|
19
|
-
</div>
|
|
20
|
-
</template>
|
|
21
|
-
|
|
22
|
-
<script>
|
|
23
|
-
import { each, picker, runer, isArray } from '@soei/util';
|
|
24
|
-
let isNil = (data) => {
|
|
25
|
-
return data == null || data == undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let Rs = /(\d+|[+\-\*/]|%)/g;
|
|
29
|
-
|
|
30
|
-
let math = {
|
|
31
|
-
'+': (a, b) => a + b,
|
|
32
|
-
'-': (a, b) => a - b,
|
|
33
|
-
'*': (a, b) => a * b,
|
|
34
|
-
'/': (a, b) => a / b,
|
|
35
|
-
'%': (a, b, c) => parseFloat(a) / 100 * c,
|
|
36
|
-
}
|
|
37
|
-
/* 从左到右顺序计算, 100% - 100px px单位会被忽略 */
|
|
38
|
-
let computer = (W, width) => {
|
|
39
|
-
let data;
|
|
40
|
-
if (data = runer('match', W, Rs)) {
|
|
41
|
-
let mark = data.length, re, T = 0, op, args = [];
|
|
42
|
-
while (mark--) {
|
|
43
|
-
T = data.shift();
|
|
44
|
-
if (T in math) {
|
|
45
|
-
re && args.push(re);
|
|
46
|
-
if (T === '%') args.length = 2;
|
|
47
|
-
op = T;
|
|
48
|
-
} else {
|
|
49
|
-
+T && args.push(+T)
|
|
50
|
-
}
|
|
51
|
-
if (args.length == 2) {
|
|
52
|
-
args.push(width);
|
|
53
|
-
re = math[op].apply(null, args);
|
|
54
|
-
args.length = 0;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (!(+re)) re = +args.pop()
|
|
58
|
-
W = re >> 0;
|
|
59
|
-
}
|
|
60
|
-
return W;
|
|
61
|
-
}
|
|
62
|
-
let Log = (...args) => {
|
|
63
|
-
console.info('::::FLYWEIGHT', ...args);
|
|
64
|
-
}
|
|
65
|
-
export default {
|
|
66
|
-
name: 'Flyweight',
|
|
67
|
-
props: {
|
|
68
|
-
flys: {
|
|
69
|
-
type: Array,
|
|
70
|
-
default: () => []
|
|
71
|
-
},
|
|
72
|
-
width: {
|
|
73
|
-
type: Number,
|
|
74
|
-
default: 0
|
|
75
|
-
},
|
|
76
|
-
height: {
|
|
77
|
-
type: Number,
|
|
78
|
-
default: 100
|
|
79
|
-
},
|
|
80
|
-
offset: {
|
|
81
|
-
type: Array,
|
|
82
|
-
default: () => [0, 0]
|
|
83
|
-
},
|
|
84
|
-
lazy: {
|
|
85
|
-
type: Number,
|
|
86
|
-
default: 100
|
|
87
|
-
},
|
|
88
|
-
view: {
|
|
89
|
-
type: Object,
|
|
90
|
-
default: () => (null)
|
|
91
|
-
},
|
|
92
|
-
index: {
|
|
93
|
-
type: Number,
|
|
94
|
-
default: 0
|
|
95
|
-
},
|
|
96
|
-
top: {
|
|
97
|
-
type: Number,
|
|
98
|
-
default: false
|
|
99
|
-
},
|
|
100
|
-
left: {
|
|
101
|
-
type: Number,
|
|
102
|
-
default: false
|
|
103
|
-
},
|
|
104
|
-
auto: {
|
|
105
|
-
type: [Boolean, String],
|
|
106
|
-
default: false
|
|
107
|
-
},
|
|
108
|
-
space: {
|
|
109
|
-
type: Object,
|
|
110
|
-
default: () => (null)
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
computed: {
|
|
114
|
-
flyweight() {
|
|
115
|
-
return this.$refs.flyweight;
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
data() {
|
|
119
|
-
return {
|
|
120
|
-
flyweights: [],
|
|
121
|
-
actice: false,
|
|
122
|
-
Height: null,
|
|
123
|
-
column: 1,
|
|
124
|
-
row: 1,
|
|
125
|
-
fwheight: 10,
|
|
126
|
-
|
|
127
|
-
count: 0,
|
|
128
|
-
task: [],
|
|
129
|
-
realW: 0,
|
|
130
|
-
realH: 0
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
watch: {
|
|
134
|
-
flys(data) {
|
|
135
|
-
this.count = data.length;
|
|
136
|
-
this.re();
|
|
137
|
-
let task = this.task.shift();
|
|
138
|
-
if (task) {
|
|
139
|
-
this.$nextTick(() => {
|
|
140
|
-
this.setview(task);
|
|
141
|
-
})
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
view: {
|
|
145
|
-
handler(data) {
|
|
146
|
-
this.setview(data)
|
|
147
|
-
},
|
|
148
|
-
immediate: true
|
|
149
|
-
},
|
|
150
|
-
index(index) {
|
|
151
|
-
this.setindex(index);
|
|
152
|
-
},
|
|
153
|
-
top(top) {
|
|
154
|
-
this.flyweight.scrollTop = top;
|
|
155
|
-
},
|
|
156
|
-
left(left) {
|
|
157
|
-
this.flyweight.scrollLeft = left;
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
mounted() {
|
|
161
|
-
this.flyweights = [];
|
|
162
|
-
this.$set || (this.$set = (list, index, value) => {
|
|
163
|
-
list[index] = value;
|
|
164
|
-
})
|
|
165
|
-
this.setindex(this.index);
|
|
166
|
-
try {
|
|
167
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
168
|
-
this.re();
|
|
169
|
-
this.$emit('resize');
|
|
170
|
-
// runer('dispatchEvent', window, new Event('resize', { view: window, bubbles: true, cancelable: true }));
|
|
171
|
-
});
|
|
172
|
-
resizeObserver.observe(this.flyweight);
|
|
173
|
-
} catch (error) {
|
|
174
|
-
Log(error);
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
methods: {
|
|
178
|
-
trigger(key, data) {
|
|
179
|
-
this.lazyrun(() => {
|
|
180
|
-
if (!isArray(key)) key = [[key, data]];
|
|
181
|
-
each(key, (k, v) => {
|
|
182
|
-
this.$emit(v[0], isNil(v[1]) ? true : v[1]);
|
|
183
|
-
})
|
|
184
|
-
});
|
|
185
|
-
},
|
|
186
|
-
cheackflys(data) {
|
|
187
|
-
let length = this.flys.length;
|
|
188
|
-
if (!length) {
|
|
189
|
-
data && this.task.push(data);
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
setview(data) {
|
|
194
|
-
runer([this.cheackflys, (data) => {
|
|
195
|
-
data = data || {};
|
|
196
|
-
let index = data.index || each(this.flys, (k, v, attr, value) => {
|
|
197
|
-
if (v[attr] == value) return k;
|
|
198
|
-
}, data.picker, data.id);
|
|
199
|
-
|
|
200
|
-
isNil(index) || this.setindex(index);
|
|
201
|
-
}], this, data)
|
|
202
|
-
},
|
|
203
|
-
setindex(index) {
|
|
204
|
-
runer([this.cheackflys, ({ index }) => {
|
|
205
|
-
this.$nextTick(() => {
|
|
206
|
-
let line = index / this.column >> 0;
|
|
207
|
-
let height = this.fwheight;
|
|
208
|
-
let first = this.flyweight.scrollTop / height >> 0;
|
|
209
|
-
let offset = first + this.row - line - 1;
|
|
210
|
-
if (offset > 0) return;
|
|
211
|
-
this.flyweight.scrollTop = line * height;
|
|
212
|
-
|
|
213
|
-
this.scroll()
|
|
214
|
-
})
|
|
215
|
-
}], this, { index: index })
|
|
216
|
-
},
|
|
217
|
-
lazyrun(back, time) {
|
|
218
|
-
clearTimeout(this.time);
|
|
219
|
-
this.time = setTimeout(() => {
|
|
220
|
-
runer(back);
|
|
221
|
-
}, time || this.lazy);
|
|
222
|
-
},
|
|
223
|
-
run(e) {
|
|
224
|
-
let position = picker(e.target, 'scrollTop=>top');
|
|
225
|
-
each(this.flyweights, (k, v, offset, row, column, first, index, i) => {
|
|
226
|
-
offset = k / column >> 0;
|
|
227
|
-
index = offset + row * (
|
|
228
|
-
/* 偏移量, 如果超出顶部 + 1轮,排列到列队后, 否则保持在当前*/
|
|
229
|
-
+(offset < first % row)
|
|
230
|
-
/* 计算轮数, row的倍数 */
|
|
231
|
-
+ (first / row >> 0)
|
|
232
|
-
);
|
|
233
|
-
i = index * column + k % column;
|
|
234
|
-
|
|
235
|
-
if (i >= this.count) {
|
|
236
|
-
this.trigger('onend');
|
|
237
|
-
return /* true */;
|
|
238
|
-
}
|
|
239
|
-
v.index = index;
|
|
240
|
-
v.top = index * this.fwheight;
|
|
241
|
-
v.data = this.flys[i];
|
|
242
|
-
},
|
|
243
|
-
null,
|
|
244
|
-
this.row,
|
|
245
|
-
this.column,
|
|
246
|
-
/* 显示区域第一行的索引 */
|
|
247
|
-
position.top / this.fwheight >> 0
|
|
248
|
-
)
|
|
249
|
-
},
|
|
250
|
-
scroll(e) {
|
|
251
|
-
this.run(e || { target: this.flyweight });
|
|
252
|
-
},
|
|
253
|
-
re() {
|
|
254
|
-
let size = this.count || this.flys.length;
|
|
255
|
-
let fws = this.flyweights;
|
|
256
|
-
if (!size) return fws.length = size;
|
|
257
|
-
this.count = size;
|
|
258
|
-
let flyweight = this.flyweight;
|
|
259
|
-
let wh = picker(flyweight, 'clientHeight=>height,clientWidth=>width');
|
|
260
|
-
this.$nextTick(() => {
|
|
261
|
-
let auto = this.auto === true;
|
|
262
|
-
let [x, y] = this.offset, W = wh.width, H = wh.height;
|
|
263
|
-
let width = (computer(this.width, W) || W) + x;
|
|
264
|
-
let height = computer(this.height, H) + y/* 偏移量填充宽度 */;
|
|
265
|
-
this.realW = width - x;
|
|
266
|
-
this.realH = height - y/* 实际高度减掉偏移量 */;
|
|
267
|
-
let column = (W / width >> 0) || 1,
|
|
268
|
-
row = H / height >> 0;
|
|
269
|
-
this.row = row + 2/* 上下各一行补位 */;
|
|
270
|
-
this.column = column;
|
|
271
|
-
this.fwheight = height;
|
|
272
|
-
let offset = W % width;
|
|
273
|
-
/* 偏移量 */
|
|
274
|
-
let margin = offset / (column - 1 * +!auto) >> 0;
|
|
275
|
-
if (auto) {
|
|
276
|
-
width = this.realW = (W / column >> 0) - x;
|
|
277
|
-
margin = x;
|
|
278
|
-
}
|
|
279
|
-
/* 总高度 */
|
|
280
|
-
this.Height = Math.ceil(size / column) * height;
|
|
281
|
-
/* 计算数量 */
|
|
282
|
-
let count = Math.min(size, column * this.row),
|
|
283
|
-
length = count - 1,
|
|
284
|
-
index,
|
|
285
|
-
fly;
|
|
286
|
-
while (count-- > 0) {
|
|
287
|
-
index = length - count;
|
|
288
|
-
fly = this.flys[index];
|
|
289
|
-
flyweight = fws[index];
|
|
290
|
-
row = index / column >> 0;
|
|
291
|
-
this.$set(fws, index, {
|
|
292
|
-
data: fly,
|
|
293
|
-
top: row * height,
|
|
294
|
-
left: (index % column) * (width + margin),
|
|
295
|
-
index: row
|
|
296
|
-
})
|
|
297
|
-
}
|
|
298
|
-
fws.length = length + 1;
|
|
299
|
-
let triggers = [];
|
|
300
|
-
if (H / height > length) triggers.push(['onend']);
|
|
301
|
-
this.scroll();
|
|
302
|
-
/* 计算占用空间 */
|
|
303
|
-
triggers.push(['update:space', { row: (length / column >> 0) + 1, column: column }]);
|
|
304
|
-
|
|
305
|
-
this.trigger(triggers);
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
</script>
|
|
311
|
-
|
|
312
|
-
<style lang="scss" scoped>
|
|
313
|
-
.flyweight {
|
|
314
|
-
height: 100%;
|
|
315
|
-
width: 100%;
|
|
316
|
-
overflow: auto;
|
|
317
|
-
position: relative;
|
|
318
|
-
|
|
319
|
-
.flyweight-all {
|
|
320
|
-
height: var(--flyweight-height);
|
|
321
|
-
|
|
322
|
-
&>* {
|
|
323
|
-
width: calc(var(--width));
|
|
324
|
-
height: var(--height);
|
|
325
|
-
position: absolute;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
</style>
|