0%

sku-filter

NPM

演示

点击查看演示

使用场景:

商品详情页一般有 Product => SKUS<Array> => types<Array>1对n对n的关系

初始化把已有的SKUs渲染出来的时候, 需要遍历嵌套的数据

每次点击直接对原始数据进行过滤操作,也需要遍历嵌套的数据

这些会造成很多不必要的遍历操作

实际上我们后续只会对types<Array>的数据进行交互,

选择的条件满足一个SKU的时候根据对应关系把这个SKU找到即可

所以我们在初始化遍历原始数据的时候建立对应关系,后续只操作types, 当选择条件已满,返回符合条件的那个唯一SKU

SKU
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"id": 106,
"name": null,
"description": null,
"price": {
"level1": "10",
"level2": "5"
},
"type": {
"颜色": "红",
"大小": "S",
"性别": "男"
},
"image": "default_point_shop_product_sku.jpg",
"stock": "99999995",
"point_shop_product_id": "3"
}
Map about Product => SKUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
{
"code": 1,
"data": {
"id": 3,
"min_price": {
"level1": "10",
"level2": "5"
},
"name": "aa",
"description": "bb",
"image": "1ac9d492.png",
"created_at": "2018-08-10 13:31:25",
"updated_at": "2018-10-12 17:01:33",
"deleted_at": null,
"category_id": "1",
"sliders": [
"d6a4a433.png",
"c37daee5.jpg"
],
"vip_level_slug": "level1",
"max_price": {
"level1": "10",
"level2": "5"
},
"type": [
"颜色",
"大小",
"性别"
],
"is_virtual": true,
"used_num": "110",
"details": "<p>cc</p>",
"limit_num": "0",
"partner_shop_id": "58",
"is_recommend": true,
"category_sort": "0",
"all_sort": "0",
"recommend_sort": "0",
"is_online": true,
"is_collected": true,
"all_stock": 129999951,
"skus": [
{
"id": 106,
"name": null,
"description": null,
"price": {
"level1": "10",
"level2": "5"
},
"type": {
"颜色": "红",
"大小": "S",
"性别": "男"
},
"image": "default_point_shop_product_sku.jpg",
"stock": "99999995",
"point_shop_product_id": "3"
},
{
"id": 107,
"name": null,
"description": null,
"price": {
"level1": "10",
"level2": "5"
},
"type": {
"颜色": "红",
"大小": "XL",
"性别": "男"
},
"image": "default_point_shop_product_sku.jpg",
"stock": "9999991",
"point_shop_product_id": "3"
},
{
"id": 108,
"name": null,
"description": null,
"price": {
"level1": "10",
"level2": "5"
},
"type": {
"颜色": "绿",
"大小": "XL",
"性别": "女"
},
"image": "default_point_shop_product_sku.jpg",
"stock": "9999966",
"point_shop_product_id": "3"
},
{
"id": 109,
"name": null,
"description": null,
"price": {
"level1": "10",
"level2": "5"
},
"type": {
"颜色": "红",
"大小": "SL",
"性别": "女"
},
"image": "default_point_shop_product_sku.jpg",
"stock": "9999999",
"point_shop_product_id": "3"
}
],
"partner_shop": {
"id": 58,
"name": "测试品牌1",
"created_at": "2018-08-09 10:48:23",
"updated_at": "2018-08-09 10:48:23",
"support_phone": null,
"support_web_link": null,
"url_to_some_news": null,
"checkbox_text_en": null,
"checkbox_text_cn": null,
"lunch_website_button_text": null,
"support_details": null,
"logo_image": "9b2b75f6.png",
"description": "测试品牌1简介",
"detail": "测试品牌1详情",
"discount": [ ]
}
}
}
如何使用
安装 npm install --save sku-filter
引入 import SKUFilter from "sku-filter"
  1. 实例化

    1
    const skus = new SKUFilter({data: skus<Array>});
  2. 初始化数据

    1
    const init = skus.initial();
  3. 过滤数据 输入已选条件(sku.types)

    1
    const result = skus.filter(conditions<Array>); // [{颜色: '红'}]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@param {Array} let skus = new SKUFilter({data: skus}); 必填

@param {Funtion} initial() => {
skus: skus<Array>, // 所有的sku [{颜色: "红", 大小: "S", 性别: "男"}]
sku_types: sku_types<Array>, // 所有的sku类型key ["颜色", "大小", "性别"]
convenient_render<Map> // 方便渲染的格式 {"颜色" => [红, 黑], "大小" => [L, XL], "性别" => [男, 女]}
}

@param {Function} filter(conditions: Array) => {
selected_types<Array>, // 已选类型 ["颜色", "大小", "性别"]

selected_detail<String>, // 已选的具体参数 每次点击的时候显示已选的参数 "颜色: 红 "

match_skus<Array>, // 符合条件的SKU[{颜色: "红", 大小: "XL", 性别: "男"}]

mismatch_skus<Array>, // 不符合条件的SKU[{颜色: "红", 大小: "XL", 性别: "男"}]

render_list<Array>, // 比如 [{颜色: "红"}, {大小: "XL"}...]视图更新方便

final_sku<Object>, // 符合全部已选条件的sku {颜色: "红", 大小: "XL", 性别: "男"} || null

target<Object>, // 加入购物车或者立即购买需要提交的完整的SKU
/* {
description: null,
id: 107,
image: "default_point_shop_product_sku.jpg",
name: null,
point_shop_product_id: "3",
price: {level1: "10", level2: "5"},
stock: "9999991",
type: {颜色: "红", 大小: "XL", 性别: "男"}
}
*/
}


@example

1. 初始化SKU

const skus = new SKUFilter({data: skus<Array>})

2. 可选三种方法

1) const init = skus.initial();

2) const result = skus.filter(conditions<Array>) // [{颜色: '红'}]

1
2
3
4
5
6
7
8
9
10
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums: number[]) {
return [...nums.reduce((prev, v)=>{
prev.has(v) ? prev.delete(v) : prev.add(v);
return prev
}, new Set())][0];
};

shuffle-animate

NPM

案例

案例

演示

点击查看演示

使用方法

  1. 安装 npm install shuffle-animate --save;

  2. 引入 import ShuffleAnimate from 'shuffle-animate';

  3. 实例化

    1. 配置DOM

      1
      2
      3
      4
      5
      6
      <div id='container'> // position: relative || absolute || fixed || sticky ......
      <span data-i='1'>1</span> // data-i = 'string' 配置索引
      <span data-i='2'>2</span>
      <span data-i='3'>3</span>
      ...
      </div>
    2. 获取容器 const box = document.getElementById('container');

    3. 创建对象 const sa = new ShuffleAnimate({data: [...box.childrens]});

  4. 渲染

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sa.update({
    target: <Number> || <Array>, // '1' || 1 目标值的索引
    shuffle: <Boolean>, // true || false 是否随机排序, 否的话按正序排列
    ease: <String>, // 'easeInOutCirc' 速度曲线, 可选见下文, 也可以自己定制化贝塞尔曲线
    time: <String>, // `2000ms` `2s` 过渡时间
    center: <Boolean>, // true || false 用此参数则target必填, 表示target块会先过渡到容器的中点(过渡到中点的时间=time), 然后再过渡到目标位置
    });

    以上参数都不是必填项 sa.update() 执行默认随机效果

可选动画曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
easeInSine: `cubic-bezier(0.47, 0, 0.745, 0.715)`,
easeOutSine: `cubic-bezier(0.39, 0.575, 0.565, 1)`,
easeInOutSine: `cubic-bezier(0.445, 0.05, 0.55, 0.95)`,

easeInQuad: `cubic-bezier(0.55, 0.085, 0.68, 0.53)`,
easeOutQuad: `cubic-bezier(0.25, 0.46, 0.45, 0.94)`,
easeInOutQuad: `cubic-bezier(0.455, 0.03, 0.515, 0.955)`,

easeInCubic: `cubic-bezier(0.55, 0.055, 0.675, 0.19)`,
easeOutCubic: `cubic-bezier(0.215, 0.61, 0.355, 1)`,
easeInOutCubic: `cubic-bezier(0.645, 0.045, 0.355, 1)`,

easeInQuart: `cubic-bezier(0.895, 0.03, 0.685, 0.22)`,
easeOutQuart: `cubic-bezier(0.165, 0.84, 0.44, 1)`,
easeInOutQuart: `cubic-bezier(0.77, 0, 0.175, 1)`,

easeInQuint: `cubic-bezier(0.755, 0.05, 0.855, 0.06)`,
easeOutQuint: `cubic-bezier(0.23, 1, 0.32, 1)`,
easeInOutQuint: `cubic-bezier(0.86, 0, 0.07, 1)`,

easeInExpo: `cubic-bezier(0.95, 0.05, 0.795, 0.035)`,
easeOutExpo: `cubic-bezier(0.19, 1, 0.22, 1)`,
easeInOutExpo: `cubic-bezier(1, 0, 0, 1)`,

easeInCirc: `cubic-bezier(0.6, 0.04, 0.98, 0.335)`,
easeOutCirc: `cubic-bezier(0.075, 0.82, 0.165, 1)`,
easeInOutCirc: `cubic-bezier(0.785, 0.135, 0.15, 0.86)`,

easeInBack: `cubic-bezier(0.6, -0.28, 0.735, 0.045`,
easeOutBack: `cubic-bezier(0.175, 0.885, 0.32, 1.275)`,
easeInOutBack: `cubic-bezier(0.68, -0.55, 0.265, 1.55)`

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(() => {
const vertical = document.querySelector('#vertical');
const verticals = new ShuffleAnimate({
data: [...vertical.children]
});
vertical.addEventListener('click', (e) => {
[...vertical.children].map(x => {
x.style.color = `black`
})
e.target.style.color = `red`;
verticals.update({
target: e.target.dataset.i,
shuffle: false
});
})
})();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix: [][], target: number) {
let row = matrix.length;
if(row === 0) return false
let col = matrix.slice(-1)[0].length;
if(col === 0) return false

let i = 0;
let r = row - 1;
while(r >= 0 && i < col) {
if(matrix[r][i] === target) return true
if(matrix[r][i] < target) {
i++
}else {
r--
}
}
return false
};

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums: number[], k: number) {
// for(let i = 0; i < k; i++) {
// nums.unshift(nums.pop())
// }
if (k < 1) return nums;
nums.splice(0, 0, ...nums.splice(nums.length - k, k));
};