uniapp-商城-68-shop(1-商品列表,获取数据,utils、tofixed 、parseInt的使用)
通过后台的商品添加,可以增加商品,这里前端页面可以读取商品数据库中数据,进行展示。包含数据不同区域的数据展示,这里我们的界面分为左右两块,但是左右需要进行协同。再前面的布局中,做了分析。
这里主要是对数据的获取和展示,进行整理,修改微小的差异。满足页面的展示。
本文介绍了商品数据获取与展示的实现过程。系统通过云对象(green-mall-goods)获取商品数据,前端分为左右两栏协同展示。左侧显示商品分类列表,右侧展示商品详情,包括图片、名称、价格、折扣等信息。关键实现包括:1)使用uniCloud.importObject导入云对象获取数据;2)通过异步方法getGoodsData获取商品列表;3)采用公共工具函数处理价格格式转换(priceFormat)和折扣计算(discount);4)使用scroll-view实现滚动展示,并添加滑动动画效果。组件化开发中,商品项(productItem)封装了图片展示、价格显示、规格选择等功能模块,提升代码复用性。
1、在shop页面获取数据
使用云对象的方法,获取数据。导入云对象。
const goodsCloudObj = uniCloud.importObject("green-mall-goods", {
"customUI": true //每一次都会有一个提示加载,true 就是不显示加载提示弹窗
})
2、删除shop中的测试数据
注释掉前期的测试数据 datalist
3、添加获取数据的方法,并在onload中调用,赋值给空数组 datalist
3.1 添加获取数据的方法,赋值给datalist
//获取所有的商品
async getGoodsData() {
let res = await goodsCloudObj.getList();
// console.log(res);
this.dataList = res;
this.setNumValue()
},
这里主要是要添加一个值到我们的商品中,本身商品中是没有这个值的,然而步进器的numvalue中又需要这样一个值,所以我们加一个显示为0.不然就是没有这个值,这个值后面还要修改。
setNumValue(){
this.dataList.forEach((item,index)=>{
item.proGroup.forEach((child,idx)=>{
// this.dataList[index].proGroup[idx].numvalue=0 也可以写成下面的样子
this.$set(this.dataList[index].proGroup[idx],"numvalue",0)
})
}) }
3.2 在onload 中调用方法,实现进入页面就获取数据
async onLoad() {
await this.getGoodsData() //异步操作同步化,是便于后面高度计算以及右侧导航时提示标识显示 leftscorll 中after能正确显示,没有同步,就有可能显示不出来
// this.getHeightArr();//这个是渲染才会执行,但是这里还没有渲染完
this.$nextTick(() => {
this.getHeightArr(); //这个是渲染才会执行,$nextTick是等渲染完在获取高度数组值
})
},
4、将获取到数据修改到页面
4.1 左侧数据展示:{{item.name}}
<!-- 货架滑动 --><view class="leftscroll"><scroll-view scroll-y="true" class="Conent" :scroll-top="leftScrollValue"><view class="navitem" :class="index==navIdex?'active':''" v-for="item,index in datalist":key="item.id" @click="clickNav(index)">{{item.name}}</view></scroll-view></view>
4.2 右侧数据展示:item.proGroup,以前是item.children
这里就涉及到组件productItem
<!-- 下面是滚动栏目 --><!-- :scroll-top="rightScrollValue" 是滚动条位置 后面rightScrollValue是个变量 使用v-bind 就是加:--><!-- scroll-with-animation 滑动动画,避免太生硬 --><!-- @scroll="rightScrollEnt" 监听右侧的滚动事件 --><scroll-view scroll-y="true" class="Conent" :scroll-top="rightScrollValue" scroll-with-animation@scroll="rightScrollEnt"><view class="productView" v-for="item,index in datalist" :key="item.id"><u-sticky customNavHeight=0 zIndex="2"><!-- 这就是吸顶,但是我们自己取消了导航,需要设置一个值 customNavHeight 导航栏高度,自定义导航栏时,需要传入此值 --><view class="producttitle"><!-- 这里需要吸顶,分类的吸顶 --><!-- 使用的是uview的sticky 产品类名,分类的 -->{{item.name}}</view></u-sticky><view class="productcontent" v-for="childrenItem,index2 in item.proGroup":key="childrenItem.id"><view class="productitem"><productItem :item="childrenItem"></productItem></view></view></view></scroll-view>
4.3 商品展示组件 productItem
4.3.1商品图片的展示
<view class="pic">
<!-- 组件的image给一个标签名 不然小程序报错 -->
<image class="img" :src="item.thumb[0].url" mode="aspectFill"></image>
<!-- aspectFill 全部显示 -->
</view>
4.3.2 商品内容的展示,包含名称、价格、折扣、规格选择/购物步进器
这里涉及到 {{item.name}}
原价:
<view class="big" v-if="item.before_price"> ¥{{priceFormat(item.before_price)}}</view>
涉及的函数 priceFormat ---见 5.1
现价:
<view class="small">低至¥{{priceFormat(item.price)}} </view>
折扣:
涉及的函数discount ---见 5.2
<view class="discount" v-if="item.before_price && discount(item.price,item.before_price)">{{discount(item.price,item.before_price)}}折 </view>
<view class="text"><view class="title"><!-- 产品标题有很多字母,这个时间就需要进行一行显示,不完全的就省略号 -->{{item.name}}</view><view class="price"><!-- 没有原价不显示 --><view class="big" v-if="item.before_price">¥{{priceFormat(item.before_price)}}</view><view class="small">低至¥{{priceFormat(item.price)}}</view></view><!-- 没有原价,或者折扣为0的就不用显示折扣 --><view class="discount" v-if="item.before_price && discount(item.price,item.before_price)">{{discount(item.price,item.before_price)}}折</view><view class="numbox" v-if="btnState"><!-- 数据中没有产品属性sku,那属性长度为0就不显示选规格,显示步进器 --><view class="skuSelect" v-if="item.sku_select.length" @click.stop="selectSpecs">选规格</view><view class="uNum" v-else><!-- 步进器 三部分 左中右三部分 --><pro-num-box :item="item"></pro-num-box></view></view></view>
4.3.3 公共文件中函数使用 (公共方法在 5章)
1.要导入 公共文件中的工具
import {
priceFormat,
discount
} from "@/utils/tools.js" //导入公共方法,并再方法中声明,就可以直接用了
2、要在方法中声明
methods: {
//声明那个公共方法,变成了this.priceFormat的方法,可以直接用
priceFormat,
discount,
3 进行使用,就和在本地定义的方法一样使用
具体见 4.3.2
5 公共utils 函数的涉及和使用
5.1、建一个公共文件夹utils,然后建立一个tools.js文件
5.2、priceFormat 价格转换(分到元,并保留两位,tofixed )
涉及的函数就是 tofixed 保留两位数据;
//公共的方法
//将价格初始化 将分转为元
export function priceFormat(num){
return (num/100).toFixed(2) //将分转为元,并保留两位,注意这里的括号必须要,不然报错 (num/100)
}
5.3 discount 折扣计算 (parseInt)
涉及的函数 parseInt 取整;
//输出折扣
export function discount(num1,num2){
return parseInt( (num1/num2)*100 ) //将现价除以原价,乘以100 ,并进行取整,就等于几折
}