@soei/flyweight 0.0.1

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 ADDED
@@ -0,0 +1,33 @@
1
+ ## 享元模式
2
+
3
+ ### 安装
4
+
5
+ ```
6
+ npm i @soei/flyweight
7
+
8
+ ```
9
+
10
+ ### 引用
11
+
12
+ ```javascript
13
+ // 引入方式 vue2
14
+ import Flyweight from "@soei/flyweight/src/Flyweight.vue";
15
+ // 引入方式 vue3
16
+ import { Flyweight } from "@soei/flyweight";
17
+ ```
18
+
19
+ ### 使用
20
+
21
+ ```html
22
+ <Flyweight
23
+ :index="0"
24
+ :view="{id: Number, picker: 'id'}"
25
+ :flys="list|Array"
26
+ :width="80"
27
+ :height="130"
28
+ :offset="[0, 30]"
29
+ @onend="Function"
30
+ >
31
+ <template #default="{data, index}"> ...todo </template>
32
+ </Flyweight>
33
+ ```
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("@soei/util"),s=require("vue");const p=(t,e)=>{const h=t.__vccOpts||t;for(const[r,i]of e)h[r]=i;return h};let m=(...t)=>{console.info("::::FLYWEIGHT",...t)};const _={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:()=>({picker:"id"})},index:{type:Number,default:0}},computed:{flyweight(){return this.$refs.flyweight}},data(){return{flyweights:[],actice:!1,H:null,column:1,row:1,fwheight:10,count:0}},watch:{flys(t){this.count=t.length,this.re()},view(t){let e=a.each(this.flys,(h,r,i,n)=>{if(r[i]==n)return h},t.picker,t.id);this.$emit("update:index",e)},index(t){let e=t/this.column>>0;(this.flyweight.scrollTop/this.fwheight>>0)+this.row-e-1>0||(this.flyweight.scrollTop=e*this.fwheight)}},mounted(){this.flyweights=[];try{new ResizeObserver(()=>{this.re(),this.$emit("resize")}).observe(this.flyweight)}catch(t){m(t)}},methods:{lazyrun(t,e){clearTimeout(this.time),this.time=setTimeout(()=>{a.runer(t)},e||this.lazy)},run(t){let e=a.picker(t.target,"scrollTop=>top");a.each(this.flyweights,(h,r,i,n,l,o,c,u)=>{if(i=h/l>>0,c=i+n*(+(i<o%n)+(o/n>>0)),u=c*l+h%l,u>=this.count)return!0;r.index=c,r.top=r.index*this.fwheight,r.data=this.flys[u]},null,this.row,this.column,e.top/this.fwheight>>0)&&this.lazyrun(()=>this.$emit("onend",!0))},scroll(t){this.run(t)},re(){let t=this.flyweight,e=a.picker(t,"clientHeight=>height,clientWidth=>width");this.$nextTick(()=>{let[h,r]=this.offset,i=this.width;i==0&&(i=e.width);let n=i+h,l=this.height+r,o=e.width/n>>0,c=e.height/l>>0;this.row=c+2,this.column=o,this.fwheight=l,this.H=this.count/o*l;let u=e.width%n/(o-1)>>0,y=Math.min(this.count,o*this.row),d=y-1,f,g;for(;y-- >0;)f=d-y,g=this.flys[f],t=this.flyweights[f],this.$set(this.flyweights,f,{data:g,top:(f/o>>0)*l,left:f%o*(n+u),index:f/o>>0});this.flyweights.length=d+1,this.scroll({target:this.flyweight})})}}};function x(t,e,h,r,i,n){return s.openBlock(),s.createElementBlock("div",{ref:"flyweight",class:s.normalizeClass(["flyweight",{"flyweight-active":i.actice}]),style:s.normalizeStyle({"--width":h.width?h.width+"px":"100%","--height":h.height+"px"}),onScroll:e[0]||(e[0]=(...l)=>n.scroll&&n.scroll(...l))},[s.createElementVNode("div",{class:"flyweight-all",style:s.normalizeStyle({"--flyweight-height":i.H+30+"px"})},[(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList(i.flyweights,(l,o)=>(s.openBlock(),s.createElementBlock("div",{key:o,style:s.normalizeStyle({top:l.top+"px",left:l.left+"px"})},[s.renderSlot(t.$slots,"default",{data:l.data,index:l.index},void 0,!0)],4))),128))],4)],38)}const w=p(_,[["render",x],["__scopeId","data-v-77fef7f4"]]),v=[w],k={install(t){v.forEach(e=>{t.component("s-"+e.__name.toLowerCase(),e)})}};exports.Flyweight=w;exports.default=k;
@@ -0,0 +1,174 @@
1
+ import { each as p, runer as _, picker as m } from "@soei/util";
2
+ import { openBlock as a, createElementBlock as d, normalizeClass as x, normalizeStyle as y, createElementVNode as v, Fragment as z, renderList as b, renderSlot as k } from "vue";
3
+ const T = (t, e) => {
4
+ const l = t.__vccOpts || t;
5
+ for (const [s, i] of e)
6
+ l[s] = i;
7
+ return l;
8
+ };
9
+ let H = (...t) => {
10
+ console.info("::::FLYWEIGHT", ...t);
11
+ };
12
+ const N = {
13
+ props: {
14
+ flys: {
15
+ type: Array,
16
+ default: () => []
17
+ },
18
+ width: {
19
+ type: Number,
20
+ default: 0
21
+ },
22
+ height: {
23
+ type: Number,
24
+ default: 100
25
+ },
26
+ offset: {
27
+ type: Array,
28
+ default: () => [0, 0]
29
+ },
30
+ lazy: {
31
+ type: Number,
32
+ default: 100
33
+ },
34
+ view: {
35
+ type: Object,
36
+ default: () => ({ picker: "id" })
37
+ },
38
+ index: {
39
+ type: Number,
40
+ default: 0
41
+ }
42
+ },
43
+ computed: {
44
+ flyweight() {
45
+ return this.$refs.flyweight;
46
+ }
47
+ },
48
+ data() {
49
+ return {
50
+ flyweights: [],
51
+ actice: !1,
52
+ H: null,
53
+ column: 1,
54
+ row: 1,
55
+ fwheight: 10,
56
+ count: 0
57
+ };
58
+ },
59
+ watch: {
60
+ flys(t) {
61
+ this.count = t.length, this.re();
62
+ },
63
+ view(t) {
64
+ let e = p(this.flys, (l, s, i, r) => {
65
+ if (s[i] == r)
66
+ return l;
67
+ }, t.picker, t.id);
68
+ this.$emit("update:index", e);
69
+ },
70
+ index(t) {
71
+ let e = t / this.column >> 0;
72
+ (this.flyweight.scrollTop / this.fwheight >> 0) + this.row - e - 1 > 0 || (this.flyweight.scrollTop = e * this.fwheight);
73
+ }
74
+ },
75
+ mounted() {
76
+ this.flyweights = [];
77
+ try {
78
+ new ResizeObserver(() => {
79
+ this.re(), this.$emit("resize");
80
+ }).observe(this.flyweight);
81
+ } catch (t) {
82
+ H(t);
83
+ }
84
+ },
85
+ methods: {
86
+ lazyrun(t, e) {
87
+ clearTimeout(this.time), this.time = setTimeout(() => {
88
+ _(t);
89
+ }, e || this.lazy);
90
+ },
91
+ run(t) {
92
+ let e = m(t.target, "scrollTop=>top");
93
+ p(
94
+ this.flyweights,
95
+ (l, s, i, r, h, n, f, c) => {
96
+ if (i = l / h >> 0, f = i + r * /* 偏移量, 如果超出顶部 + 1轮,排列到列队后, 否则保持在当前*/
97
+ (+(i < n % r) + (n / r >> 0)), c = f * h + l % h, c >= this.count)
98
+ return !0;
99
+ s.index = f, s.top = s.index * this.fwheight, s.data = this.flys[c];
100
+ },
101
+ null,
102
+ this.row,
103
+ this.column,
104
+ /* 显示区域第一行的索引 */
105
+ e.top / this.fwheight >> 0
106
+ ) && this.lazyrun(() => this.$emit("onend", !0));
107
+ },
108
+ scroll(t) {
109
+ this.run(t);
110
+ },
111
+ re() {
112
+ let t = this.flyweight, e = m(t, "clientHeight=>height,clientWidth=>width");
113
+ this.$nextTick(() => {
114
+ let [l, s] = this.offset, i = this.width;
115
+ i == 0 && (i = e.width);
116
+ let r = i + l, h = this.height + s, n = e.width / r >> 0, f = e.height / h >> 0;
117
+ this.row = f + 2, this.column = n, this.fwheight = h, this.H = this.count / n * h;
118
+ let c = e.width % r / (n - 1) >> 0, u = Math.min(this.count, n * this.row), w = u - 1, o, g;
119
+ for (; u-- > 0; )
120
+ o = w - u, g = this.flys[o], t = this.flyweights[o], this.$set(this.flyweights, o, {
121
+ data: g,
122
+ top: (o / n >> 0) * h,
123
+ left: o % n * (r + c),
124
+ index: o / n >> 0
125
+ });
126
+ this.flyweights.length = w + 1, this.scroll({ target: this.flyweight });
127
+ });
128
+ }
129
+ }
130
+ };
131
+ function O(t, e, l, s, i, r) {
132
+ return a(), d("div", {
133
+ ref: "flyweight",
134
+ class: x(["flyweight", {
135
+ "flyweight-active": i.actice
136
+ }]),
137
+ style: y({
138
+ "--width": l.width ? l.width + "px" : "100%",
139
+ "--height": l.height + "px"
140
+ }),
141
+ onScroll: e[0] || (e[0] = (...h) => r.scroll && r.scroll(...h))
142
+ }, [
143
+ v("div", {
144
+ class: "flyweight-all",
145
+ style: y({
146
+ "--flyweight-height": i.H + 30 + "px"
147
+ })
148
+ }, [
149
+ (a(!0), d(z, null, b(i.flyweights, (h, n) => (a(), d("div", {
150
+ key: n,
151
+ style: y({
152
+ top: h.top + "px",
153
+ left: h.left + "px"
154
+ })
155
+ }, [
156
+ k(t.$slots, "default", {
157
+ data: h.data,
158
+ index: h.index
159
+ }, void 0, !0)
160
+ ], 4))), 128))
161
+ ], 4)
162
+ ], 38);
163
+ }
164
+ const E = /* @__PURE__ */ T(N, [["render", O], ["__scopeId", "data-v-77fef7f4"]]), F = [E], S = {
165
+ install(t) {
166
+ F.forEach((e) => {
167
+ t.component("s-" + e.__name.toLowerCase(), e);
168
+ });
169
+ }
170
+ };
171
+ export {
172
+ E as Flyweight,
173
+ S as default
174
+ };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .flyweight[data-v-77fef7f4]{height:100%;width:100%;overflow:auto;position:relative}.flyweight .flyweight-all[data-v-77fef7f4]{height:var(--flyweight-height)}.flyweight .flyweight-all[data-v-77fef7f4]>*{width:var(--width);height:var(--height);position:absolute}
package/dist/vite.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@soei/flyweight",
3
+ "private": false,
4
+ "version": "0.0.1",
5
+ "type": "module",
6
+ "main": "dist/Flyweight.cjs",
7
+ "module": "dist/Flyweight.js",
8
+ "files": [
9
+ "dist",
10
+ "src/Flyweight.vue"
11
+ ],
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "vite build",
15
+ "preview": "vite preview"
16
+ },
17
+ "dependencies": {
18
+ "@soei/util": "^1.1.1",
19
+ "vue": "^3.3.4"
20
+ },
21
+ "devDependencies": {
22
+ "@vitejs/plugin-vue": "^4.2.3",
23
+ "sass": "^1.69.5",
24
+ "scss": "^0.2.4",
25
+ "vite": "^4.4.5"
26
+ }
27
+ }
@@ -0,0 +1,213 @@
1
+ <template>
2
+ <div ref="flyweight" class="flyweight" :class="{
3
+ 'flyweight-active': actice
4
+ }" :style="{
5
+ '--width': width ? width + 'px' : '100%',
6
+ '--height': height + 'px'
7
+ }" @scroll="scroll">
8
+ <div class="flyweight-all" :style="{
9
+ '--flyweight-height': (H + 30) + 'px'
10
+ }">
11
+ <div v-for="(item, index) in flyweights" :key="index" :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
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ import { each, picker, runer } from '@soei/util';
23
+
24
+ let Log = (...args) => {
25
+ console.info('::::FLYWEIGHT', ...args);
26
+ }
27
+
28
+ export default {
29
+ props: {
30
+ flys: {
31
+ type: Array,
32
+ default: () => []
33
+ },
34
+ width: {
35
+ type: Number,
36
+ default: 0
37
+ },
38
+ height: {
39
+ type: Number,
40
+ default: 100
41
+ },
42
+ offset: {
43
+ type: Array,
44
+ default: () => [0, 0]
45
+ },
46
+ lazy: {
47
+ type: Number,
48
+ default: 100
49
+ },
50
+ view: {
51
+ type: Object,
52
+ default: () => ({ picker: 'id' })
53
+ },
54
+ index: {
55
+ type: Number,
56
+ default: 0
57
+ }
58
+ },
59
+ computed: {
60
+ flyweight() {
61
+ return this.$refs.flyweight;
62
+ }
63
+ },
64
+ data() {
65
+ return {
66
+ flyweights: [],
67
+ actice: false,
68
+ H: null,
69
+ column: 1,
70
+ row: 1,
71
+ fwheight: 10,
72
+
73
+ count: 0
74
+ }
75
+ },
76
+ watch: {
77
+ flys(data) {
78
+ this.count = data.length;
79
+ this.re();
80
+ },
81
+ view(data) {
82
+ // Log('---------------')
83
+ let index = each(this.flys, (k, v, attr, value) => {
84
+ if(v[attr] == value) return k;
85
+ }, data.picker, data.id);
86
+ // runer('dispatchEvent', window, new Event('resize', { view: this.flyweight, bubbles: true, cancelable: true }));
87
+ this.$emit('update:index', index);
88
+ },
89
+ index(index) {
90
+ let line = index / this.column >> 0;
91
+ let first = this.flyweight.scrollTop / this.fwheight >> 0;
92
+ let offset = first + this.row - line - 1
93
+ // Log(data, first, line, offset);
94
+ if (offset > 0 ) return;
95
+ this.flyweight.scrollTop = line * this.fwheight;
96
+ }
97
+ },
98
+ mounted() {
99
+ this.flyweights = [];
100
+ try {
101
+ const resizeObserver = new ResizeObserver(() => {
102
+ this.re();
103
+ this.$emit('resize');
104
+ // runer('dispatchEvent', window, new Event('resize', { view: window, bubbles: true, cancelable: true }));
105
+ });
106
+ resizeObserver.observe(this.flyweight);
107
+ } catch (error) {
108
+ Log(error);
109
+ }
110
+ },
111
+ methods: {
112
+ lazyrun(back, time) {
113
+ clearTimeout(this.time);
114
+ this.time = setTimeout(() => {
115
+ runer(back);
116
+ }, time || this.lazy);
117
+ },
118
+ run(e) {
119
+ let position = picker(e.target, 'scrollTop=>top');
120
+ if (each(this.flyweights, (k, v, offset, row, column, first, index, i) => {
121
+ offset = k / column >> 0;
122
+ index = offset + row * (
123
+ /* 偏移量, 如果超出顶部 + 1轮,排列到列队后, 否则保持在当前*/
124
+ +(offset < first % row)
125
+ /* 计算轮数, row的倍数 */
126
+ + (first / row >> 0)
127
+ );
128
+ i = index * column + k % column;
129
+
130
+ // Log(k, i, index);
131
+ if (i >= this.count) {
132
+ return true;
133
+ }
134
+ v.index = index;
135
+ v.top = v.index * this.fwheight;
136
+ v.data = this.flys[i];
137
+ },
138
+ null,
139
+ this.row,
140
+ this.column,
141
+ /* 显示区域第一行的索引 */
142
+ position.top / this.fwheight >> 0
143
+ )) {
144
+ this.lazyrun(() => this.$emit('onend', true))
145
+ }
146
+ },
147
+ scroll(e) {
148
+ this.run(e);
149
+ },
150
+ re() {
151
+ let flyweight = this.flyweight;
152
+ let wh = picker(flyweight, 'clientHeight=>height,clientWidth=>width');
153
+ // Log(wh, wh.width / this.width, wh.height / this.height);
154
+ this.$nextTick(() => {
155
+ let [x, y] = this.offset,
156
+ W = this.width;
157
+ if (W == 0) {
158
+ W = wh.width;
159
+ }
160
+ let width = W + x;
161
+ let height = this.height + y;
162
+ let column = wh.width / width >> 0,
163
+ row = wh.height / height >> 0;
164
+ this.row = row + 2/* 上下各一行补位 */;
165
+ this.column = column;
166
+ this.fwheight = height;
167
+ /* 总高度 */
168
+ this.H = (this.count / column) * height;
169
+ /* 偏移量 */
170
+ let margin = (wh.width % width) / (column - 1) >> 0;
171
+ /* 计算数量 */
172
+ let count = Math.min(this.count, column * this.row),
173
+ length = count - 1,
174
+ index,
175
+ fly;
176
+ while (count-- > 0) {
177
+ index = length - count;
178
+ fly = this.flys[index];
179
+ flyweight = this.flyweights[index];
180
+ this.$set(this.flyweights, index, {
181
+ data: fly,
182
+ top: (index / column >> 0) * height,
183
+ left: (index % column) * (width + margin),
184
+ index: index / column >> 0
185
+ });
186
+ }
187
+ this.flyweights.length = length + 1;
188
+
189
+ this.scroll({ target: this.flyweight })
190
+ });
191
+ }
192
+ }
193
+ }
194
+ </script>
195
+
196
+ <style lang="scss" scoped>
197
+ .flyweight {
198
+ height: 100%;
199
+ width: 100%;
200
+ overflow: auto;
201
+ position: relative;
202
+
203
+ .flyweight-all {
204
+ height: var(--flyweight-height);
205
+
206
+ &>* {
207
+ width: var(--width);
208
+ height: var(--height);
209
+ position: absolute;
210
+ }
211
+ }
212
+ }
213
+ </style>