vue3-andsign 中实现实物电商列表的页面
这里自己做一个代码整理 做了一个实物电商 选品中心的页面 看里面有些效果挺好 这里记录一下
直接粘贴代码了 我自己能看懂 做了一个列表显示 骨架屏等 效果 使用了grid 布局 比媒体查询好使
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { message, Skeleton } from 'ant-design-vue'
import * as echarts from 'echarts'
import Tip from './components/Tip.vue'
import { useBrandStore } from '@/store/modules/brand'
import { DownOutlined } from '@ant-design/icons-vue'
import Item from './components/item.vue'
import * as phyicalApi from '@/api/physical'const route = useRoute()
let chart = ref<echarts.ECharts | null>(null)
const oneRef = ref(null)
const dataSource = ref([])
const loading = ref(false)
const skeletonLoading = ref(false)
const addGoodsRef = ref(null)interface Pagination {page: numberpageSize: numbertotal: numbercurrent?: numberonChange: FunctionshowSizeChanger: booleanshowQuickJumper: boolean
}const handlePageChange = (page: any, pageSize: any) => {pagination.value.pageSize = pageSizesearchParams.value.pageSize = pageSize
}const pagination = ref<Pagination>({page: 1,pageSize: 12,total: 0,onChange: handlePageChange,showSizeChanger: true,showQuickJumper: true,
})const searchParams = ref<SearchParams>({currentPage: pagination.value.page,pageSize: pagination.value.pageSize,pdrPutAwayTimeNum: 0,fortyBelowPrice: 0,
})interface SearchParams {currentPage: numberpageSize: number[propName: string]: any
}const onChangePage = (page: any, pageSize: any) => {searchParams.value.currentPage = pageskeletonLoading.value = truegetList()
}onMounted(() => {getList()getCateList()
})const getList = async () => {try {loading.value = trueskeletonLoading.value = trueconst { state, data, message: msg } = await phyicalApi.getGoodsList(searchParams.value)if (state == 200) {dataSource.value = data.listpagination.value.total = Number(data.totalCount)} else {message.error(msg)}} catch (error) {message.error('网络请求连接失败~')} finally {loading.value = falsesetTimeout(() => {skeletonLoading.value = false}, 500)}
}const drawOne = (chart: any) => {let option = {xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],},yAxis: {type: 'value',},series: [{data: [120,{value: 200,itemStyle: {color: '#a90000',},},150,80,70,110,130,],type: 'bar',},],}chart.setOption(option)
}const onResize = () => {if (chart.value) {chart.value.dispose()chart.value = echarts.init(oneRef.value)drawOne(chart.value)}
}window.addEventListener('resize', onResize)let dxTokenRef = ref()
const add = () => {dxTokenRef.value.callbackFn()
}const getToken = (e: any) => {console.log(e)
}const getCateList = async () => {try {const { data, state, message: msg } = await phyicalApi.getProductCateList()if (state == 200) {filterList.value = data.map((item: any) => {return {label: item.cateName,id: item.cateId}})filterList.value.unshift({label: "所有类目",id: 0})} else {message.error(msg)}} catch (error) {console.error(error)}
}const filterList = ref([])
const filterSelected = ref(0)
const filterSelectedId = ref(0)const filterClick = (item: any, index: any) => {filterSelected.value = indexfilterSelectedId.value = item.idsearchParams.value.cateId = item.idif (item.id == 0) {delete searchParams.value.cateId}pagination.value.page = 1searchParams.value.currentPage = 1getList()
}let checked1 = ref(false)
let checked2 = ref(false)watch(checked1, (newVal) => {searchParams.value.fortyBelowPrice = newVal ? 1 : 0pagination.value.page = 1searchParams.value.currentPage = 1getList()
})watch(checked2, (newVal) => {searchParams.value.pdrPutAwayTimeNum = newVal ? 1 : 0pagination.value.page = 1searchParams.value.currentPage = 1getList()
})const beforePrice = ref("")
const afterPrice = ref("")import type { SelectProps } from 'ant-design-vue';
const value = ref("")
const options = ref<SelectProps['options']>([{value: '1',label: '描述不符包退',},{value: '2',label: '二十四小时发货',},{value: '3',label: '四十八小时发货',},{value: '4',label: '假货包赔',},
]);const handleChange = (e) => {value.value = e
}const handleSearch = () => {if (value.value) {searchParams.value.serviceAssurance = Number(value.value)}searchParams.value.beforePrice = beforePrice.value * 100searchParams.value.afterPrice = afterPrice.value * 100if (!searchParams.value.beforePrice) {delete searchParams.value.beforePrice}if (!searchParams.value.afterPrice) {delete searchParams.value.afterPrice}pagination.value.page = 1searchParams.value.currentPage = 1getList()
}const handleReset = () => {delete searchParams.value.beforePricedelete searchParams.value.afterPricedelete searchParams.value.serviceAssurancesearchParams.value.currentPage = 1checked1.value = falsechecked2.value = falsebeforePrice.value = ""afterPrice.value = ""value.value = ""pagination.value.page = 1filterClick(filterList.value[0], 0)
}
</script><template><page-container :title="route.meta.title"><a-card ><div class="category-list"><div class="title">分销分类</div><div class="left"><div class="box"><div class="item hiddenText" v-for="(item, index) in filterList":class="{ active: filterSelected === index }" @click="filterClick(item, index)" :key="item.id">{{ item.label }}</div></div></div></div><div class="filter-list"><div class="title">商品信息</div><div class="left"><div class="price-between"><div class="left-price"><a-input-number placeholder="开始价格" v-model:value="beforePrice" style="width: 120px":disabled="loading"></a-input-number></div><div class="line">—</div><div class="right-price"><a-input-number placeholder="结束价格" v-model:value="afterPrice" style="width: 120px":disabled="loading"></a-input-number></div></div><div><a-select ref="select" v-model:value="value" placeholder="服务类型" allowClear style="width: 150px":options="options" @change="handleChange" :disabled="loading"></a-select></div><div class="filter-actions"><a-button @click="handleSearch" type="primary" :loading="loading">查询</a-button><a-button @click="handleReset" type="default" :disabled="loading">重置</a-button></div><div class="checkbox-group"><a-checkbox v-model:checked="checked1" :disabled="loading">40元以下商品</a-checkbox><a-checkbox v-model:checked="checked2" :disabled="loading">新上架商品</a-checkbox></div></div></div><div class="good-list-container"><template v-if="skeletonLoading && !loading"><div class="skeleton-list"><Skeleton v-for="i in 12" :key="i" active /></div></template><template v-else-if="dataSource.length > 0"><div class="good-list"><div class="good-item" v-for="(item, index) in dataSource" :key="index"><Item :info="item"></Item></div></div></template><template v-else><div class="empty-list"><img src="@/assets/empty.png" alt="暂无数据"><div class="empty-text">暂无商品数据</div></div></template></div><div class="pagination-container" v-if="dataSource.length > 0"><a-pagination v-model:current="pagination.page" show-quick-jumper :total="pagination.total":show-total="(total) => `共 ${total} 件商品`" @change="onChangePage" :disabled="loading" /></div></a-card></page-container>
</template><style lang="less" scoped>
.hiddenText {display: inline-block;width: 100px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.good-list-container {min-height: 500px;position: relative;
}.skeleton-list {display: grid;grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));gap: 24px;padding: 16px;
}.good-list {width: 100%;margin: 0 auto;display: grid;grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));gap: 24px;padding: 16px;
}.empty-list {height: 400px;display: flex;flex-direction: column;justify-content: center;align-items: center;color: #999;img {width: 200px;height: auto;margin-bottom: 20px;}.empty-text {font-size: 16px;}
}.good-item {border-radius: 8px;overflow: hidden;border: 1px solid #f0f0f0;background: #fff;transition: all 0.3s;&:hover {box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);transform: translateY(-2px);}
}.filter-list {display: flex;align-items: flex-start;margin: 24px 0;padding: 16px;background: #fafafa;border-radius: 8px;.title {font-size: 14px;color: #666;margin-right: 25px;min-width: 80px;line-height: 32px;}.left {flex: 1;display: flex;align-items: center;flex-wrap: wrap;gap: 16px;.price-between {display: flex;align-items: center;.line {color: #999;margin: 0 10px;}}.filter-actions {display: flex;gap: 8px;}.checkbox-group {display: flex;gap: 16px;margin-left: 16px;}}
}.category-list {display: flex;margin-bottom: 24px;padding: 16px;background: #fafafa;border-radius: 8px;.title {font-size: 14px;color: #666;margin-right: 25px;min-width: 80px;line-height: 32px;}.left {flex: 1;.box {display: flex;align-items: center;flex-wrap: wrap;gap: 8px;.item {padding: 6px 12px;border-radius: 16px;cursor: pointer;border: 1px solid #e8e8e8;color: #666;transition: all 0.3s;font-size: 14px;&:hover {border-color: #1890ff;color: #1890ff;}&.active {background: #1890ff;color: #fff;border-color: #1890ff;}}}}
}.pagination-container {margin-top: 24px;display: flex;justify-content: center;
}a:hover {color: #1890ff;
}
</style>
相关文章:
vue3-andsign 中实现实物电商列表的页面
这里自己做一个代码整理 做了一个实物电商 选品中心的页面 看里面有些效果挺好 这里记录一下 直接粘贴代码了 我自己能看懂 做了一个列表显示 骨架屏等 效果 使用了grid 布局 比媒体查询好使 <script setup lang"ts"> import { ref, onMounted, watch } fro…...

Linux Docker的简介
参考资料 30分钟Docker入门教程 ◀ 本篇博客所有图片皆来自于该视频截图阮一峰 - Docker 入门教程 目录 一. 环境配置时可能会遇到的问题二. 什么是Docker三. 虚拟机 与 Docker 的区别3.1 虚拟机3.2 Docker 四. Docker的基本架构五. Dockerfile 一. 环境配置时可能会遇到的问题…...

极昆仑智慧与数元灵科技达成战略合作
近日,北京极昆仑智慧科技有限公司与北京数元灵科技有限公司正式签署产品级融合战略合作协议,双方将围绕 "AIBI商业智能分析" " Hybrid RAG 大模型问答" 等核心大模型应用,实现技术架构与业务场景的深度集成,…...
如何写一篇基于Spring Boot + Vue + 微信小程序的软件的接口文档
如何写一篇基于Spring Boot Vue 微信小程序的软件的接口文档 下面是一个例子,仅供参考! 基于Spring Boot Vue 微信小程序的博客系统接口文档 技术栈:Spring Boot 3.x Vue 3 Element Plus 微信小程序原生框架 文档版本:v1…...
上位机知识篇---网页端实现
一、网页端基础概念 网页的本质 网页是通过浏览器展示的超文本(HTML)内容,依赖 HTTP/HTTPS 协议 进行数据传输。组成要素: 结构层(HTML):定义页面内容和语义(如标题、段落、列表等&a…...
鼠标的拖动效果
1、变量的设置 let isDragging false; let startX; let startY; let endX; let endY; let box null;isDragging : 表示是否推拽startX、startY:表示起始坐标,相对于元素endX、endY:表示结束坐标,相对于元素box&…...

第四讲:类和对象(下)
1. 再探构造函数 • 之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅ 式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成 员列表ÿ…...
C++ vector容器存储对象和存储指针的区别(vector对象、vector指针)(存储指针时推荐使用智能指针)
文章目录 **1. 内存管理**- **存储对象**:- **存储指针**: **2. 生命周期控制**- **存储对象**:- **存储指针**: **3. 性能差异**- **存储对象**:- **存储指针**: **4. 使用场景**- **选择存储对象的情况**…...
C#和C++在编译过程中的文件区分
1. .h是头文件(Header File) 用来 声明类、函数、常量等。 通常不包含实际实现,只是“定义接口” // 示例:math_utils.h#pragma once int add(int a, int b); //定义函数名2. .cpp是源文件(Source File&…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Dad Jokes(冷笑话卡片)
📅 我们继续 50 个小项目挑战!—— DadJokes 组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/ 豆包翻译确实可以,冷笑话应该属于各类语言比较难理解的…...

Spring AOP执行原理源码解析
对【com.example.demo.TestAspect#aopTest】连接点增加了五个通知 在调用【com.example.demo.A#testAop()】(用户自定义)方法时,Cglib拦截器对其进行了拦截 可以看到执行顺序分别是环绕前置,前置,环绕后置,…...

基于FPGA的超声波显示水位距离,通过蓝牙传输水位数据到手机,同时支持RAM存储水位数据,读取数据。
基于FPGA的超声波显示水位距离 前言一、整体框架二、代码架构1.超声波测距模块2.蓝牙数据发送模块3.数码管数据切换模块4.数码管驱动模块6.串口驱动7.顶层模块8.RAM ip核 仿真相关截图 前言 随着工业化进程的加速和环境保护意识的提升,对水资源管理和水位监测的需求…...
使用swoole作为MQTT客户端并接收实现即时消息推送
环境准备 首先需要安装swoole 可以使用pecl进行安装 ,如 pecl install swool, 注意加上版本号 或者使用构建好的docker镜像,这里使用构建好的 zacksleo/php:7.1-alpine-fpm-swoole 镜像 使用 compose 安装依赖库 composer require jesusslim/mqttcl…...

在Windows下利用LoongArch-toolchain交叉编译Qt
文章目录 0.交叉编译的必要性1.下载交叉编译工具链1.1.直接在Windows下使用mingw(不使用虚拟机)编译(还没成功,无法编译)1.2.在虚拟机中的Ubuntu中进行交叉编译 2.下载qt源码3.编译Qt3.1.创建loongarch64的mkspec3.2.创…...
如何在 React 中监听 div 的滚动事件
在 React 中监听 div 的滚动事件(scroll),可以通过为该 div 添加 onScroll 属性来实现。以下是一个基本的例子: ✅ 示例:监听 div 的滚动事件 import React, { useRef } from react;function ScrollComponent() {cons…...

AIRIOT无人机安防解决方案
随着无人机技术的飞速发展和广泛应用,其在安防领域的价值日益凸显,从关键设施巡检、大型活动安保到边境巡防、应急救援,无人机正成为立体化安防体系不可或缺的“空中哨兵”。然而,无人机安防应用蓬勃发展的同时,其自身…...

华为OD机考 - 水仙花数 Ⅰ(2025B卷 100分)
import java.util.*; public static Integer get(int count,int c){if(count<3||count>7){return -1;}//存储每位数的最高位……最低位int[] arr new int[count];List<Integer> res new ArrayList<>();for(int i(int) Math.pow(10,count-1);i<(int) Math…...
软考 系统架构设计师系列知识点之杂项集萃(81)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(80) 第145题 商业智能是企业对商业数据的搜集、管理和分析的系统过程,主要技术包括()。 A. 数据仓库、联机分析和数据挖掘 B. 数据采集、数据清洗…...

php apache构建 Web 服务器
虚拟机配置流程winsever2016配置Apache、Mysql、php_windows server 2016配置web服务器-CSDN博客 PHP 和 Apache 通过 模块化协作 共同构建 Web 服务器,以下是它们的交互机制和工作流程: 一、核心组件分工 组件角色ApacheWeb …...
Ntfs!ReadIndexBuffer函数分析之nt!CcGetVirtualAddress函数之nt!CcGetVacbMiss
第一部分: NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…...
Vue3 + TypeSrcipt 防抖、防止重复点击实例
需要实现防抖应用场景: 点击【查询】按钮,发送网络请求,等待并接收响应数据 原来点击【查询】的代码: <script setup lang"ts" name"ReagentTransactionsDrawer"> ...... // 查询,没有防…...
SQL进阶之旅 Day 14:数据透视与行列转换技巧
【SQL进阶之旅 Day 14】数据透视与行列转换技巧 开篇 欢迎来到“SQL进阶之旅”系列的第14天!今天我们将探讨数据透视与行列转换技巧,这是数据分析和报表生成中的核心技能。无论你是数据库开发工程师、数据分析师还是后端开发人员,行转列或列…...

打通印染车间“神经末梢”:DeviceNet转Ethernet/IP连接机器人的高效方案
在印染行业自动化升级中,设备联网需求迫切。老旧印染设备多采用Devicenet协议,而新型工业机器人普遍支持Ethernet/IP协议,协议不兼容导致数据交互困难,设备协同效率低、生产监控滞后,成了行业数字化转型的阻碍。本文将…...
Ubuntu挂载本地镜像源(像CentOS 一样挂载本地镜像源)
1.挂载 ISO 镜像 sudo mount -o loop /ubuntu-22.04.5-desktop-amd64.iso /mnt/iso 2.备份现有的软件源配置文件: sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 3.编辑软件源配置文件 编辑 /etc/apt/sources.list sudo nano /etc/apt/sources.l…...

2025-06-02-IP 地址规划及案例分析
IP 地址规划及案例分析 参考资料 Plan for IP addressing - Cloud Adoption Frameworkwww.cnblogs.comimage-hosting/articles at master jonsam-ng/image-hosting 概述 在网络通信中,MAC 地址与 IP 地址分别位于 OSI 模型的数据链路层和网络层,二者协…...

AUTOSAR实战教程--开放式通用DoIP刷写工具OpenOTA开发计划
目录 软件概述 安装与运行 界面说明 3.1 功能区划分 3.2 状态显示 基本操作流程 4.1 DoIP连接配置 4.2 服务配置(刷写流程) 4.3 执行操作 4.4 保存配置 4.5 加载配置 功能详解 5.1 核心功能模块 诊断服务配置 通信设置 文件下载 工具功…...
Vue 学习路线图(从零到实战)
🎯 学习目标:掌握 Vue 并能独立开发中大型项目 ✅ 适合人群:前端初学者、想快速上手做项目的开发者、中小型团队成员 🧭 Vue 学习路线图(从零到实战) 第一阶段:基础语法 核心功能(…...

AI赋能的浏览器自动化:Playwright MCP安装配置与实操案例
以下是对Playwright MCP的简单介绍: Playwright MCP 是一个基于 Playwright 的 MCP 工具,提供浏览器自动化功能不要求视觉模型支持,普通的文本大语言模型就可以通过结构化数据与网页交互支持多种浏览器操作,包括截图、点击、拖动…...
AI编程助手入门指南:GitHub Copilot、Cursor与Claude的安装与基础使用
🔥 AI编程助手入门指南:GitHub Copilot、Cursor与Claude的安装与基础使用 你是否曾幻想过拥有一个24小时在线的编程搭档?它能理解你的思路、自动补全代码、解释复杂逻辑,甚至帮你调试错误?如今,这个幻想已成…...
Android 线性布局中常见的冲突属性总结
1. gravity vs layout_gravity 冲突原因:两者作用对象不同,混用会导致行为异常。 区别: android:gravity:父容器的属性,控制子元素在容器内的对齐方式。android:layout_gravity:子元素的属性,控…...