- 概要
- 支持的平台
- 使用方式
- 属性说明
- 事件说明
- 组件方法
- refresh的使用示例
- 隐藏单个图片示例
- 完整示例
- 温馨提示
- 关注我,不要迷路
概要
custom-waterfalls-flow瀑布流插件配置灵活,使用方便,兼容多端,兼容vue2和vue3。
最近做项目的时候需要瀑布流,就在插件市场找了一些。下载量最高的是定位。我觉得瀑布流不用定位就能实现,就自己写了插件。经过反复测试和优化,终于完成了!
瀑布流的列数可以通过参数直接控制,实时监控,随改变而生效。最小列数为2,最大默认为5,可过maxColumn理论上,参数可以控制最大列数,设置无限大,具体值可以自己处理。
瀑布流的每一个数据都可以直接修改value,随着改进的生效,可以加载更多的数据。渲染过的数据不会再渲染,只会每次渲染新的数据,避免了渲染越多越慢的数据。可以调用组件refresh()
方法刷新数据,注意vue2和vue3.调用子组件的方法不同,下面也会说明。
瀑布流可以是纯图片,可以使用插槽自定义文本描述、微信小程序和app、h5使用会有一些差异,下面会详细说明。不用担心内容的高度和排名,会根据每个项目的高度自动计算。
通过配置列数,先渲染出每列,再计算每列的高度,最小的那列就加入一条数据进行渲染,然后再重复计算每列,高度小的加入数据…其实思路很简单。
uniapp插件市场地址:https://ext.dcloud.net.cn/plugin?id=7594
支持的平台
H5、app、微信小程序(这三个平台经过反复测试优化,兼容vue2和vue3)。
百度小程序:由于插槽不能循环渲染,只支持纯图像瀑布流。
其他小程序:没有测试,需要自己测试和修改,想法必须正确,主要与插槽兼容。
nvue:如果暂时不支持,以后可能会支持在需要的可以自己修改源码。
使用方式
该组件符合uni_modules规范,使用Hbuilderx导入插件,导入项目根目目录uni_modules文件夹中。
uni_modules规范直接用于项目页面,无需单独引入注册组件。
<template> <custom-waterfalls-flow :value="data.list"></custom-waterfalls-flow> </template>
微信小程序没有动态模板,使用for渲染循环方式。
<template> <custom-waterfalls-flow :value="data.list"> <view class="item" v-for="(item,index) in data.list" :key="index" slot="slot{
{index}}"> <view class="title">{
{item.title}}</view> <view class="desc">{
{item.desc}}</view> </view> </custom-waterfalls-flow> </template>
实现使用作用域插槽
<template> <custom-waterfalls-flow :value="data.list"> <template v-slot:default="item"> <view class="item"> <view class="title">{
{item.title}}</view> <view class="desc">{
{item.desc}}</view> </view> </template> </custom-waterfalls-flow> </template>
条件渲染-多端同时兼容
<template> <custom-waterfalls-flow :value="data.list"> <!-- #ifdef MP-WEIXIN --> <view class="item" v-for="(item,index) in data.list" :key="index" slot="slot{
{index}}"> <view class="title">{
{item.title}}</view> <view class="desc">{
{item.desc}}</view> </view> <!-- #endif --> <!-- #ifndef MP-WEIXIN --> <template v-slot:default="item"> <view class="item"> <view class="title">{
{item.title}}</view> <view class="desc">{
{item.desc}}</view> </view> </template> <!-- #endif --> </custom-waterfalls-flow> </template>
属性说明
参数 | 说明 | 类型 | 是否必填 | 可选值 | 默认值 |
---|---|---|---|---|---|
value | 渲染的列表 | Array | 是 | - | - |
column | 列数 | Number | 否 | 2-maxColumn | 2 |
maxColumn | 最大列数 | Number | 否 | >2 | 5 |
columnSpace | 列间距(单位为百分比) | Number | 否 | - | 2 |
imageKey | 列表中图片字段的键名 | String | 否 | - | image |
hideImageKey | 隐藏图片字段的键名 | String | 否 | - | hide |
seat | 定制文本的位置,1-图片上方,2-图片下方 | Numbr | 否 | 1/2 | 2 |
listStyle | 单个展示项的样式 | Object | 否 | 示例:{'background':'red'} |
- |
事件说明
事件名称 | 说明 | 回调参数 |
---|---|---|
@loaded | 图片加载完成事件 | - |
@wapperClick | 单项点击事件 | 单项对应参数 |
@imageClick | 图片点击事件 | 单项对应参数 |
组件方法
事件名称 | 说明 | 参数 | 使用场景 |
---|---|---|---|
refresh | 刷新数据,数据初始化,vue2中使用:this.$refs.waterfallsFlowRef.refresh(); ;vue3中使用:const waterfallsFlowRef = ref(null);waterfallsFlowRef.value.refresh(); |
- | 下拉刷新等 |
refresh的使用示例
<template>
<view>
<button class="btn" type="default" @click="reset()">刷新数据</button>
<custom-waterfalls-flow ref="waterfallsFlowRef" :value="data.list"></custom-waterfalls-flow>
</view>
</template>
<script>
export default {
data() {
return {
data:{
list: [
{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' },
{ image: 'https://via.placeholder.com/200x200.png/2878ff', title: '我是标题2', desc: '描述描述描述描述描述描述描述描述2' }
]
}
}
},
reset(){
this.data.list = [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' }]
this.$refs.waterfallsFlowRef.refresh();
}
}
</script>
<template>
<view>
<button class="btn" type="default" @click="reset()">刷新数据</button>
<custom-waterfalls-flow ref="waterfallsFlowRef" :value="data.list"></custom-waterfalls-flow>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
const data = reactive({
list: [
{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' },
{ image: 'https://via.placeholder.com/200x200.png/2878ff', title: '我是标题2', desc: '描述描述描述描述描述描述描述描述2' }
]
});
const waterfallsFlowRef = ref(null);
function reset(){
data.list = [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' }]
waterfallsFlowRef.value.refresh();
}
</script>
隐藏单项图片示例
在数据列表中配置hide:true
或者hide:1
,就可以达到不显示图片的效果。支持使用参数hideImageKey自定义键名称,那就使用:定义的键名称:true
或者定义的键名称:1
。
<template>
<custom-waterfalls-flow :value="data.list">
<!-- #ifdef MP-WEIXIN -->
<view class="item" v-for="(item,index) in data.list" :key="index" slot="slot{
{index}}">
<view class="title">{
{item.title}}</view>
<view class="desc">{
{item.desc}}</view>
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<template v-slot:default="item">
<view class="item">
<view class="title">{
{item.title}}</view>
<view class="desc">{
{item.desc}}</view>
</view>
</template>
<!-- #endif -->
</custom-waterfalls-flow>
</template>
<script setup>
import { reactive, ref } from 'vue';
const data = reactive({
list: [
{ image: 'https://via.placeholder.com/200x500.png/ff0000',
hide:1,title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' },
{ image: 'https://via.placeholder.com/200x200.png/2878ff', title: '我是标题2', desc: '描述描述描述描述描述描述描述描述2' }
]
});
</script>
完整示例
<template>
<view style="padding: 0 10rpx;">
<view class="handle">
<button class="btn" type="default" @click="add()">增加数据</button>
<button class="btn" type="default" @click="changeColumn(1)">+列数({
{column}})</button>
<button class="btn" type="default" @click="changeColumn(0)">-列数({
{column}})</button>
<button class="btn" type="default" @click="reset()">刷新数据</button>
</view>
<custom-waterfalls-flow ref="waterfallsFlowRef" :value="data.list" :column="column" :columnSpace="1.5" :seat="2" @wapperClick="wapperClick" @imageClick="imageClick" @loaded="loaded">
<!-- #ifdef MP-WEIXIN -->
<view class="item" v-for="(item,index) in data.list" :key="index" slot="slot{
{index}}">
<view class="title">{
{item.title}}</view>
<view class="desc">{
{item.desc}}</view>
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<template v-slot:default="item">
<view class="item">
<view class="title">{
{item.title}}</view>
<view class="desc">{
{item.desc}}</view>
</view>
</template>
<!-- #endif -->
</custom-waterfalls-flow>
</view>
</template>
<script setup>
// #ifdef VUE3
import { reactive, ref, onMounted } from 'vue';
const data = reactive({
list: [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' },
{ image: 'https://via.placeholder.com/200x200.png/2878ff', title: '我是标题2', desc: '描述描述描述描述描述描述描述描述2' },
{ image: 'https://via.placeholder.com/200x100.png/FFB6C1', title: '我是标题3', desc: '描述描述描述描述描述描述描述描述3' },
{ image: 'https://via.placeholder.com/200x300.png/9400D3', title: '我是标题4', desc: '描述描述描述描述描述描述描述描述4' },
{ image: 'https://via.placeholder.com/100x240.png/B0E0E6', title: '我是标题5', desc: '描述描述描述描述描述描述描述描述5' },
{ image: 'https://via.placeholder.com/140x280.png/7FFFAA', title: '我是标题6', desc: '描述描述描述描述描述描述描述描述6' },
{ image: 'https://via.placeholder.com/40x60.png/EEE8AA', title: '我是标题7', desc: '描述描述描述描述描述描述描述描述7' }]
});
const column = ref(3);
function add() {
const newArr = [{ image: 'https://via.placeholder.com/58x100.png/FF7F50', title: '我是标题8', desc: '描述描述描述描述描述描述描述描述8' },
{ image: 'https://via.placeholder.com/59x100.png/C0C0C0', title: '我是标题9', desc: '描述描述描述描述描述描述描述描述9' },
{ image: 'https://via.placeholder.com/60x100.png/FAEBD7', title: '我是标题10', desc: '描述描述描述描述描述描述描述描述10' }];
data.list = data.list.concat(newArr);
}
function changeColumn(h) {
column.value = !h ? column.value - 1 : column.value + 1;
}
function loaded() {
console.log('加载完成')
}
function wapperClick(item) {
console.log('单项点击事件', item)
}
function imageClick(item) {
console.log('图片点击事件', item)
}
const waterfallsFlowRef = ref(null);
function reset() {
data.list = [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' }]
waterfallsFlowRef.value.refresh();
}
// #endif
</script>
<script>
// #ifdef VUE2
export default {
data() {
return {
data: {
list: [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' },
{ image: 'https://via.placeholder.com/200x200.png/2878ff', title: '我是标题2', desc: '描述描述描述描述描述描述描述描述2' },
{ image: 'https://via.placeholder.com/200x100.png/FFB6C1', title: '我是标题3', desc: '描述描述描述描述描述描述描述描述3' },
{ image: 'https://via.placeholder.com/200x300.png/9400D3', title: '我是标题4', desc: '描述描述描述描述描述描述描述描述4' },
{ image: 'https://via.placeholder.com/100x240.png/B0E0E6', title: '我是标题5', desc: '描述描述描述描述描述描述描述描述5' },
{ image: 'https://via.placeholder.com/140x280.png/7FFFAA', title: '我是标题6', desc: '描述描述描述描述描述描述描述描述6' },
{ image: 'https://via.placeholder.com/40x60.png/EEE8AA', title: '我是标题7', desc: '描述描述描述描述描述描述描述描述7' }]
},
column: 3
}
},
methods: {
add() {
const newArr = [{ image: 'https://via.placeholder.com/58x100.png/FF7F50', title: '我是标题8', desc: '描述描述描述描述描述描述描述描述8' },
{ image: 'https://via.placeholder.com/59x100.png/C0C0C0', title: '我是标题9', desc: '描述描述描述描述描述描述描述描述9' },
{ image: 'https://via.placeholder.com/60x100.png/FAEBD7', title: '我是标题10', desc: '描述描述描述描述描述描述描述描述10' }]
this.data.list = this.data.list.concat(newArr);
},
changeColumn(h) {
this.column = !h ? this.column - 1 : this.column + 1;
},
loaded() {
console.log('加载完成')
},
wapperClick(item) {
console.log('单项点击事件', item)
},
imageClick(item) {
console.log('图片点击事件', item)
},
reset() {
this.data.list = [{ image: 'https://via.placeholder.com/200x500.png/ff0000', title: '我是标题1', desc: '描述描述描述描述描述描述描述描述1' }]
this.$refs.waterfallsFlowRef.refresh();
}
}
}
// #endif
</script>
<style>
page {
background-color: #f2f5f9;
}
</style>
<style lang="scss" scoped>
.handle {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 20rpx;
padding: 10rpx;
.btn {
margin: 20rpx 10rpx;
padding: 0 20rpx;
background: #2878FF;
font-size: 28rpx;
color: #fff;
&::after {
border: 0;
}
}
}
.item {
padding: 10rpx 10rpx 20rpx;
.title {
line-height: 48rpx;
font-size: 28rpx;
color: #222;
}
.desc {
font-size: 24rpx;
color: #666;
}
}
</style>
温馨提示
1、该插件反复测试过微信小程序、h5、app-vue三个端,vue2和vue3都兼容,其他端可能需要测试改进。
2、该插件的使用hbuilderx版本最好升级到较新版本,我开发的版本是hbuilderx3.3.11.20220209。
3、对此插件或相关问题有好的建议,可以直接在评论区进行讨论。
4、希望遇到问题不要喷,也不要骂人,其实这种心情我能理解,写该插件也不是一时半会就完成了的,所以希望互相理解。只要有问题,我会第一时间回复解决。
5、对此插件有任何问题的可以在下方留言,我会第一时间回复和解决问题。还可以加QQ群进行前端技术交流 568984539,加群备注‘地区-名字-技术类型’。
最后我想说:认为该插件对你有帮助的,记得收藏、好评,这样可以帮助到更多人哟!
关注我,不迷路
如果任何疑问的可以在评论区留言,还可以加QQ群交流:568984539,加群备注‘地区-名字-技术类型’。
更多前端等相关知识可关注我个人博客:https://blog.csdn.net/qq_42961150?spm=1011.2124.3001.5343