@gmcb/uv-ui 0.2.26 → 0.3.0
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/CHANGELOG.md +8 -0
- package/LICENSE +21 -21
- package/README.md +95 -141
- package/components/uv-overlay/props.js +29 -24
- package/components/uv-overlay/uv-overlay.vue +87 -85
- package/docs/api/configs/color.md +52 -0
- package/docs/api/index.md +77 -0
- package/docs/api/mixins/mpShare.md +95 -0
- package/docs/api/request/apiManage.md +88 -0
- package/docs/api/request/http.md +451 -0
- package/docs/api/utils/colorSwitch.md +78 -0
- package/docs/api/utils/debounce.md +104 -0
- package/docs/api/utils/fastUse.md +246 -0
- package/docs/api/utils/getRect.md +238 -0
- package/docs/api/utils/guid.md +41 -0
- package/docs/api/utils/index.md +55 -0
- package/docs/api/utils/intro.md +25 -0
- package/docs/api/utils/object.md +171 -0
- package/docs/api/utils/queryParams.md +68 -0
- package/docs/api/utils/random.md +23 -0
- package/docs/api/utils/randomArray.md +28 -0
- package/docs/api/utils/route.md +121 -0
- package/docs/api/utils/test.md +237 -0
- package/docs/api/utils/time.md +81 -0
- package/docs/api/utils/trim.md +24 -0
- package/docs/components/actionSheet.md +236 -0
- package/docs/components/addQQGroup.md +5 -0
- package/docs/components/album.md +91 -0
- package/docs/components/alert.md +83 -0
- package/docs/components/avatar.md +152 -0
- package/docs/components/backTop.md +181 -0
- package/docs/components/badge.md +117 -0
- package/docs/components/button.md +196 -0
- package/docs/components/calendar.md +398 -0
- package/docs/components/calendars.md +294 -0
- package/docs/components/cell.md +185 -0
- package/docs/components/checkbox.md +281 -0
- package/docs/components/circleProgress.md +5 -0
- package/docs/components/code.md +162 -0
- package/docs/components/codeInput.md +175 -0
- package/docs/components/collapse.md +250 -0
- package/docs/components/color.md +324 -0
- package/docs/components/common.md +126 -0
- package/docs/components/countDown.md +166 -0
- package/docs/components/countTo.md +140 -0
- package/docs/components/datetimePicker.md +283 -0
- package/docs/components/diff1.x.md +190 -0
- package/docs/components/divider.md +88 -0
- package/docs/components/downloadSetting.md +54 -0
- package/docs/components/dropDown.md +375 -0
- package/docs/components/empty.md +99 -0
- package/docs/components/feature.md +261 -0
- package/docs/components/form.md +736 -0
- package/docs/components/gap.md +49 -0
- package/docs/components/grid.md +225 -0
- package/docs/components/icon.md +101 -0
- package/docs/components/image.md +182 -0
- package/docs/components/index.md +110 -0
- package/docs/components/indexList.md +133 -0
- package/docs/components/input.md +250 -0
- package/docs/components/install.md +59 -0
- package/docs/components/intro.md +32 -0
- package/docs/components/keyboard.md +226 -0
- package/docs/components/layout.md +310 -0
- package/docs/components/line.md +85 -0
- package/docs/components/lineProgress.md +141 -0
- package/docs/components/link.md +89 -0
- package/docs/components/list.md +223 -0
- package/docs/components/loadMore.md +140 -0
- package/docs/components/loadingIcon.md +144 -0
- package/docs/components/loadingPage.md +92 -0
- package/docs/components/modal.md +230 -0
- package/docs/components/more.md +13 -0
- package/docs/components/navbar.md +192 -0
- package/docs/components/noNetwork.md +116 -0
- package/docs/components/noticeBar.md +131 -0
- package/docs/components/notify.md +204 -0
- package/docs/components/npmSetting.md +64 -0
- package/docs/components/numberBox.md +257 -0
- package/docs/components/nvue.md +170 -0
- package/docs/components/overlay.md +117 -0
- package/docs/components/parse.md +204 -0
- package/docs/components/pickColor.md +112 -0
- package/docs/components/picker.md +357 -0
- package/docs/components/popup.md +221 -0
- package/docs/components/problem.md +300 -0
- package/docs/components/qrcode.md +169 -0
- package/docs/components/quickstart.md +33 -0
- package/docs/components/radio.md +256 -0
- package/docs/components/rate.md +128 -0
- package/docs/components/read.md +163 -0
- package/docs/components/readMore.md +227 -0
- package/docs/components/resource.md +17 -0
- package/docs/components/scrollList.md +218 -0
- package/docs/components/search.md +160 -0
- package/docs/components/setting.md +111 -0
- package/docs/components/settingDesc.md +66 -0
- package/docs/components/skeleton.md +105 -0
- package/docs/components/skeletons.md +323 -0
- package/docs/components/slider.md +157 -0
- package/docs/components/steps.md +189 -0
- package/docs/components/sticky.md +76 -0
- package/docs/components/subsection.md +183 -0
- package/docs/components/swipeAction.md +279 -0
- package/docs/components/swiper.md +352 -0
- package/docs/components/switch.md +216 -0
- package/docs/components/tabbar.md +263 -0
- package/docs/components/table.md +5 -0
- package/docs/components/tabs.md +364 -0
- package/docs/components/tag.md +227 -0
- package/docs/components/testPic.md +20 -0
- package/docs/components/text.md +157 -0
- package/docs/components/textarea.md +121 -0
- package/docs/components/toast.md +124 -0
- package/docs/components/tooltip.md +98 -0
- package/docs/components/transition.md +404 -0
- package/docs/components/upload.md +253 -0
- package/docs/components/vtabs.md +332 -0
- package/docs/components/vueUse.md +45 -0
- package/docs/components/vuexDetail.md +103 -0
- package/docs/components/waterfall.md +651 -0
- package/docs/faq/index.md +53 -0
- package/docs/guide/codeHint.md +44 -0
- package/docs/guide/customIcon.md +168 -0
- package/docs/guide/demo.md +92 -0
- package/docs/guide/design.md +56 -0
- package/docs/guide/globalVariable.md +239 -0
- package/docs/guide/i18n.md +194 -0
- package/docs/guide/index.md +28 -0
- package/docs/guide/note.md +74 -0
- package/docs/guide/safeAreaInset.md +64 -0
- package/docs/guide/theme.md +67 -0
- package/docs/index.md +88 -0
- package/libs/config/config.js +0 -10
- package/libs/css/color.scss +15 -14
- package/package.json +7 -2
- package/theme.scss +2 -1
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
## Waterfall 瀑布流 <to-api/>
|
|
2
|
+
|
|
3
|
+
<demo-model url="/pages/componentsC/waterfall/waterfall"></demo-model>
|
|
4
|
+
|
|
5
|
+
::: tip ✈
|
|
6
|
+
|
|
7
|
+
**组件名:uv-waterfall**
|
|
8
|
+
|
|
9
|
+
[点击下载&安装](https://ext.dcloud.net.cn/plugin?name=uv-waterfall)
|
|
10
|
+
|
|
11
|
+
:::
|
|
12
|
+
|
|
13
|
+
该组件主要用于瀑布流式布局显示,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。常用于一些电商商品展示等,如某宝首页。
|
|
14
|
+
|
|
15
|
+
### 平台兼容性
|
|
16
|
+
|
|
17
|
+
|App(vue)|App(nvue)|H5|小程序|VUE2|VUE3|
|
|
18
|
+
|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
19
|
+
|√|√|√|√|√|√|
|
|
20
|
+
|
|
21
|
+
::: warning 注意
|
|
22
|
+
1. 瀑布流集成了`uni-app`官方提供的`nvue`组件[waterfall](https://uniapp.dcloud.net.cn/component/waterfall.html),在`nvue`中性能更佳,`nvue`和`vue`中使用有些区别,下面会在示例中说明。
|
|
23
|
+
2. 在`APP-NVUE`中,该组件中不能使用`uv-image`等组件,具体原因请查看:[android端list中为什么不能使用uv-image等组件](https://www.uvui.cn/components/problem.html#%E5%85%AD%E3%80%81android%E7%AB%AFlist%E4%B8%AD%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E8%83%BD%E4%BD%BF%E7%94%A8uv-image%E7%AD%89%E7%BB%84%E4%BB%B6)
|
|
24
|
+
:::
|
|
25
|
+
|
|
26
|
+
### 基本使用 (vue生效)
|
|
27
|
+
|
|
28
|
+
- **这是`vue`页面的使用法,`nvue`的写法在下面单独说明[nvue中使用](/components/waterfall.html#nvue中使用-nvue生效)。**
|
|
29
|
+
- 通过`column-count`设置瀑布流列数,默认2,范围1-5。
|
|
30
|
+
- 如果列数为2,则需要定义两个插槽值`<template v-slot:list1>...</template>`、`<template v-slot:list2">...</template>`
|
|
31
|
+
- 如果列数为3,则需要定义三个插槽值`<template v-slot:list1>...</template>`、`<template v-slot:list2">...</template>`、`<template v-slot:list3">...</template>`,更多列数以此类推。
|
|
32
|
+
|
|
33
|
+
```vue
|
|
34
|
+
<template>
|
|
35
|
+
<view class="waterfall">
|
|
36
|
+
<uv-waterfall ref="waterfall"
|
|
37
|
+
v-model="list"
|
|
38
|
+
:add-time="10"
|
|
39
|
+
:left-gap="leftGap"
|
|
40
|
+
:right-gap="rightGap"
|
|
41
|
+
:column-gap="columnGap"
|
|
42
|
+
@changeList="changeList">
|
|
43
|
+
<!-- 第一列数据 -->
|
|
44
|
+
<template v-slot:list1>
|
|
45
|
+
<!-- 为了磨平部分平台的BUG,必须套一层view -->
|
|
46
|
+
<view>
|
|
47
|
+
<view v-for="(item, index) in list1"
|
|
48
|
+
:key="item.id"
|
|
49
|
+
class="waterfall-item">
|
|
50
|
+
<view class="waterfall-item__image" :style="[imageStyle(item)]">
|
|
51
|
+
<image :src="item.image" mode="widthFix" :style="{width:item.width+'px'}"></image>
|
|
52
|
+
</view>
|
|
53
|
+
<view class="waterfall-item__ft">
|
|
54
|
+
<view class="waterfall-item__ft__title">
|
|
55
|
+
<text class="value">{{item.title}}</text>
|
|
56
|
+
</view>
|
|
57
|
+
<view class="waterfall-item__ft__desc uv-line-2">
|
|
58
|
+
<text class="value">{{item.desc}}</text>
|
|
59
|
+
</view>
|
|
60
|
+
</view>
|
|
61
|
+
</view>
|
|
62
|
+
</view>
|
|
63
|
+
</template>
|
|
64
|
+
<!-- 第二列数据 -->
|
|
65
|
+
<template v-slot:list2>
|
|
66
|
+
<!-- 为了磨平部分平台的BUG,必须套一层view -->
|
|
67
|
+
<view>
|
|
68
|
+
<view v-for="(item, index) in list2"
|
|
69
|
+
:key="item.id"
|
|
70
|
+
class="waterfall-item">
|
|
71
|
+
<view class="waterfall-item__image" :style="[imageStyle(item)]">
|
|
72
|
+
<image :src="item.image" mode="widthFix" :style="{width:item.width+'px'}"></image>
|
|
73
|
+
</view>
|
|
74
|
+
<view class="waterfall-item__ft">
|
|
75
|
+
<view class="waterfall-item__ft__title">
|
|
76
|
+
<text class="value">{{item.title}}</text>
|
|
77
|
+
</view>
|
|
78
|
+
<view class="waterfall-item__ft__desc uv-line-2">
|
|
79
|
+
<text class="value">{{item.desc}}</text>
|
|
80
|
+
</view>
|
|
81
|
+
</view>
|
|
82
|
+
</view>
|
|
83
|
+
</view>
|
|
84
|
+
</template>
|
|
85
|
+
</uv-waterfall>
|
|
86
|
+
</view>
|
|
87
|
+
</template>
|
|
88
|
+
<script setup>
|
|
89
|
+
import { guid } from '@gmcb/uv-ui/libs/function/index.js';
|
|
90
|
+
import { ref, computed } from "vue";
|
|
91
|
+
import { onLoad } from "@dcloudio/uni-app";
|
|
92
|
+
const list = ref([]);
|
|
93
|
+
const list1 = ref([]);
|
|
94
|
+
const list2 = ref([]);
|
|
95
|
+
const leftGap = ref(10);
|
|
96
|
+
const rightGap = ref(10);
|
|
97
|
+
const columnGap = ref(10);
|
|
98
|
+
const imageStyle = computed(item => {
|
|
99
|
+
return item => {
|
|
100
|
+
const v = uni.upx2px(750) - leftGap.value - rightGap.value - columnGap.value;
|
|
101
|
+
const w = v / 2;
|
|
102
|
+
const rate = w / item.w;
|
|
103
|
+
const h = rate * item.h;
|
|
104
|
+
return {
|
|
105
|
+
width: w + 'px',
|
|
106
|
+
height: h + 'px'
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
const waterfall = ref(null);
|
|
111
|
+
const columnMap = {
|
|
112
|
+
list1,
|
|
113
|
+
list2
|
|
114
|
+
};
|
|
115
|
+
function changeList(e) {
|
|
116
|
+
columnMap[e.name]?.value.push(e.value);
|
|
117
|
+
}
|
|
118
|
+
function getData() {
|
|
119
|
+
return new Promise(resolve => {
|
|
120
|
+
const imgs = [{
|
|
121
|
+
url: 'https://via.placeholder.com/100x110.png/3c9cff/fff',
|
|
122
|
+
width: 100,
|
|
123
|
+
height: 110
|
|
124
|
+
}, {
|
|
125
|
+
url: 'https://via.placeholder.com/200x220.png/f9ae3d/fff',
|
|
126
|
+
width: 200,
|
|
127
|
+
height: 220
|
|
128
|
+
}, {
|
|
129
|
+
url: 'https://via.placeholder.com/300x340.png/5ac725/fff',
|
|
130
|
+
width: 300,
|
|
131
|
+
height: 340
|
|
132
|
+
}, {
|
|
133
|
+
url: 'https://via.placeholder.com/400x400.png/f56c6c/fff',
|
|
134
|
+
width: 400,
|
|
135
|
+
height: 400
|
|
136
|
+
}, {
|
|
137
|
+
url: 'https://via.placeholder.com/500x510.png/909399/fff',
|
|
138
|
+
width: 500,
|
|
139
|
+
height: 510
|
|
140
|
+
}, {
|
|
141
|
+
url: 'https://via.placeholder.com/600x606.png/3c9cff/fff',
|
|
142
|
+
width: 600,
|
|
143
|
+
height: 606
|
|
144
|
+
}, {
|
|
145
|
+
url: 'https://via.placeholder.com/310x422.png/f1a532/fff',
|
|
146
|
+
width: 310,
|
|
147
|
+
height: 422
|
|
148
|
+
}, {
|
|
149
|
+
url: 'https://via.placeholder.com/320x430.png/3c9cff/fff',
|
|
150
|
+
width: 320,
|
|
151
|
+
height: 430
|
|
152
|
+
}, {
|
|
153
|
+
url: 'https://via.placeholder.com/330x424.png/f9ae3d/fff',
|
|
154
|
+
width: 330,
|
|
155
|
+
height: 424
|
|
156
|
+
}, {
|
|
157
|
+
url: 'https://via.placeholder.com/340x435.png/5ac725/fff',
|
|
158
|
+
width: 340,
|
|
159
|
+
height: 435
|
|
160
|
+
}, {
|
|
161
|
+
url: 'https://via.placeholder.com/350x440.png/f56c6c/fff',
|
|
162
|
+
width: 350,
|
|
163
|
+
height: 440
|
|
164
|
+
}, {
|
|
165
|
+
url: 'https://via.placeholder.com/380x470.png/909399/fff',
|
|
166
|
+
width: 380,
|
|
167
|
+
height: 470
|
|
168
|
+
}];
|
|
169
|
+
const dataList = [];
|
|
170
|
+
const doFn = i => {
|
|
171
|
+
const randomIndex = Math.floor(Math.random() * 10);
|
|
172
|
+
return {
|
|
173
|
+
id: guid(),
|
|
174
|
+
allowEdit: i == 0,
|
|
175
|
+
image: imgs[randomIndex].url,
|
|
176
|
+
w: imgs[randomIndex].width,
|
|
177
|
+
h: imgs[randomIndex].height,
|
|
178
|
+
title: i % 2 == 0 ? `(${list.value.length + i + 1})体验uv-ui框架` : `(${list.value.length + i + 1})uv-ui支持多平台`,
|
|
179
|
+
desc: i % 2 == 0 ? `(${list.value.length + i + 1})欢迎使用uv-ui,uni-app生态专用的UI框架` : `(${list.value.length + i})开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序`
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
// 模拟异步
|
|
183
|
+
setTimeout(() => {
|
|
184
|
+
for (let i = 0; i < 20; i++) {
|
|
185
|
+
dataList.push(doFn(i));
|
|
186
|
+
}
|
|
187
|
+
resolve({
|
|
188
|
+
data: dataList
|
|
189
|
+
});
|
|
190
|
+
}, 200);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
onLoad(async () => {
|
|
194
|
+
const {
|
|
195
|
+
data
|
|
196
|
+
} = await getData();
|
|
197
|
+
list.value = data;
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
</script>
|
|
201
|
+
<style>
|
|
202
|
+
page {
|
|
203
|
+
background: #f1f1f1;
|
|
204
|
+
}
|
|
205
|
+
</style>
|
|
206
|
+
<style scoped lang="scss">
|
|
207
|
+
$show-lines: 1;
|
|
208
|
+
@import '@gmcb/uv-ui/libs/css/variable.scss';
|
|
209
|
+
.waterfall-item {
|
|
210
|
+
overflow: hidden;
|
|
211
|
+
margin-top: 10px;
|
|
212
|
+
border-radius: 6px;
|
|
213
|
+
}
|
|
214
|
+
.waterfall-item__ft {
|
|
215
|
+
padding: 20rpx;
|
|
216
|
+
background: #fff;
|
|
217
|
+
&__title {
|
|
218
|
+
margin-bottom: 10rpx;
|
|
219
|
+
line-height: 48rpx;
|
|
220
|
+
font-weight: 700;
|
|
221
|
+
.value {
|
|
222
|
+
font-size: 32rpx;
|
|
223
|
+
color: #303133;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
&__desc .value {
|
|
227
|
+
font-size: 28rpx;
|
|
228
|
+
color: #606266;
|
|
229
|
+
}
|
|
230
|
+
&__btn {
|
|
231
|
+
padding: 10px 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
</style>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 删除某项数据 (vue生效)
|
|
238
|
+
|
|
239
|
+
- 该用法是在[基本使用](/components/waterfall.html#基本使用-vue生效)的代码基础上进行扩展
|
|
240
|
+
- 使用`ref`调用组件内置方法`remove(id)`,注意需要带上数据中`id`参数。执行之后,必须在`@remove`回调中处理列表数据,如下:
|
|
241
|
+
|
|
242
|
+
```vue
|
|
243
|
+
<template>
|
|
244
|
+
<view class="waterfall">
|
|
245
|
+
<uv-waterfall ref="waterfall" @remove="remove">...</uv-waterfall>
|
|
246
|
+
</view>
|
|
247
|
+
</template>
|
|
248
|
+
<script setup>
|
|
249
|
+
import { ref } from "vue";
|
|
250
|
+
const waterfall = ref(null);
|
|
251
|
+
const list1 = ref([]);
|
|
252
|
+
const list2 = ref([]);
|
|
253
|
+
function longHandle(item) {
|
|
254
|
+
uni.showModal({
|
|
255
|
+
title: '提示',
|
|
256
|
+
content: '你确定删除该项?',
|
|
257
|
+
success(res) {
|
|
258
|
+
if (res.confirm) {
|
|
259
|
+
waterfall.value?.remove(item.id);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function remove(id) {
|
|
265
|
+
list1.value.forEach((item, index) => {
|
|
266
|
+
if (item.id == id) {
|
|
267
|
+
list1.value.splice(index, 1);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
list2.value.forEach((item, index) => {
|
|
271
|
+
if (item.id == id) {
|
|
272
|
+
list2.value.splice(index, 1);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
</script>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 清除所有数据 (vue生效)
|
|
281
|
+
|
|
282
|
+
- 该用法是在[基本使用](/components/waterfall.html#基本使用-vue生效)的代码基础上进行扩展
|
|
283
|
+
- 使用`ref`调用组件内置方法`clear()`,该方法执行后触发`@clear`回调
|
|
284
|
+
- 使用场景:下拉刷新数据或tab切换时更改数据,需要先清空数据,再去赋值新的数据等场景。以下是以下拉刷新数据为例:
|
|
285
|
+
|
|
286
|
+
```vue
|
|
287
|
+
<template>
|
|
288
|
+
<view class="waterfall">
|
|
289
|
+
<uv-waterfall ref="waterfall" @clear="clear">...</uv-waterfall>
|
|
290
|
+
</view>
|
|
291
|
+
</template>
|
|
292
|
+
<script setup>
|
|
293
|
+
import { ref } from "vue";
|
|
294
|
+
import { onPullDownRefresh } from "@dcloudio/uni-app";
|
|
295
|
+
const waterfall = ref(null);
|
|
296
|
+
const list = ref([]);
|
|
297
|
+
const list1 = ref([]);
|
|
298
|
+
const list2 = ref([]);
|
|
299
|
+
function clear() {
|
|
300
|
+
console.log('执行了clear');
|
|
301
|
+
}
|
|
302
|
+
onPullDownRefresh(async () => {
|
|
303
|
+
list.value = [];
|
|
304
|
+
waterfall.value?.clear();
|
|
305
|
+
list1.value = [];
|
|
306
|
+
list2.value = [];
|
|
307
|
+
const {
|
|
308
|
+
data
|
|
309
|
+
} = await getData();
|
|
310
|
+
list.value = data;
|
|
311
|
+
uni.showToast({
|
|
312
|
+
icon: 'success',
|
|
313
|
+
title: '刷新成功'
|
|
314
|
+
});
|
|
315
|
+
uni.stopPullDownRefresh();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
</script>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 加载更多数据 (vue生效)
|
|
322
|
+
|
|
323
|
+
- 该用法是在[基本使用](/components/waterfall.html#基本使用-vue生效)的代码基础上进行扩展
|
|
324
|
+
- 使用场景:一般使用在触底加载更多数据等场景。以下案例配合加载更多组件[uv-load-more](https://ext.dcloud.net.cn/plugin?name=uv-load-more)
|
|
325
|
+
|
|
326
|
+
```vue
|
|
327
|
+
<template>
|
|
328
|
+
<view class="waterfall">
|
|
329
|
+
<uv-waterfall ref="waterfall">...</uv-waterfall>
|
|
330
|
+
<!-- 加载更多组件 -->
|
|
331
|
+
<uv-load-more :status="loadStatus"></uv-load-more>
|
|
332
|
+
</view>
|
|
333
|
+
</template>
|
|
334
|
+
<script setup>
|
|
335
|
+
import { ref } from 'vue';
|
|
336
|
+
import { onReachBottom } from '@dcloudio/uni-app';
|
|
337
|
+
|
|
338
|
+
const list = ref([]);
|
|
339
|
+
const waterfall = ref(null);
|
|
340
|
+
const loadStatus = ref('loadmore');
|
|
341
|
+
|
|
342
|
+
onReachBottom(async () => {
|
|
343
|
+
if (loadStatus.value === 'loadmore') {
|
|
344
|
+
loadStatus.value = 'loading';
|
|
345
|
+
const { data } = await getData();
|
|
346
|
+
list.value.push(...data);
|
|
347
|
+
loadStatus.value = 'loadmore';
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
</script>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### tab切换案例
|
|
355
|
+
|
|
356
|
+
设计思路:瀑布流是属于动态去根据每项的高度去计算该显示到哪列,当tab切换数据更换时,就需要将原有的数据清除,重新赋值新数据。
|
|
357
|
+
|
|
358
|
+
该示例不完整,需要完整示例请到[跳转入口](/components/waterfall.html#完整示例)下载,这里只是提供一个思路:
|
|
359
|
+
|
|
360
|
+
```vue
|
|
361
|
+
<template>
|
|
362
|
+
<view class="waterfall">
|
|
363
|
+
<uv-tabs :list="tabList" @click="clickTab"></uv-tabs>
|
|
364
|
+
<uv-waterfall ...>
|
|
365
|
+
...
|
|
366
|
+
</uv-waterfall>
|
|
367
|
+
</view>
|
|
368
|
+
</template>
|
|
369
|
+
<script setup>
|
|
370
|
+
import { ref } from "vue";
|
|
371
|
+
const tabList = ref([{
|
|
372
|
+
name: '选项一'
|
|
373
|
+
}, {
|
|
374
|
+
name: '选项二'
|
|
375
|
+
}]);
|
|
376
|
+
const list = ref([]);
|
|
377
|
+
const list1 = ref([]);
|
|
378
|
+
const list2 = ref([]);
|
|
379
|
+
const waterfall = ref(null);
|
|
380
|
+
async function clickTab(e) {
|
|
381
|
+
list.value = [];
|
|
382
|
+
waterfall.value.clear();
|
|
383
|
+
list1.value = [];
|
|
384
|
+
list2.value = [];
|
|
385
|
+
const {
|
|
386
|
+
data
|
|
387
|
+
} = await getData();
|
|
388
|
+
list.value = data;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
</script>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 优化方案 (vue生效)
|
|
395
|
+
|
|
396
|
+
- 上面的示例使用`image`展示图片,如果需要功能更强大图片组件(加载中、加载失败反馈等),可使用[uv-image](https://www.uvui.cn/components/image.html)
|
|
397
|
+
- 通过`addTime`属性可以设置每项显示的速度,值越小体验越好,但是可能导致两列高度相差较大。这里可以提供一个优化思路:通过后端返回图片的宽高,然后再通过每列的宽度,最后计算出每张图片应该展示的宽高,然后给`image`套一层`<view style="width:xxx;height:xxx;"></view>`,提前将位置站好,这样计算出的每列的高度就能保证相近没有误差
|
|
398
|
+
- 如果页面还没渲染结束,页面就跳走,但此时`@changeList`回调还在返回数据,可能会造成渲染出错,所以要想办法停止渲染,如下处理方式:
|
|
399
|
+
```vue
|
|
400
|
+
<script setup>
|
|
401
|
+
import { ref } from "vue";
|
|
402
|
+
import { onHide } from "@dcloudio/uni-app";
|
|
403
|
+
|
|
404
|
+
const waterfall = ref(null);
|
|
405
|
+
|
|
406
|
+
onHide(() => {
|
|
407
|
+
waterfall.value?.clear();
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
</script>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### NVUE中使用 (nvue生效)
|
|
414
|
+
|
|
415
|
+
- 在`NVUE`中使用方法比较简单,直接看下面案例就懂,需要注意的是`APP-NVUE`中不能使用`uv-iamge`等组件,原因:[android端list中为什么不能使用uv-image等组件](https://www.uvui.cn/components/problem.html#%E5%85%AD%E3%80%81android%E7%AB%AFlist%E4%B8%AD%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E8%83%BD%E4%BD%BF%E7%94%A8uv-image%E7%AD%89%E7%BB%84%E4%BB%B6)。
|
|
416
|
+
- 通过`column-count`设置瀑布流列数,默认2,范围1-5。
|
|
417
|
+
- 在`NVUE`中使用`uv-waterfall`需要配合`cell`使用,相关文档可以参考[waterfall](https://uniapp.dcloud.net.cn/component/waterfall.html)。
|
|
418
|
+
|
|
419
|
+
```vue
|
|
420
|
+
<template>
|
|
421
|
+
<view class="waterfall">
|
|
422
|
+
<uv-waterfall
|
|
423
|
+
column-count="2"
|
|
424
|
+
left-gap="10"
|
|
425
|
+
right-gap="10"
|
|
426
|
+
column-gap="8"
|
|
427
|
+
@scrolltolower="init">
|
|
428
|
+
<cell
|
|
429
|
+
v-for="(item,index) in list"
|
|
430
|
+
class="waterfall-item-cell"
|
|
431
|
+
>
|
|
432
|
+
<view class="waterfall-item">
|
|
433
|
+
<view class="waterfall-item__image">
|
|
434
|
+
<image :src="item.image" mode="widthFix" style="border-radius: 20rpx;"></image>
|
|
435
|
+
</view>
|
|
436
|
+
<view class="waterfall-item__ft">
|
|
437
|
+
<view class="waterfall-item__ft__title">
|
|
438
|
+
<text class="value">{{item.title}}</text>
|
|
439
|
+
</view>
|
|
440
|
+
<view class="waterfall-item__ft__desc uv-line-2">
|
|
441
|
+
<text class="value">{{item.desc}}</text>
|
|
442
|
+
</view>
|
|
443
|
+
</view>
|
|
444
|
+
</view>
|
|
445
|
+
<view style="height: 4px;width: 4px;"></view>
|
|
446
|
+
</cell>
|
|
447
|
+
</uv-waterfall>
|
|
448
|
+
</view>
|
|
449
|
+
</template>
|
|
450
|
+
<script setup>
|
|
451
|
+
import { guid } from '@gmcb/uv-ui/libs/function/index.js';
|
|
452
|
+
import { ref } from "vue";
|
|
453
|
+
import { onLoad, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
|
|
454
|
+
const list = ref([]);
|
|
455
|
+
const loadStatus = ref('loadmore');
|
|
456
|
+
async function init() {
|
|
457
|
+
loadStatus.value = 'loading';
|
|
458
|
+
const {
|
|
459
|
+
data
|
|
460
|
+
} = await getData();
|
|
461
|
+
list.value.push.apply(list.value, data);
|
|
462
|
+
loadStatus.value = 'loadmore';
|
|
463
|
+
}
|
|
464
|
+
function getData() {
|
|
465
|
+
return new Promise(resolve => {
|
|
466
|
+
const imgs = [{
|
|
467
|
+
url: 'https://via.placeholder.com/100x110.png/3c9cff/fff',
|
|
468
|
+
width: 100,
|
|
469
|
+
height: 110
|
|
470
|
+
}, {
|
|
471
|
+
url: 'https://via.placeholder.com/200x220.png/f9ae3d/fff',
|
|
472
|
+
width: 200,
|
|
473
|
+
height: 220
|
|
474
|
+
}, {
|
|
475
|
+
url: 'https://via.placeholder.com/300x340.png/5ac725/fff',
|
|
476
|
+
width: 300,
|
|
477
|
+
height: 340
|
|
478
|
+
}, {
|
|
479
|
+
url: 'https://via.placeholder.com/400x400.png/f56c6c/fff',
|
|
480
|
+
width: 400,
|
|
481
|
+
height: 400
|
|
482
|
+
}, {
|
|
483
|
+
url: 'https://via.placeholder.com/500x510.png/909399/fff',
|
|
484
|
+
width: 500,
|
|
485
|
+
height: 510
|
|
486
|
+
}, {
|
|
487
|
+
url: 'https://via.placeholder.com/600x606.png/3c9cff/fff',
|
|
488
|
+
width: 600,
|
|
489
|
+
height: 606
|
|
490
|
+
}, {
|
|
491
|
+
url: 'https://via.placeholder.com/310x422.png/f1a532/fff',
|
|
492
|
+
width: 310,
|
|
493
|
+
height: 422
|
|
494
|
+
}, {
|
|
495
|
+
url: 'https://via.placeholder.com/320x430.png/3c9cff/fff',
|
|
496
|
+
width: 320,
|
|
497
|
+
height: 430
|
|
498
|
+
}, {
|
|
499
|
+
url: 'https://via.placeholder.com/330x424.png/f9ae3d/fff',
|
|
500
|
+
width: 330,
|
|
501
|
+
height: 424
|
|
502
|
+
}, {
|
|
503
|
+
url: 'https://via.placeholder.com/340x435.png/5ac725/fff',
|
|
504
|
+
width: 340,
|
|
505
|
+
height: 435
|
|
506
|
+
}, {
|
|
507
|
+
url: 'https://via.placeholder.com/350x440.png/f56c6c/fff',
|
|
508
|
+
width: 350,
|
|
509
|
+
height: 440
|
|
510
|
+
}, {
|
|
511
|
+
url: 'https://via.placeholder.com/380x470.png/909399/fff',
|
|
512
|
+
width: 380,
|
|
513
|
+
height: 470
|
|
514
|
+
}];
|
|
515
|
+
let list = [];
|
|
516
|
+
const doFn = i => {
|
|
517
|
+
const randomIndex = Math.floor(Math.random() * 10);
|
|
518
|
+
return {
|
|
519
|
+
id: guid(),
|
|
520
|
+
allowEdit: i == 0,
|
|
521
|
+
image: imgs[randomIndex].url,
|
|
522
|
+
w: imgs[randomIndex].width,
|
|
523
|
+
h: imgs[randomIndex].height,
|
|
524
|
+
title: i % 2 == 0 ? `(${list.value.length + i + 1})体验uv-ui框架` : `(${list.value.length + i + 1})uv-ui支持多平台`,
|
|
525
|
+
desc: i % 2 == 0 ? `(${list.value.length + i + 1})欢迎使用uv-ui,uni-app生态专用的UI框架` : `(${list.value.length + i})开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序`
|
|
526
|
+
};
|
|
527
|
+
};
|
|
528
|
+
// 模拟异步
|
|
529
|
+
setTimeout(() => {
|
|
530
|
+
for (let i = 0; i < 20; i++) {
|
|
531
|
+
list.push(doFn(i));
|
|
532
|
+
}
|
|
533
|
+
resolve({
|
|
534
|
+
data: list
|
|
535
|
+
});
|
|
536
|
+
}, 200);
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
onLoad(async () => {
|
|
540
|
+
const {
|
|
541
|
+
data
|
|
542
|
+
} = await getData();
|
|
543
|
+
list.value = data;
|
|
544
|
+
});
|
|
545
|
+
onPullDownRefresh(async () => {
|
|
546
|
+
list.value = [];
|
|
547
|
+
init();
|
|
548
|
+
uni.showToast({
|
|
549
|
+
icon: 'success',
|
|
550
|
+
title: '刷新成功'
|
|
551
|
+
});
|
|
552
|
+
uni.stopPullDownRefresh();
|
|
553
|
+
});
|
|
554
|
+
onReachBottom(async () => {
|
|
555
|
+
if (loadStatus.value == 'loadmore') {
|
|
556
|
+
init();
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
</script>
|
|
561
|
+
<style scoped lang="scss">
|
|
562
|
+
$show-lines: 1;
|
|
563
|
+
@import '@gmcb/uv-ui/libs/css/variable.scss';
|
|
564
|
+
.waterfall {
|
|
565
|
+
background-color: #f1f1f1;
|
|
566
|
+
}
|
|
567
|
+
.waterfall-item {
|
|
568
|
+
overflow: hidden;
|
|
569
|
+
margin-top: 10px;
|
|
570
|
+
border-radius: 6px;
|
|
571
|
+
}
|
|
572
|
+
.waterfall-item__ft {
|
|
573
|
+
padding: 20rpx;
|
|
574
|
+
background: #fff;
|
|
575
|
+
&__title {
|
|
576
|
+
margin-bottom: 10rpx;
|
|
577
|
+
line-height: 48rpx;
|
|
578
|
+
font-weight: 700;
|
|
579
|
+
.value {
|
|
580
|
+
font-size: 32rpx;
|
|
581
|
+
color: #303133;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
&__desc .value {
|
|
585
|
+
font-size: 28rpx;
|
|
586
|
+
color: #606266;
|
|
587
|
+
}
|
|
588
|
+
&__btn {
|
|
589
|
+
padding: 10px 0;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
</style>
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### 完整示例
|
|
596
|
+
|
|
597
|
+
::: tip 完整示例下载地址
|
|
598
|
+
|
|
599
|
+
[https://ext.dcloud.net.cn/plugin?name=uv-ui](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
|
600
|
+
|
|
601
|
+
:::
|
|
602
|
+
|
|
603
|
+
### API
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
### Waterfall Props
|
|
607
|
+
|
|
608
|
+
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
|
609
|
+
| :- | :- | :- | :- | :- |
|
|
610
|
+
| v-model | 瀑布流数据,(vue生效) | Array | [] | - |
|
|
611
|
+
| idKey | 数据的id值,根据id值对数据可执行删除操作。如数据为:{id: 1, name: 'uv-ui'},那么该值设置为id,(vue生效) | String | 'id' | - |
|
|
612
|
+
| addTime | 每次插入数据的事件间隔,间隔越长能保证两列高度相近,但是用户体验不好,单位ms,(vue生效) | Number | 200 | - |
|
|
613
|
+
| columnCount | 瀑布流的列数,默认2,最高为5 | Number | String | 2 | 1-5 |
|
|
614
|
+
| columnGap | 列与列的间隙,默认单位px | Number | String | 20 | - |
|
|
615
|
+
| leftGap | 左边和列表的间隙,默认单位px | Number | String | 0 | - |
|
|
616
|
+
| rightGap | 右边和列表的间隙,默认单位px | Number | String | 0 | - |
|
|
617
|
+
| showScrollbar | 是否显示滚动条,(nvue生效) | Boolean | false | true | false |
|
|
618
|
+
| columnWidth | 列宽,单位px,(nvue生效) | Number | String | 'auto' | - |
|
|
619
|
+
| width | 瀑布流的宽度,(nvue生效) | Number | String | 屏幕宽度 | - |
|
|
620
|
+
| height | 瀑布流的高度,(nvue生效) | Number | String | 屏幕高度 | - |
|
|
621
|
+
|
|
622
|
+
### Waterfall Methods
|
|
623
|
+
|
|
624
|
+
| 事件名 | 说明 | 类型 |
|
|
625
|
+
| :- | :- | :- |
|
|
626
|
+
| remove | 清除指定的某一条数据,根据id来实现,删除后v-model绑定的数据会自动变化,(vue生效) | Handler|
|
|
627
|
+
| clear | 清除瀑布流数据,(vue生效) |-|
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
### Waterfall Events
|
|
631
|
+
|
|
632
|
+
|事件名 |说明 |回调参数 |
|
|
633
|
+
|:- |:- |:- |
|
|
634
|
+
| @changeList | **【必须使用】** 处理数据时触发,为了兼容某些端不支持插槽回传参数的情况(vue生效) | 列表数据,eg:columnCount=2,的、第一次返回{list1:{...}},第二次返回{list2:{...}}...。返回后需要手动追加对应的列数据 |
|
|
635
|
+
| @finish | 瀑布流加载完成触发事件,(vue生效) | - |
|
|
636
|
+
| @clear | 清空数据列表触发事件,(vue生效) | - |
|
|
637
|
+
| @remove | 删除列表中某条数据触发事件,(vue生效) | id |
|
|
638
|
+
| @scrolltolower | 滚动到底部触发事件,(nvue生效) | - |
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
### Waterfall Slots (vue生效)
|
|
642
|
+
|
|
643
|
+
|事件名 |说明 |
|
|
644
|
+
|:- |:- |
|
|
645
|
+
| - | 瀑布流内容 |
|
|
646
|
+
|
|
647
|
+
<style scoped>
|
|
648
|
+
h3[id=waterfall-slots-vue生效] + table thead tr th:nth-child(2) {
|
|
649
|
+
width: 80%;
|
|
650
|
+
}
|
|
651
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 常见问题
|
|
2
|
+
|
|
3
|
+
## easycom 配置后组件不生效
|
|
4
|
+
|
|
5
|
+
确认 `pages.json` 中配置了当前包路径:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"easycom": {
|
|
10
|
+
"autoscan": true,
|
|
11
|
+
"custom": {
|
|
12
|
+
"^uv-(.*)": "@gmcb/uv-ui/components/uv-$1/uv-$1.vue"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
修改 easycom 后需要重新运行 uni-app 项目。
|
|
19
|
+
|
|
20
|
+
## `uni.$uv` 不存在
|
|
21
|
+
|
|
22
|
+
确认项目入口已经注册插件:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import uvUI from '@gmcb/uv-ui';
|
|
26
|
+
|
|
27
|
+
app.use(uvUI);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
如果在插件注册之前访问 `uni.$uv`,会得到空值或旧值。
|
|
31
|
+
|
|
32
|
+
## 样式变量未生效
|
|
33
|
+
|
|
34
|
+
确认主题和基础样式已经引入:
|
|
35
|
+
|
|
36
|
+
```scss
|
|
37
|
+
@import '@gmcb/uv-ui/theme.scss';
|
|
38
|
+
@import '@gmcb/uv-ui/index.scss';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
主题变量需要在组件样式加载前覆盖或统一在项目主题入口维护。
|
|
42
|
+
|
|
43
|
+
## 工具文档为什么在 API 下
|
|
44
|
+
|
|
45
|
+
当前包将工具归入 API:纯工具函数在 `docs/api/utils`,请求能力在 `docs/api/request`,混入能力在 `docs/api/mixins`,配置说明在 `docs/api/configs`。旧版 uv-ui 文档里的 `js` 分类不再保留。
|
|
46
|
+
|
|
47
|
+
## 是否还需要旧工具包
|
|
48
|
+
|
|
49
|
+
不需要。当前包已经包含组件、样式、工具函数和 `$uv` 全局能力,推荐统一使用 `@gmcb/uv-ui`。
|
|
50
|
+
|
|
51
|
+
## 请求能力如何使用
|
|
52
|
+
|
|
53
|
+
插件注册后可通过 `uni.$uv.http` 使用请求实例。具体拦截器和实践示例见 [HTTP 请求](/api/request/http.md)。
|