【UniApp开发小程序】悬浮按钮+出售闲置商品+商品分类选择【基于若依管理系统开发】

文章目录

  • 界面效果
  • 界面实现
    • 悬浮按钮实现
    • 商品分类选择界面
      • 使元素均匀分布
    • 闲置商品描述信息填写界面
      • 价格校验

界面效果

【悬浮按钮】

在这里插入图片描述
【闲置商品描述信息填写界面】

在这里插入图片描述
【商品分类选择界面】

在这里插入图片描述
【分类选择完成】
在这里插入图片描述

界面实现

悬浮按钮实现

悬浮按钮漂浮于页面之上,等页面滑动时,悬浮按钮的位置相对于屏幕不会改变

【悬浮按钮组件】

<template><div class="floating-button" @click="onClick"><slot><!-- 这里可以放置默认的按钮样式等 --></slot></div>
</template><script>export default {name: 'FloatButton',props: {},data() {return {};},mounted() {},methods: {onClick() {this.$emit('click');}},computed: {}};
</script><style>.floating-button {display: flex;justify-content: center;align-items: center;width: 58px;height: 58px;border-radius: 50%;background-color: #007aff;color: #fff;position: fixed;right: 20rpx;bottom: 20rpx;}/* 按钮点击之后会产生偏移 */.floating-button:active {transform: translate(0, 2px);}
</style>

【在其他界面中使用】

因为组件中使用了插槽,可以在该组件中插入其他组件

<FloatButton @click="cellMyProduct()"><u--image :src="floatButtonPic" shape="circle" width="60px" height="60px"></u--image>
</FloatButton>

示例中,我给浮动按钮的插槽中添加了图片组件,图片使用项目静态资源中的图片

在这里插入图片描述

data() {return {title: 'Hello',floatButtonPic: require("@/static/cellLeaveUnused.png"),}},

商品分类选择界面

分类数据的格式如下

{"msg": "productCategoryItemVoList","code": 200,"data": [{"id": 5,"name": "数码产品","children": [{"id": 10,"name": "电脑","children": [{"id": 12,"name": "台式机","children": [],"icon": "a","sort": 1,"description": "a"},{"id": 13,"name": "笔记本","children": [],"icon": "a","sort": 1,"description": "a"}],"icon": "a","sort": 1,"description": "a"},{"id": 11,"name": "手机","children": [{"id": 14,"name": "老人机","children": [],"icon": "a","sort": 1,"description": "a"},{"id": 15,"name": "智能手机","children": [],"icon": "a","sort": 1,"description": "a"}],"icon": "a","sort": 1,"description": "a"}],"icon": "a","sort": 1,"description": "a"},{"id": 6,"name": "服装","children": [],"icon": "a","sort": 1,"description": "a"},{"id": 7,"name": "教育用品","children": [],"icon": "a","sort": 1,"description": "a"},{"id": 8,"name": "食品","children": [],"icon": "a","sort": 1,"description": "a"}]
}
<template><view class="container"><u-toast ref="uToast"></u-toast><view class="titleView"><view class="controlButton" @click="back"><u-icon name="arrow-left" color="#ffffff"></u-icon>上一级</view><text>{{getCategoryLayerName()}}</text><view class="controlButton" @click="commit">完成<u-icon name="checkmark" color="#ffffff"></u-icon></view></view><view style="height: 20px;"></view><u-empty v-if="curLayerCategoryData.length==0" mode="search" texColor="#ffffff" iconSize="180" iconColor="#2b92ff" text="分类选择完成,请点击右上角的完成" textColor="#2b92ff" textSize="18" marginTop="30"></u-empty><u-list @scrolltolower="scrolltolower" v-else><u-list-item v-for="(category, index) in curLayerCategoryData" :key="index"><u-cell :title="category.name" @click="selectCurCategory(category)"><u-avatar slot="icon" shape="square" size="35" :src="category.icon"customStyle="margin: -3px 5px -3px 0"></u-avatar></u-cell></u-list-item></u-list></view>
</template><script>import {getProductCategoryTree} from "@/api/market/category.js";export default {data() {return {categoryNameList: ["分类未选择"],categoryTreeData: [],// 当前层级分类数据curLayerCategoryData: [],// 已经选择的层级分类数据haveSelectLayerCategoryData: [],// 层级layer: 0,// 商品所属分类productCategoryId: 0,}},created() {this.getProductCategoryTree();},methods: {getCategoryLayerName() {let str = '';for (let i = 0; i < this.categoryNameList.length - 1; i++) {str += this.categoryNameList[i] + '/';}return str + this.categoryNameList[this.categoryNameList.length - 1];},/*** 查询商品分类的树形结构数据*/getProductCategoryTree() {getProductCategoryTree().then(res => {// console.log("getProductCategoryTree:" + JSON.stringify(res));this.categoryTreeData = res.data;this.curLayerCategoryData = this.categoryTreeData;})},/*** 选择分类* @param {Object} category 当前选择的分类*/selectCurCategory(category) {if (this.layer == 0) {this.categoryNameList = [];}this.categoryNameList.push(category.name);this.productCategoryId = category.id;this.layer++;// 将当前层的数据设置进haveSelectLayerCategoryDatathis.haveSelectLayerCategoryData.push(this.curLayerCategoryData);this.curLayerCategoryData = category.children;if (this.curLayerCategoryData.length == 0) {this.$refs.uToast.show({type: 'success',message: "分类选择完成,请提交数据"})}},/*** 返回上一级*/back() {if (this.layer == 0) {this.$refs.uToast.show({type: 'warning',message: "已经是第一层级,无法返回上一级"})} else {this.layer--;this.curLayerCategoryData = this.haveSelectLayerCategoryData[this.haveSelectLayerCategoryData.length -1];// 删掉最后一条数据this.haveSelectLayerCategoryData.splice(this.haveSelectLayerCategoryData.length - 1, 1);}},/*** 提交分类数据*/commit() {if (this.curLayerCategoryData.length != 0) {this.$refs.uToast.show({type: 'error',message: "分类还没有选择完成,请继续选择"})} else {uni.setStorageSync("productCategoryId", this.productCategoryId);uni.setStorageSync("categoryNameList", this.categoryNameList);uni.navigateBack();}}}}
</script><style lang="scss">.container {background: #F6F6F6;min-height: 100vh;padding: 20rpx;.titleView {display: flex;justify-content: space-between;align-items: center;background: #2b92ff;color: #ffffff;border-radius: 4px;.controlButton {// width: 100px;display: flex;// border: #2b92ff 1px solid;padding: 10px;}}}
</style>

使元素均匀分布

使用下面的代码,可以让元素在组件中的子组件在组件中横向均匀分布,效果如下图

在这里插入图片描述

<view class="titleView"><view class="controlButton" @click="back"><u-icon name="arrow-left" color="#ffffff"></u-icon>上一级</view><text>{{getCategoryLayerName()}}</text><view class="controlButton" @click="commit">完成<u-icon name="checkmark" color="#ffffff"></u-icon></view>
</view>
display: flex;
justify-content: space-between;

闲置商品描述信息填写界面

<template><view class="container"><u-toast ref="uToast"></u-toast><view class="content"><view class="item"><view class="labelName">商品名称</view><u--input placeholder="请输入商品名称" border="surround" v-model="product.name"></u--input></view><u-divider text="商品描述和外观"></u-divider><!-- 商品描述 --><u--textarea v-model="product.descripption" placeholder="请输入商品描述" height="150"></u--textarea><!-- 图片上传 --><view><imageUpload v-model="product.picList" maxCount="9"></imageUpload></view><u-divider text="分类选择/自定义标签"></u-divider><!-- 分类选择/自定义标签 --><view class="item"><view class="labelName">分类</view><view class="selectTextClass" @click="selectCategory">{{getCategoryLayerName()}}</view></view><!-- 商品的属性 新度 功能完整性 --><view class="item"><view class="labelName">成色</view><view class="columnClass"><view :class="product.fineness==index?'selectTextClass':'textClass'"v-for="(finessName,index) in finenessList" :key="index" @click="changeFineness(index)">{{finessName}}</view></view></view><view class="item"><view class="labelName">功能状态</view><view class="columnClass"><view :class="product.functionalStatus==index?'selectTextClass':'textClass'"v-for="(functionName,index) in functionList" :key="index"@click="changeFunctionalStatus(index)">{{functionName}}</view></view></view><u-row customStyle="margin-bottom: 10px"><u-col span="5"><view class="item"><view class="labelName">数量</view><u--input placeholder="请输入商品数量" border="surround" v-model="product.number"></u--input></view></u-col><u-col span="7"><view class="item"><view class="labelName">计量单位</view><u--input placeholder="请输入计量单位" border="surround" v-model="product.unit"></u--input></view></u-col></u-row><!-- 价格 原价 现价 --><u-divider text="价格"></u-divider><u-row customStyle="margin-bottom: 10px"><u-col span="6"><view class="item"><view class="labelName">原价</view><u-input placeholder="请输入原价" border="surround" v-model="product.originalPrice" color="#ff0000"@blur="originalPriceChange"><u--text text="¥" slot="prefix" margin="0 3px 0 0" type="error"></u--text></u-input></view></u-col><u-col span="6"><view class="item"><view class="labelName">出售价格</view><u-input placeholder="请输入出售价格" border="surround" v-model="product.price" color="#ff0000"@blur="priceChange"><u--text text="¥" slot="prefix" margin="0 3px 0 0" type="error"></u--text></u-input></view></u-col></u-row><u-button text="出售" size="large" type="primary" @click="uploadSellProduct"></u-button></view></view>
</template><script>import imageUpload from "@/components/ImageUpload/ImageUpload.vue";import {uploadSellProduct} from "@/api/market/prodct.js"export default {components: {imageUpload},onShow: function() {let categoryNameList = uni.getStorageSync("categoryNameList");if (categoryNameList) {this.categoryNameList = categoryNameList;this.product.productCategoryId = uni.getStorageSync("productCategoryId");uni.removeStorageSync("categoryNameList");uni.removeStorageSync("productCategoryId");}},data() {return {product: {name: '',descripption: '',picList: [],productCategoryId: 0,number: 1,unit: '',isContribute: 0,originalPrice: 0.00,price: 0.00,// 成色fineness: 0,// 功能状态functionalStatus: 0,brandId: 0},value: 'dasdas',categoryNameList: ["选择分类"],finenessList: ["全新", "几乎全新", "轻微使用痕迹", "明显使用痕迹", "外观破损"],functionList: ["功能完好无维修", "维修过,可正常使用", "有小问题,不影响使用", "无法正常使用"]}},methods: {getCategoryLayerName() {let str = '';for (let i = 0; i < this.categoryNameList.length - 1; i++) {str += this.categoryNameList[i] + '/';}return str + this.categoryNameList[this.categoryNameList.length - 1];},/*** 价格校验* @param {Object} price 价格*/priceVerify(price) {if (isNaN(price)) {this.$refs.uToast.show({type: 'error',message: "输入的价格不是数字,请重新输入"})return false;}if (price < 0) {this.$refs.uToast.show({type: 'error',message: "输入的价格不能为负数,请重新输入"})return false;}if (price.toString().indexOf('.') !== -1 && price.toString().split('.')[1].length > 2) {this.$refs.uToast.show({type: 'error',message: "输入的价格小数点后最多只有两位数字,请重新输入"})return false;}return true;},originalPriceChange() {let haha = this.priceVerify(this.product.originalPrice);if (haha === false) {console.log("haha:" + haha);this.product.originalPrice = 0.00;console.log("this.product" + JSON.stringify(this.product));}},priceChange() {if (this.priceVerify(this.product.price) === false) {this.product.price = 0.00;}},/*** 修改成色* @param {Object} index*/changeFineness(index) {this.product.fineness = index;},/*** 修改功能状态* @param {Object} index*/changeFunctionalStatus(index) {this.product.functionalStatus = index;},/*** 上传闲置商品*/uploadSellProduct() {uploadSellProduct(this.product).then(res => {this.$refs.uToast.show({type: 'success',message: "您的商品已经发布到平台"})setTimeout(() => {uni.reLaunch({url: "/pages/index/index"})}, 1500)})},/*** 选择分类*/selectCategory() {uni.navigateTo({url: "/pages/sellMyProduct/selectCategory"})}}}
</script><style lang="scss">.container {background: #F6F6F6;min-height: 100vh;padding: 20rpx;.content {background: #ffffff;padding: 20rpx;.item {display: flex;align-items: center;height: 50px;margin-bottom: 5px;.labelName {width: 70px;margin-right: 10px;}.textClass {display: inline;background: #F7F7F7;padding: 10px;margin-right: 15px;border-radius: 5px;}.selectTextClass {display: inline;background: #2B92FF;padding: 10px;margin-right: 15px;border-radius: 5px;color: #ffffff;font-weight: bold;}.columnClass {// height: 50px;display: flex;align-items: center;width: calc(100% - 70px);overflow-x: auto;// // 让内容只有一行white-space: nowrap;}.columnClass::-webkit-scrollbar {background-color: transparent;/* 设置滚动条背景颜色 */// width: 0px;height: 0px;}}}}
</style>

价格校验

价格是商品比较关键的属性,一定要确保其数据没有问题,所以在用户提交之前一定要对商品的价格进行校验,防止用户乱输或者输错数据,这里对价格有如下规定:

  • 输入的价格必须是数字,不可以是字符串
  • 输入的价格必须是正数,不可以是负数
  • 输入的价格的小数点有限制,不可以输入太多小数点

那么校验应该在什么时候触发呢?本示例在用户输入结束之后,手指离开输入组件时触发,即当元素失去焦点时触发,使用的是@blur事件

/*** 价格校验
* @param {Object} price 价格*/
priceVerify(price) {if (isNaN(price)) {this.$refs.uToast.show({type: 'error',message: "输入的价格不是数字,请重新输入"})return false;}if (price < 0) {this.$refs.uToast.show({type: 'error',message: "输入的价格不能为负数,请重新输入"})return false;}if (price.toString().indexOf('.') !== -1 && price.toString().split('.')[1].length > 2) {this.$refs.uToast.show({type: 'error',message: "输入的价格小数点后最多只有两位数字,请重新输入"})return false;}return true;
},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencv-20 深入理解HSV 色彩空间(通过指定,标记颜色等来拓展ROI区域)

RGB 色彩空间是一种被广泛接受的色彩空间&#xff0c;但是该色彩空间过于抽象&#xff0c;我们不能够直接通过其值感知具体的色彩。 我们更习惯使用直观的方式来感知颜色&#xff0c;HSV 色彩空间提供了这样 的方式。 通过 HSV色彩空间&#xff0c;我们能够更加方便地通过色调、…

Python补充笔记5-模块化、文件

目录 一、模块 二、模块的导入 三、python中的包​编辑 四、常用的内容模块 五、第三方模块的安装与使用 六、编码格式的介绍 七、文件读写的原理 八、常用的文件打开模式 ​九、文件对象的常用方法 十、with语句​编辑 十一、os模块的常用函数 十二、os.path模块的常用方法​编…

今天学学消息队列RocketMQ:消息类型

RocketMQ支持的消息类型有三种&#xff1a;普通消息、顺序消息、延时消息、事务消息。以下内容的代码部分都是基于rocketmq-spring-boot-starter做的。 普通消息 普通消息是一种无序消息&#xff0c;消息分布在各个MessageQueue当中&#xff0c;以保证效率为第一使命。这种消息…

Staples Drop Ship EDI 需求分析

Staples 是一家美国零售公司&#xff0c;总部位于马萨诸塞州弗拉明汉&#xff0c;主要提供支持工作和学习的产品和服务。该公司于 1986 年在马萨诸塞州布莱顿开设了第一家门店。到 1996 年&#xff0c;该公司已跻身《财富》世界 500 强&#xff0c;后来又收购了办公用品公司 Qu…

MySQL优化(面试)

文章目录 通信优化查询缓存语法解析及查询优化器查询优化器的策略 性能优化建议数据类型优化索引优化 优化关联查询优化limit分页对于varchar end mysql查询过程: 客户端向MySQL服务器发送一条查询请求服务器首先检查查询缓存&#xff0c;如果命中缓存&#xff0c;则立刻返回存…

初识mysql数据库之事务的概念及操作

目录 一、数据库多客户端访问问题 1. 数据库的CURD无限制带来的问题 2. 如何解决CURD导致的问题 二、事务的概念 1. 什么是事务 2. 事务的四个属性 3. mysql对事务的管理 4. 为什么会有事务 5. 事务的版本支持 三、事务的操作 1. 事务提交方式 2. 事务操作的准备工…

哈工大计算机网络课程局域网详解之:无线局域网

哈工大计算机网络课程局域网详解之&#xff1a;无线局域网 文章目录 哈工大计算机网络课程局域网详解之&#xff1a;无线局域网IEEE 802.11无线局域网802.11体系结构802.11&#xff1a;信道与AP关联 本节介绍一下平时经常使用的一个无线局域网技术&#xff0c;也就是通常我们使…

3ds MAX绘制茶壶

综合一下之前的内容画个茶壶 长方形&#xff0c;然后转化为可编辑多边形&#xff0c;添加节点并设置圆角&#xff0c;如下图 车削生成一个圆环&#xff0c;其实这一步也可以用一个圆柱体和两个圆角圆柱体解决 效果如下&#xff1a; 茶壶的底座绘制好了 接下来是茶壶的上半边 …

TypeScript -- 函数

文章目录 TypeScript -- 函数JS -- 函数的两种表现形式函数声明函数的表达式es6 箭头函数 TS -- 定义一个函数TS -- 函数声明使用接口(定义)ts 定义参数可选参数写法 -- ?的使用TS函数 -- 设置剩余参数函数重载 TypeScript – 函数 JS – 函数的两种表现形式 我们熟知js有两…

history命令:显示命令执行时间

1.修改配置文件 vim /etc/profile 添加内容 export HISTTIMEFORMAT"%Y-%m-%d %H:%M:%S " ​ #注意&#xff1a;在末尾的“引号”与“S”之间&#xff0c;加入一位空格&#xff0c;将日期时间和历史命令用空格相隔开来。 你也可以换一种清晰的形式&#xff0c;效果…

实验三 贪心算法

实验三 贪心算法 迪杰斯特拉的贪心算法实现 优先队列等 1.实验目的 1、掌握贪心算法的基本要素 &#xff1a;最优子结构性质和贪心选择性质 2、应用优先队列求单源顶点的最短路径Dijkstra算法&#xff0c;掌握贪心算法。 2.实验环境 Java 3.问题描述 给定带权有向图G (V…

背包问题求具体方案数问题--板子题

12. 背包问题求具体方案 - AcWing题库 思路&#xff1a;先将v[i]和w[i]先输入进去&#xff0c;然后我们进行倒叙dp&#xff0c;这个做的目的就是为了后边我们为了匹配确定路径做好准备&#xff0c;如果我们倒叙输入进去&#xff0c;我们再正序的时候就可以用推导式来进行路径输…

DevOps(四)

CD(二) 1. CDStep 1 - 上传代码Step 2 - 下载代码Step 3 - 检查代码Step 4 - 编译代码Step 5 - 上传仓库Step 6 - 下载软件Step 7 - 制作镜像Step 8 - 上传镜像Step 9 - 部署服务2. 整体预览2.1 预览1. 修改代码2. 查看sonarqube检查结果3. 查看nexus仓库4. 查看harbor仓库5.…

Hadoop简介以及集群搭建详细过程

Hadoop简介以及集群搭建详细过程 hadoop集群简介hadoop部署模式Hadoop集群安装1.集群角色规划2.服务器基础环境准备3.上传安装包hadoop安装包目录结构5.编辑hadoop配置文件6.分发安装包7.配置hadoop环境变量8.NameNode format(格式化操作) hadoop集群启动关闭-手动逐个进程启停…

【低代码专题方案】使用iPaaS平台下发数据,快捷集成MDM类型系统

01 场景背景 伴随着企业信息化建设日趋完善化、体系化&#xff0c;使用的应用系统越来越多&#xff0c;业务发展中沉淀了大量数据。主数据作为数据治理中枢&#xff0c;保存大量标准数据库&#xff0c;如何把庞大的数据下发到各个业务系统成了很棘手的问题。 传统的数据下发方…

android app控制ros机器人一

android开发app&#xff0c;进而通过控制ros机器人&#xff0c;记录开发过程 查阅资料&#xff1a; rosjava使用较多&#xff0c;已经开发好的app也有开源的案例 rosjava GitHub https://github.com/ros-autom/RobotCA https://github.com/ROS-Mobile/ROS-Mobile-Android…

Pandas时序数据分析实践—概述

时序数据&#xff0c;作为一种时间上有序的数据形式&#xff0c;无疑是我们日常生活中最常见的数据类型之一。它记录了事件、现象或者过程随时间的变化&#xff0c;是对于许多实际场景的忠实反映。而在众多时序数据的应用领域中&#xff0c;跑步训练记录莫过于是一项令人着迷的…

亲测解决Git inflate: data stream error (incorrect data check)

Git inflate: data stream error (incorrect data check) error: unable to unpack… 前提是你的repository在github等服务器或者其他路径有过历史备份/副本&#xff0c;不要求是最新版本的&#xff0c;只要有就可能恢复你做的所有工作。 执行git fsck --full检查损坏的文件 在…

《TCP IP网络编程》第十一章

第 11 章 进程间通信 11.1 进程间通信的基本概念 通过管道实现进程间通信&#xff1a; 进程间通信&#xff0c;意味着两个不同的进程中可以交换数据。下图是基于管道&#xff08;PIPE&#xff09;的进程间通信的模型&#xff1a; 可以看出&#xff0c;为了完成进程间通信&…

数据决定AIGC的高度,什么又决定着数据的深度?

有人曾言&#xff0c;数据决定人工智能发展的天花板。深以为然。 随着ChatGPT等AIGC应用所展现出的强大能力&#xff0c;人们意识到通用人工智能的奇点正在来临&#xff0c;越来越多的企业开始涌入这条赛道。在AIGC浪潮席卷全球之际&#xff0c;数据的重要性也愈发被业界所认同…