mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-06 08:27:54 +08:00
feat: 新增组件-瀑布流demo
This commit is contained in:
parent
799a5140e3
commit
4e3d752fb6
@ -36,6 +36,7 @@ const include = [
|
||||
"element-resize-detector",
|
||||
"@amap/amap-jsapi-loader",
|
||||
"el-table-infinite-scroll",
|
||||
"vue-waterfall-plugin-next",
|
||||
"@wangeditor/editor-for-vue",
|
||||
"vuedraggable/src/vuedraggable"
|
||||
];
|
||||
|
@ -39,6 +39,7 @@ menus:
|
||||
hsdialog: Dialog Components
|
||||
hsmessage: Message Tips Components
|
||||
hsvideo: Video Components
|
||||
hswaterfall: Waterfall Components
|
||||
hsmap: Map Components
|
||||
hsdraggable: Draggable Components
|
||||
hssplitPane: Split Pane
|
||||
|
@ -39,6 +39,7 @@ menus:
|
||||
hsdialog: 函数式弹框组件
|
||||
hsmessage: 消息提示组件
|
||||
hsvideo: 视频组件
|
||||
hswaterfall: 瀑布流组件
|
||||
hsmap: 地图组件
|
||||
hsdraggable: 拖拽组件
|
||||
hssplitPane: 切割面板
|
||||
|
@ -72,6 +72,7 @@
|
||||
"vue-router": "^4.2.0",
|
||||
"vue-types": "^5.0.2",
|
||||
"vue-virtual-scroller": "2.0.0-beta.7",
|
||||
"vue-waterfall-plugin-next": "^2.2.1",
|
||||
"vue3-danmaku": "1.4.0-beta.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"xgplayer": "^3.0.2",
|
||||
|
29
pnpm-lock.yaml
generated
29
pnpm-lock.yaml
generated
@ -108,6 +108,7 @@ specifiers:
|
||||
vue-tsc: ^1.6.5
|
||||
vue-types: ^5.0.2
|
||||
vue-virtual-scroller: 2.0.0-beta.7
|
||||
vue-waterfall-plugin-next: ^2.2.1
|
||||
vue3-danmaku: 1.4.0-beta.1
|
||||
vuedraggable: ^4.1.0
|
||||
xgplayer: ^3.0.2
|
||||
@ -157,6 +158,7 @@ dependencies:
|
||||
vue-router: 4.2.0_vue@3.3.2
|
||||
vue-types: 5.0.2_vue@3.3.2
|
||||
vue-virtual-scroller: 2.0.0-beta.7_vue@3.3.2
|
||||
vue-waterfall-plugin-next: 2.2.1_vue@3.3.2
|
||||
vue3-danmaku: 1.4.0-beta.1_vue@3.3.2
|
||||
vuedraggable: 4.1.0_vue@3.3.2
|
||||
xgplayer: 3.0.2
|
||||
@ -11966,6 +11968,33 @@ packages:
|
||||
vue-resize: 2.0.0-alpha.1_vue@3.3.2
|
||||
dev: false
|
||||
|
||||
/vue-waterfall-plugin-next/2.2.0_vue@3.3.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-rhrTdAlBnMWWt6737L+E08A7itgK3wHTy1NsSDgR9EPiBPuHYlth8jL2/hp2gIMAS4XUxJBtitfNUyK5qynkEA==
|
||||
}
|
||||
dependencies:
|
||||
animate.css: 4.1.1
|
||||
element-plus: 2.3.4_vue@3.3.2
|
||||
transitivePeerDependencies:
|
||||
- "@vue/composition-api"
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/vue-waterfall-plugin-next/2.2.1_vue@3.3.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-wEPT9D9VLTPWxGKrIusBxj9JVyXyXU6RLEqKIm3mJt/DeaTUvKu0sZjLOKK9UztkcJV2LaRALwRoCDOOKbLsiw==
|
||||
}
|
||||
dependencies:
|
||||
animate.css: 4.1.1
|
||||
element-plus: 2.3.4_vue@3.3.2
|
||||
vue-waterfall-plugin-next: 2.2.0_vue@3.3.2
|
||||
transitivePeerDependencies:
|
||||
- "@vue/composition-api"
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/vue/3.3.2:
|
||||
resolution:
|
||||
{
|
||||
|
@ -31,6 +31,15 @@ export default {
|
||||
title: $t("menus.hsmessage")
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/components/waterfall",
|
||||
name: "Waterfall",
|
||||
component: () => import("@/views/components/waterfall/index.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hswaterfall"),
|
||||
extraIcon: "IF-pure-iconfont-new svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/components/video",
|
||||
name: "Video",
|
||||
|
38
src/views/components/waterfall/api.ts
Normal file
38
src/views/components/waterfall/api.ts
Normal file
@ -0,0 +1,38 @@
|
||||
export function randomID(length = 6) {
|
||||
return Number(
|
||||
Math.random().toString().substr(3, length) + Date.now()
|
||||
).toString(36);
|
||||
}
|
||||
|
||||
const COLORS = ["#409EFF", "#67C23A", "#E6A23C", "#F56C6C", "#909399"];
|
||||
|
||||
function getRandomNum(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function randomColor() {
|
||||
return COLORS[getRandomNum(0, 4)];
|
||||
}
|
||||
|
||||
const website = "https://www.getphotoblanket.com";
|
||||
|
||||
export const getList = ({ page = 1, pageSize = 20 }) => {
|
||||
const url = `${website}/products.json?page=${page}&limit=${pageSize}`;
|
||||
return fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(res => res.products)
|
||||
.then(res => {
|
||||
return res.map((item: any) => {
|
||||
return {
|
||||
id: randomID(),
|
||||
star: false,
|
||||
price: item.variants[0].price,
|
||||
src: {
|
||||
original: item.images[0].src
|
||||
},
|
||||
backgroundColor: randomColor(),
|
||||
name: item.title
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
BIN
src/views/components/waterfall/error.png
Normal file
BIN
src/views/components/waterfall/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
151
src/views/components/waterfall/index.vue
Normal file
151
src/views/components/waterfall/index.vue
Normal file
@ -0,0 +1,151 @@
|
||||
<script setup lang="ts">
|
||||
import { getList } from "./api";
|
||||
import error from "./error.png";
|
||||
import loading from "./loading.png";
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import "vue-waterfall-plugin-next/dist/style.css";
|
||||
import backTop from "@/assets/svg/back_top.svg?component";
|
||||
import { LazyImg, Waterfall } from "vue-waterfall-plugin-next";
|
||||
|
||||
const options = reactive({
|
||||
// 唯一key值
|
||||
rowKey: "id",
|
||||
// 卡片之间的间隙
|
||||
gutter: 10,
|
||||
// 是否有周围的gutter
|
||||
hasAroundGutter: true,
|
||||
// 卡片在PC上的宽度
|
||||
width: 320,
|
||||
// 自定义行显示个数,主要用于对移动端的适配
|
||||
breakpoints: {
|
||||
1200: {
|
||||
// 当屏幕宽度小于等于1200
|
||||
rowPerView: 4
|
||||
},
|
||||
800: {
|
||||
// 当屏幕宽度小于等于800
|
||||
rowPerView: 3
|
||||
},
|
||||
500: {
|
||||
// 当屏幕宽度小于等于500
|
||||
rowPerView: 2
|
||||
}
|
||||
},
|
||||
// 动画效果
|
||||
animationEffect: "animate__fadeInUp",
|
||||
// 动画时间
|
||||
animationDuration: 1000,
|
||||
// 动画延迟
|
||||
animationDelay: 300,
|
||||
// 背景色
|
||||
// backgroundColor: "#2C2E3A",
|
||||
// 图片字段选择器,如果层级较深,使用 xxx.xxx.xxx 方式
|
||||
imgSelector: "src.original",
|
||||
// 加载配置
|
||||
loadProps: {
|
||||
loading,
|
||||
error
|
||||
},
|
||||
// 是否懒加载
|
||||
lazyload: true
|
||||
});
|
||||
|
||||
const page = ref(1);
|
||||
const list = ref([]);
|
||||
const pageSize = ref();
|
||||
|
||||
/** 加载更多 */
|
||||
function handleLoadMore() {
|
||||
getList({
|
||||
page: page.value,
|
||||
pageSize: pageSize.value
|
||||
}).then(res => {
|
||||
list.value.push(...res);
|
||||
page.value += 1;
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(item, index) {
|
||||
list.value.splice(index, 1);
|
||||
}
|
||||
|
||||
function handleClick(item) {
|
||||
console.log(item);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleLoadMore();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-card shadow="never" class="!h-[85vh]">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">
|
||||
瀑布流组件,采用开源的
|
||||
<el-link
|
||||
href="https://github.com/heikaimu/vue3-waterfall-plugin"
|
||||
target="_blank"
|
||||
style="margin: 0 4px 5px; font-size: 16px"
|
||||
>
|
||||
vue-waterfall-plugin-next
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-scrollbar height="78vh" class="content">
|
||||
<Waterfall :list="list" v-bind="options">
|
||||
<template #item="{ item, url, index }">
|
||||
<div
|
||||
class="bg-gray-900 rounded-lg shadow-md overflow-hidden transition-all duration-300 ease-linear hover:shadow-lg hover:shadow-gray-600 group"
|
||||
@click="handleClick(item)"
|
||||
>
|
||||
<div class="overflow-hidden">
|
||||
<LazyImg
|
||||
:url="url"
|
||||
class="cursor-pointer transition-all duration-300 ease-linear group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
<div class="px-4 pt-2 pb-4 border-t border-t-gray-800">
|
||||
<h4 class="pb-4 text-gray-50 group-hover:text-yellow-300">
|
||||
{{ item.name }}
|
||||
</h4>
|
||||
<div
|
||||
class="pt-3 flex justify-between items-center border-t border-t-gray-600 border-opacity-50"
|
||||
>
|
||||
<div class="text-gray-50">$ {{ item.price }}</div>
|
||||
<div>
|
||||
<button
|
||||
class="px-3 h-7 rounded-full bg-red-500 text-sm text-white shadow-lg transition-all duration-300 hover:bg-red-600"
|
||||
@click.stop="handleDelete(item, index)"
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Waterfall>
|
||||
|
||||
<div class="flex justify-center py-10">
|
||||
<button
|
||||
class="px-5 py-2 rounded-full bg-gray-700 text-md text-white cursor-pointer hover:bg-gray-800 transition-all duration-300"
|
||||
@click="handleLoadMore"
|
||||
>
|
||||
加载更多
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<el-backtop
|
||||
title="回到顶部"
|
||||
:right="35"
|
||||
:visibility-height="400"
|
||||
target=".content .el-scrollbar__wrap"
|
||||
>
|
||||
<backTop />
|
||||
</el-backtop>
|
||||
</el-scrollbar>
|
||||
</el-card>
|
||||
</template>
|
BIN
src/views/components/waterfall/loading.png
Normal file
BIN
src/views/components/waterfall/loading.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Loading…
x
Reference in New Issue
Block a user