@soei/flyweight 0.0.1 → 0.0.3
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/README.md +124 -5
- package/dist/Flyweight.cjs +1 -1
- package/dist/Flyweight.js +105 -58
- package/dist/style.css +1 -1
- package/package.json +9 -9
- package/src/Flyweight.vue +82 -29
package/README.md
CHANGED
|
@@ -1,22 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
# 享元模式
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```html
|
|
4
|
+
<div style="height:100px;width:300px;">
|
|
5
|
+
<!-- 确认父容器 宽 高 存在, 依赖父容器 `宽`, `高` 计算 -->
|
|
6
|
+
<s-flyweight ...></s-flyweight>
|
|
7
|
+
</div>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
### 更新日志
|
|
11
|
+
|
|
12
|
+
### `0.0.3`
|
|
13
|
+
|
|
14
|
+
- #### 新增 `:top`
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<s-flyweight :top="滚动高度"></s-flyweight>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### `0.0.2`
|
|
21
|
+
|
|
22
|
+
- #### 优化了 `Vue3` 的 `兼容` 问题
|
|
23
|
+
|
|
24
|
+
`Vue3` 引入方式
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<script>
|
|
28
|
+
import { Flyweight } from "@soei/flyweight";
|
|
29
|
+
</script>
|
|
30
|
+
<!-- 非 <style scoped> scoped-->
|
|
31
|
+
<style>
|
|
32
|
+
@import "@soei/flyweight/dist/style.css";
|
|
33
|
+
</style>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`或` 源码引入
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
import Flyweight from "@soei/flyweight/src/Flyweight.vue";
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`或`
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// main.js
|
|
46
|
+
import "@soei/flyweight/dist/style.css";
|
|
47
|
+
import flyweight from "@soei/flyweight";
|
|
48
|
+
Vue.use(flyweight);
|
|
49
|
+
// use.vue
|
|
50
|
+
<s-flyweight ...></s-flyweight>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## `安装`
|
|
4
54
|
|
|
5
55
|
```
|
|
6
56
|
npm i @soei/flyweight
|
|
7
57
|
|
|
8
58
|
```
|
|
9
59
|
|
|
10
|
-
|
|
60
|
+
## `引用`
|
|
11
61
|
|
|
12
62
|
```javascript
|
|
13
63
|
// 引入方式 vue2
|
|
14
64
|
import Flyweight from "@soei/flyweight/src/Flyweight.vue";
|
|
15
|
-
// 引入方式
|
|
65
|
+
// 引入方式 Vue3
|
|
16
66
|
import { Flyweight } from "@soei/flyweight";
|
|
17
67
|
```
|
|
18
68
|
|
|
19
|
-
|
|
69
|
+
## `使用`
|
|
20
70
|
|
|
21
71
|
```html
|
|
22
72
|
<Flyweight
|
|
@@ -31,3 +81,72 @@ import { Flyweight } from "@soei/flyweight";
|
|
|
31
81
|
<template #default="{data, index}"> ...todo </template>
|
|
32
82
|
</Flyweight>
|
|
33
83
|
```
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<Flyweight [attrs]></Flyweight>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## `index` 和 `view` 只生效一个
|
|
90
|
+
|
|
91
|
+
### _`index`_ 定位索引
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
// 格式
|
|
95
|
+
Number;
|
|
96
|
+
:index="10";
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### _`view`_ 指定显示哪个索引
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
// 格式
|
|
103
|
+
{
|
|
104
|
+
// 定位属性
|
|
105
|
+
id: Number,
|
|
106
|
+
// 定位属性字段名称
|
|
107
|
+
picker: String
|
|
108
|
+
}
|
|
109
|
+
:view="{id: 10, picker: 'id'}";
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### _`flys`_ 显示的`数据列表`
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// 格式
|
|
116
|
+
Array;
|
|
117
|
+
:flys="[]";
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### _`width`_ 单个容器 `宽度`
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// 格式
|
|
124
|
+
Number;
|
|
125
|
+
// 默认: 0, 占整行
|
|
126
|
+
:width="100";
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### _`height`_ 单个容器 `高度`
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
// 格式
|
|
133
|
+
Number;
|
|
134
|
+
// 默认: 100
|
|
135
|
+
:height="10";
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### _`offset`_ 偏移量 _[`左右`, `上下`]_
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
// 格式
|
|
142
|
+
Array = [左右, 上下];
|
|
143
|
+
:offset="[0, 30]";
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `@onend` 拉到`底部`时的回调
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
// 格式
|
|
150
|
+
Function;
|
|
151
|
+
@onend="function(){}";
|
|
152
|
+
```
|
package/dist/Flyweight.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("@soei/util"),h=require("vue");const p=(e,t)=>{const i=e.__vccOpts||e;for(const[r,l]of t)i[r]=l;return i};let m=e=>e==null||e==null,x=(...e)=>{console.info("::::FLYWEIGHT",...e)};const k={name:"Flyweight",props:{flys:{type:Array,default:()=>[]},width:{type:Number,default:0},height:{type:Number,default:100},offset:{type:Array,default:()=>[0,0]},lazy:{type:Number,default:100},view:{type:Object,default:()=>null},index:{type:Number,default:0},top:{type:Number,default:!1},left:{type:Number,default:!1}},computed:{flyweight(){return this.$refs.flyweight}},data(){return{flyweights:[],actice:!1,Height:null,column:1,row:1,fwheight:10,count:0,task:[]}},watch:{flys(e){this.count=e.length,this.re();let t=this.task.shift();t&&this.$nextTick(()=>{this.setview(t)})},view:{handler(e){this.setview(e)},immediate:!0},index(e){this.setindex(e)},top(e){this.flyweight.scrollTop=e},left(e){this.flyweight.scrollLeft=e}},mounted(){this.flyweights=[],this.$set||(this.$set=(e,t,i)=>{e[t]=i}),this.setindex(this.index);try{new ResizeObserver(()=>{this.re(),this.$emit("resize")}).observe(this.flyweight)}catch(e){x(e)}},methods:{cheackflys(e){if(!this.flys.length)return e&&this.task.push(e),!0},setview(e){c.runer([this.cheackflys,t=>{t=t||{};let i=t.index||c.each(this.flys,(r,l,n,s)=>{if(l[n]==s)return r},t.picker,t.id);m(i)||this.setindex(i)}],this,e)},setindex(e){c.runer([this.cheackflys,({index:t})=>{this.$nextTick(()=>{let i=t/this.column>>0,r=this.fwheight;(this.flyweight.scrollTop/r>>0)+this.row-i-1>0||(this.flyweight.scrollTop=i*r,this.scroll())})}],this,{index:e})},lazyrun(e,t){clearTimeout(this.time),this.time=setTimeout(()=>{c.runer(e)},t||this.lazy)},run(e){let t=c.picker(e.target,"scrollTop=>top");c.each(this.flyweights,(i,r,l,n,s,o,u,y)=>{if(l=i/s>>0,u=l+n*(+(l<o%n)+(o/n>>0)),y=u*s+i%s,y>=this.count){this.lazyrun(()=>this.$emit("onend",!0));return}r.index=u,r.top=r.index*this.fwheight,r.data=this.flys[y]},null,this.row,this.column,t.top/this.fwheight>>0)},scroll(e){this.run(e||{target:this.flyweight})},re(){let e=this.flyweight,t=c.picker(e,"clientHeight=>height,clientWidth=>width");this.$nextTick(()=>{let[i,r]=this.offset,l=this.width;l==0&&(l=t.width);let n=l+i,s=this.height+r,o=t.width/n>>0,u=t.height/s>>0;this.row=u+2,this.column=o,this.fwheight=s;let y=t.width%n/(o-1)>>0;this.Height=Math.ceil(this.count/o)*s;let d=Math.min(this.count,o*this.row),a=d-1,f,g;for(;d-- >0;)f=a-d,g=this.flys[f],e=this.flyweights[f],this.$set(this.flyweights,f,{data:g,top:(f/o>>0)*s,left:f%o*(n+y),index:f/o>>0});this.flyweights.length=a+1,this.scroll()})}}};function _(e,t,i,r,l,n){return h.openBlock(),h.createElementBlock("div",{ref:"flyweight",class:h.normalizeClass(["flyweight",{"flyweight-active":l.actice}]),style:h.normalizeStyle({"--width":i.width?i.width+"px":"100%","--height":i.height+"px"}),onScroll:t[0]||(t[0]=(...s)=>n.scroll&&n.scroll(...s))},[h.createElementVNode("div",{class:"flyweight-all",style:h.normalizeStyle({"--flyweight-height":l.Height+"px"})},[(h.openBlock(!0),h.createElementBlock(h.Fragment,null,h.renderList(l.flyweights,(s,o)=>(h.openBlock(),h.createElementBlock("div",{key:o,style:h.normalizeStyle({top:s.top+"px",left:s.left+"px"})},[h.renderSlot(e.$slots,"default",{data:s.data,index:s.index},void 0,!0)],4))),128))],4),l.flyweights.length?h.renderSlot(e.$slots,"end",{key:0},void 0,!0):h.createCommentVNode("",!0)],38)}const w=p(k,[["render",_],["__scopeId","data-v-075d9b23"]]),v=[w],b={install(e){v.forEach(t=>{e.component("s-"+t.name.toLowerCase(),t)})}};exports.Flyweight=w;exports.default=b;
|
package/dist/Flyweight.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { openBlock as
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
for (const [
|
|
6
|
-
l
|
|
7
|
-
return
|
|
1
|
+
import { runer as y, each as m, picker as x } from "@soei/util";
|
|
2
|
+
import { openBlock as d, createElementBlock as g, normalizeClass as k, normalizeStyle as w, createElementVNode as v, Fragment as b, renderList as z, renderSlot as _, createCommentVNode as T } from "vue";
|
|
3
|
+
const N = (t, e) => {
|
|
4
|
+
const i = t.__vccOpts || t;
|
|
5
|
+
for (const [l, s] of e)
|
|
6
|
+
i[l] = s;
|
|
7
|
+
return i;
|
|
8
8
|
};
|
|
9
|
-
let
|
|
9
|
+
let $ = (t) => t == null || t == null, F = (...t) => {
|
|
10
10
|
console.info("::::FLYWEIGHT", ...t);
|
|
11
11
|
};
|
|
12
|
-
const
|
|
12
|
+
const H = {
|
|
13
|
+
name: "Flyweight",
|
|
13
14
|
props: {
|
|
14
15
|
flys: {
|
|
15
16
|
type: Array,
|
|
@@ -33,11 +34,19 @@ const N = {
|
|
|
33
34
|
},
|
|
34
35
|
view: {
|
|
35
36
|
type: Object,
|
|
36
|
-
default: () =>
|
|
37
|
+
default: () => null
|
|
37
38
|
},
|
|
38
39
|
index: {
|
|
39
40
|
type: Number,
|
|
40
41
|
default: 0
|
|
42
|
+
},
|
|
43
|
+
top: {
|
|
44
|
+
type: Number,
|
|
45
|
+
default: !1
|
|
46
|
+
},
|
|
47
|
+
left: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: !1
|
|
41
50
|
}
|
|
42
51
|
},
|
|
43
52
|
computed: {
|
|
@@ -49,126 +58,164 @@ const N = {
|
|
|
49
58
|
return {
|
|
50
59
|
flyweights: [],
|
|
51
60
|
actice: !1,
|
|
52
|
-
|
|
61
|
+
Height: null,
|
|
53
62
|
column: 1,
|
|
54
63
|
row: 1,
|
|
55
64
|
fwheight: 10,
|
|
56
|
-
count: 0
|
|
65
|
+
count: 0,
|
|
66
|
+
task: []
|
|
57
67
|
};
|
|
58
68
|
},
|
|
59
69
|
watch: {
|
|
60
70
|
flys(t) {
|
|
61
71
|
this.count = t.length, this.re();
|
|
72
|
+
let e = this.task.shift();
|
|
73
|
+
e && this.$nextTick(() => {
|
|
74
|
+
this.setview(e);
|
|
75
|
+
});
|
|
62
76
|
},
|
|
63
|
-
view
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.$emit("update:index", e);
|
|
77
|
+
view: {
|
|
78
|
+
handler(t) {
|
|
79
|
+
this.setview(t);
|
|
80
|
+
},
|
|
81
|
+
immediate: !0
|
|
69
82
|
},
|
|
70
83
|
index(t) {
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
this.setindex(t);
|
|
85
|
+
},
|
|
86
|
+
top(t) {
|
|
87
|
+
this.flyweight.scrollTop = t;
|
|
88
|
+
},
|
|
89
|
+
left(t) {
|
|
90
|
+
this.flyweight.scrollLeft = t;
|
|
73
91
|
}
|
|
74
92
|
},
|
|
75
93
|
mounted() {
|
|
76
|
-
this.flyweights = []
|
|
94
|
+
this.flyweights = [], this.$set || (this.$set = (t, e, i) => {
|
|
95
|
+
t[e] = i;
|
|
96
|
+
}), this.setindex(this.index);
|
|
77
97
|
try {
|
|
78
98
|
new ResizeObserver(() => {
|
|
79
99
|
this.re(), this.$emit("resize");
|
|
80
100
|
}).observe(this.flyweight);
|
|
81
101
|
} catch (t) {
|
|
82
|
-
|
|
102
|
+
F(t);
|
|
83
103
|
}
|
|
84
104
|
},
|
|
85
105
|
methods: {
|
|
106
|
+
cheackflys(t) {
|
|
107
|
+
if (!this.flys.length)
|
|
108
|
+
return t && this.task.push(t), !0;
|
|
109
|
+
},
|
|
110
|
+
setview(t) {
|
|
111
|
+
y([this.cheackflys, (e) => {
|
|
112
|
+
e = e || {};
|
|
113
|
+
let i = e.index || m(this.flys, (l, s, r, h) => {
|
|
114
|
+
if (s[r] == h)
|
|
115
|
+
return l;
|
|
116
|
+
}, e.picker, e.id);
|
|
117
|
+
$(i) || this.setindex(i);
|
|
118
|
+
}], this, t);
|
|
119
|
+
},
|
|
120
|
+
setindex(t) {
|
|
121
|
+
y([this.cheackflys, ({ index: e }) => {
|
|
122
|
+
this.$nextTick(() => {
|
|
123
|
+
let i = e / this.column >> 0, l = this.fwheight;
|
|
124
|
+
(this.flyweight.scrollTop / l >> 0) + this.row - i - 1 > 0 || (this.flyweight.scrollTop = i * l, this.scroll());
|
|
125
|
+
});
|
|
126
|
+
}], this, { index: t });
|
|
127
|
+
},
|
|
86
128
|
lazyrun(t, e) {
|
|
87
129
|
clearTimeout(this.time), this.time = setTimeout(() => {
|
|
88
|
-
|
|
130
|
+
y(t);
|
|
89
131
|
}, e || this.lazy);
|
|
90
132
|
},
|
|
91
133
|
run(t) {
|
|
92
|
-
let e =
|
|
93
|
-
|
|
134
|
+
let e = x(t.target, "scrollTop=>top");
|
|
135
|
+
m(
|
|
94
136
|
this.flyweights,
|
|
95
|
-
(l, s,
|
|
96
|
-
if (
|
|
97
|
-
(+(
|
|
98
|
-
|
|
99
|
-
|
|
137
|
+
(i, l, s, r, h, n, f, c) => {
|
|
138
|
+
if (s = i / h >> 0, f = s + r * /* 偏移量, 如果超出顶部 + 1轮,排列到列队后, 否则保持在当前*/
|
|
139
|
+
(+(s < n % r) + (n / r >> 0)), c = f * h + i % h, c >= this.count) {
|
|
140
|
+
this.lazyrun(() => this.$emit("onend", !0));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
l.index = f, l.top = l.index * this.fwheight, l.data = this.flys[c];
|
|
100
144
|
},
|
|
101
145
|
null,
|
|
102
146
|
this.row,
|
|
103
147
|
this.column,
|
|
104
148
|
/* 显示区域第一行的索引 */
|
|
105
149
|
e.top / this.fwheight >> 0
|
|
106
|
-
)
|
|
150
|
+
);
|
|
107
151
|
},
|
|
108
152
|
scroll(t) {
|
|
109
|
-
this.run(t);
|
|
153
|
+
this.run(t || { target: this.flyweight });
|
|
110
154
|
},
|
|
111
155
|
re() {
|
|
112
|
-
let t = this.flyweight, e =
|
|
156
|
+
let t = this.flyweight, e = x(t, "clientHeight=>height,clientWidth=>width");
|
|
113
157
|
this.$nextTick(() => {
|
|
114
|
-
let [
|
|
115
|
-
|
|
116
|
-
let r =
|
|
117
|
-
this.row = f + 2, this.column = n, this.fwheight = h
|
|
118
|
-
let c = e.width % r / (n - 1) >> 0
|
|
158
|
+
let [i, l] = this.offset, s = this.width;
|
|
159
|
+
s == 0 && (s = e.width);
|
|
160
|
+
let r = s + i, h = this.height + l, n = e.width / r >> 0, f = e.height / h >> 0;
|
|
161
|
+
this.row = f + 2, this.column = n, this.fwheight = h;
|
|
162
|
+
let c = e.width % r / (n - 1) >> 0;
|
|
163
|
+
this.Height = Math.ceil(this.count / n) * h;
|
|
164
|
+
let u = Math.min(this.count, n * this.row), a = u - 1, o, p;
|
|
119
165
|
for (; u-- > 0; )
|
|
120
|
-
o =
|
|
121
|
-
data:
|
|
166
|
+
o = a - u, p = this.flys[o], t = this.flyweights[o], this.$set(this.flyweights, o, {
|
|
167
|
+
data: p,
|
|
122
168
|
top: (o / n >> 0) * h,
|
|
123
169
|
left: o % n * (r + c),
|
|
124
170
|
index: o / n >> 0
|
|
125
171
|
});
|
|
126
|
-
this.flyweights.length =
|
|
172
|
+
this.flyweights.length = a + 1, this.scroll();
|
|
127
173
|
});
|
|
128
174
|
}
|
|
129
175
|
}
|
|
130
176
|
};
|
|
131
|
-
function
|
|
132
|
-
return
|
|
177
|
+
function L(t, e, i, l, s, r) {
|
|
178
|
+
return d(), g("div", {
|
|
133
179
|
ref: "flyweight",
|
|
134
|
-
class:
|
|
135
|
-
"flyweight-active":
|
|
180
|
+
class: k(["flyweight", {
|
|
181
|
+
"flyweight-active": s.actice
|
|
136
182
|
}]),
|
|
137
|
-
style:
|
|
138
|
-
"--width":
|
|
139
|
-
"--height":
|
|
183
|
+
style: w({
|
|
184
|
+
"--width": i.width ? i.width + "px" : "100%",
|
|
185
|
+
"--height": i.height + "px"
|
|
140
186
|
}),
|
|
141
187
|
onScroll: e[0] || (e[0] = (...h) => r.scroll && r.scroll(...h))
|
|
142
188
|
}, [
|
|
143
189
|
v("div", {
|
|
144
190
|
class: "flyweight-all",
|
|
145
|
-
style:
|
|
146
|
-
"--flyweight-height":
|
|
191
|
+
style: w({
|
|
192
|
+
"--flyweight-height": s.Height + "px"
|
|
147
193
|
})
|
|
148
194
|
}, [
|
|
149
|
-
(
|
|
195
|
+
(d(!0), g(b, null, z(s.flyweights, (h, n) => (d(), g("div", {
|
|
150
196
|
key: n,
|
|
151
|
-
style:
|
|
197
|
+
style: w({
|
|
152
198
|
top: h.top + "px",
|
|
153
199
|
left: h.left + "px"
|
|
154
200
|
})
|
|
155
201
|
}, [
|
|
156
|
-
|
|
202
|
+
_(t.$slots, "default", {
|
|
157
203
|
data: h.data,
|
|
158
204
|
index: h.index
|
|
159
205
|
}, void 0, !0)
|
|
160
206
|
], 4))), 128))
|
|
161
|
-
], 4)
|
|
207
|
+
], 4),
|
|
208
|
+
s.flyweights.length ? _(t.$slots, "end", { key: 0 }, void 0, !0) : T("", !0)
|
|
162
209
|
], 38);
|
|
163
210
|
}
|
|
164
|
-
const
|
|
211
|
+
const O = /* @__PURE__ */ N(H, [["render", L], ["__scopeId", "data-v-075d9b23"]]), E = [O], S = {
|
|
165
212
|
install(t) {
|
|
166
|
-
|
|
167
|
-
t.component("s-" + e.
|
|
213
|
+
E.forEach((e) => {
|
|
214
|
+
t.component("s-" + e.name.toLowerCase(), e);
|
|
168
215
|
});
|
|
169
216
|
}
|
|
170
217
|
};
|
|
171
218
|
export {
|
|
172
|
-
|
|
219
|
+
O as Flyweight,
|
|
173
220
|
S as default
|
|
174
221
|
};
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.flyweight[data-v-
|
|
1
|
+
.flyweight[data-v-075d9b23]{height:100%;width:100%;overflow:auto;position:relative}.flyweight .flyweight-all[data-v-075d9b23]{height:var(--flyweight-height)}.flyweight .flyweight-all[data-v-075d9b23]>*{width:var(--width);height:var(--height);position:absolute}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soei/flyweight",
|
|
3
3
|
"private": false,
|
|
4
|
-
"
|
|
4
|
+
"description": "Vue组件, 列表de享元模式~减少DOM节点 flyweight",
|
|
5
|
+
"version": "0.0.3",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "dist/Flyweight.cjs",
|
|
7
8
|
"module": "dist/Flyweight.js",
|
|
@@ -15,13 +16,12 @@
|
|
|
15
16
|
"preview": "vite preview"
|
|
16
17
|
},
|
|
17
18
|
"dependencies": {
|
|
18
|
-
"@soei/util": "^1.1.1"
|
|
19
|
-
"vue": "^3.3.4"
|
|
19
|
+
"@soei/util": "^1.1.1"
|
|
20
20
|
},
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
21
|
+
"keywords": [
|
|
22
|
+
"Flyweight",
|
|
23
|
+
"享元模式",
|
|
24
|
+
"List",
|
|
25
|
+
"列表展示"
|
|
26
|
+
]
|
|
27
27
|
}
|
package/src/Flyweight.vue
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'--height': height + 'px'
|
|
7
7
|
}" @scroll="scroll">
|
|
8
8
|
<div class="flyweight-all" :style="{
|
|
9
|
-
'--flyweight-height':
|
|
9
|
+
'--flyweight-height': Height + 'px'
|
|
10
10
|
}">
|
|
11
11
|
<div v-for="(item, index) in flyweights" :key="index" :style="{
|
|
12
12
|
top: item.top + 'px',
|
|
@@ -15,17 +15,23 @@
|
|
|
15
15
|
<slot :data="item.data" :index="item.index"></slot>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
|
+
<slot name="end" v-if="flyweights.length"></slot>
|
|
18
19
|
</div>
|
|
19
20
|
</template>
|
|
20
21
|
|
|
21
22
|
<script>
|
|
22
23
|
import { each, picker, runer } from '@soei/util';
|
|
23
24
|
|
|
25
|
+
let isNil = (data) => {
|
|
26
|
+
return data == null || data == undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
let Log = (...args) => {
|
|
25
30
|
console.info('::::FLYWEIGHT', ...args);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
export default {
|
|
34
|
+
name: 'Flyweight',
|
|
29
35
|
props: {
|
|
30
36
|
flys: {
|
|
31
37
|
type: Array,
|
|
@@ -49,11 +55,19 @@ export default {
|
|
|
49
55
|
},
|
|
50
56
|
view: {
|
|
51
57
|
type: Object,
|
|
52
|
-
default: () => (
|
|
58
|
+
default: () => (null)
|
|
53
59
|
},
|
|
54
60
|
index: {
|
|
55
61
|
type: Number,
|
|
56
62
|
default: 0
|
|
63
|
+
},
|
|
64
|
+
top: {
|
|
65
|
+
type: Number,
|
|
66
|
+
default: false
|
|
67
|
+
},
|
|
68
|
+
left: {
|
|
69
|
+
type: Number,
|
|
70
|
+
default: false
|
|
57
71
|
}
|
|
58
72
|
},
|
|
59
73
|
computed: {
|
|
@@ -65,38 +79,48 @@ export default {
|
|
|
65
79
|
return {
|
|
66
80
|
flyweights: [],
|
|
67
81
|
actice: false,
|
|
68
|
-
|
|
82
|
+
Height: null,
|
|
69
83
|
column: 1,
|
|
70
84
|
row: 1,
|
|
71
85
|
fwheight: 10,
|
|
72
86
|
|
|
73
|
-
count: 0
|
|
87
|
+
count: 0,
|
|
88
|
+
task: []
|
|
74
89
|
}
|
|
75
90
|
},
|
|
76
91
|
watch: {
|
|
77
92
|
flys(data) {
|
|
78
93
|
this.count = data.length;
|
|
79
94
|
this.re();
|
|
95
|
+
let task = this.task.shift();
|
|
96
|
+
if (task) {
|
|
97
|
+
this.$nextTick(() => {
|
|
98
|
+
this.setview(task);
|
|
99
|
+
})
|
|
100
|
+
}
|
|
80
101
|
},
|
|
81
|
-
view
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// runer('dispatchEvent', window, new Event('resize', { view: this.flyweight, bubbles: true, cancelable: true }));
|
|
87
|
-
this.$emit('update:index', index);
|
|
102
|
+
view: {
|
|
103
|
+
handler(data) {
|
|
104
|
+
this.setview(data)
|
|
105
|
+
},
|
|
106
|
+
immediate: true
|
|
88
107
|
},
|
|
89
108
|
index(index) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
this.setindex(index);
|
|
110
|
+
},
|
|
111
|
+
top(top) {
|
|
112
|
+
this.flyweight.scrollTop = top;
|
|
113
|
+
},
|
|
114
|
+
left(left) {
|
|
115
|
+
this.flyweight.scrollLeft = left;
|
|
96
116
|
}
|
|
97
117
|
},
|
|
98
118
|
mounted() {
|
|
99
119
|
this.flyweights = [];
|
|
120
|
+
this.$set || (this.$set = (list, index, value) => {
|
|
121
|
+
list[index] = value;
|
|
122
|
+
})
|
|
123
|
+
this.setindex(this.index);
|
|
100
124
|
try {
|
|
101
125
|
const resizeObserver = new ResizeObserver(() => {
|
|
102
126
|
this.re();
|
|
@@ -109,6 +133,37 @@ export default {
|
|
|
109
133
|
}
|
|
110
134
|
},
|
|
111
135
|
methods: {
|
|
136
|
+
cheackflys(data) {
|
|
137
|
+
let length = this.flys.length;
|
|
138
|
+
if (!length) {
|
|
139
|
+
data && this.task.push(data);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
setview(data) {
|
|
144
|
+
runer([this.cheackflys, (data) => {
|
|
145
|
+
data = data || {};
|
|
146
|
+
let index = data.index || each(this.flys, (k, v, attr, value) => {
|
|
147
|
+
if (v[attr] == value) return k;
|
|
148
|
+
}, data.picker, data.id);
|
|
149
|
+
|
|
150
|
+
isNil(index) || this.setindex(index);
|
|
151
|
+
}], this, data)
|
|
152
|
+
},
|
|
153
|
+
setindex(index) {
|
|
154
|
+
runer([this.cheackflys, ({ index }) => {
|
|
155
|
+
this.$nextTick(() => {
|
|
156
|
+
let line = index / this.column >> 0;
|
|
157
|
+
let height = this.fwheight;
|
|
158
|
+
let first = this.flyweight.scrollTop / height >> 0;
|
|
159
|
+
let offset = first + this.row - line - 1;
|
|
160
|
+
if (offset > 0) return;
|
|
161
|
+
this.flyweight.scrollTop = line * height;
|
|
162
|
+
|
|
163
|
+
this.scroll()
|
|
164
|
+
})
|
|
165
|
+
}], this, { index: index })
|
|
166
|
+
},
|
|
112
167
|
lazyrun(back, time) {
|
|
113
168
|
clearTimeout(this.time);
|
|
114
169
|
this.time = setTimeout(() => {
|
|
@@ -117,7 +172,7 @@ export default {
|
|
|
117
172
|
},
|
|
118
173
|
run(e) {
|
|
119
174
|
let position = picker(e.target, 'scrollTop=>top');
|
|
120
|
-
|
|
175
|
+
each(this.flyweights, (k, v, offset, row, column, first, index, i) => {
|
|
121
176
|
offset = k / column >> 0;
|
|
122
177
|
index = offset + row * (
|
|
123
178
|
/* 偏移量, 如果超出顶部 + 1轮,排列到列队后, 否则保持在当前*/
|
|
@@ -127,9 +182,9 @@ export default {
|
|
|
127
182
|
);
|
|
128
183
|
i = index * column + k % column;
|
|
129
184
|
|
|
130
|
-
// Log(k, i, index);
|
|
131
185
|
if (i >= this.count) {
|
|
132
|
-
|
|
186
|
+
this.lazyrun(() => this.$emit('onend', true));
|
|
187
|
+
return /* true */;
|
|
133
188
|
}
|
|
134
189
|
v.index = index;
|
|
135
190
|
v.top = v.index * this.fwheight;
|
|
@@ -140,17 +195,15 @@ export default {
|
|
|
140
195
|
this.column,
|
|
141
196
|
/* 显示区域第一行的索引 */
|
|
142
197
|
position.top / this.fwheight >> 0
|
|
143
|
-
)
|
|
144
|
-
this.lazyrun(() => this.$emit('onend', true))
|
|
145
|
-
}
|
|
198
|
+
)
|
|
146
199
|
},
|
|
147
200
|
scroll(e) {
|
|
148
|
-
this.run(e);
|
|
201
|
+
this.run(e || { target: this.flyweight });
|
|
149
202
|
},
|
|
203
|
+
|
|
150
204
|
re() {
|
|
151
205
|
let flyweight = this.flyweight;
|
|
152
206
|
let wh = picker(flyweight, 'clientHeight=>height,clientWidth=>width');
|
|
153
|
-
// Log(wh, wh.width / this.width, wh.height / this.height);
|
|
154
207
|
this.$nextTick(() => {
|
|
155
208
|
let [x, y] = this.offset,
|
|
156
209
|
W = this.width;
|
|
@@ -164,10 +217,10 @@ export default {
|
|
|
164
217
|
this.row = row + 2/* 上下各一行补位 */;
|
|
165
218
|
this.column = column;
|
|
166
219
|
this.fwheight = height;
|
|
167
|
-
/* 总高度 */
|
|
168
|
-
this.H = (this.count / column) * height;
|
|
169
220
|
/* 偏移量 */
|
|
170
221
|
let margin = (wh.width % width) / (column - 1) >> 0;
|
|
222
|
+
/* 总高度 */
|
|
223
|
+
this.Height = Math.ceil(this.count / column) * height;
|
|
171
224
|
/* 计算数量 */
|
|
172
225
|
let count = Math.min(this.count, column * this.row),
|
|
173
226
|
length = count - 1,
|
|
@@ -182,11 +235,11 @@ export default {
|
|
|
182
235
|
top: (index / column >> 0) * height,
|
|
183
236
|
left: (index % column) * (width + margin),
|
|
184
237
|
index: index / column >> 0
|
|
185
|
-
})
|
|
238
|
+
})
|
|
186
239
|
}
|
|
187
240
|
this.flyweights.length = length + 1;
|
|
188
241
|
|
|
189
|
-
this.scroll(
|
|
242
|
+
this.scroll()
|
|
190
243
|
});
|
|
191
244
|
}
|
|
192
245
|
}
|