今日学习内容
- 商品详情页
商品详情页
1、定义类型
import type { GoodsItem } from './global'
/** 商品信息 */
export type GoodsResult = {
/** id */
id: string
/** 商品名称 */
name: string
/** 商品描述 */
desc: string
/** 当前价格 */
price: number
/** 原价 */
oldPrice: number
/** 商品详情: 包含详情属性 + 详情图片 */
details: Details
/** 主图图片集合[ 主图图片链接 ] */
mainPictures: string[]
/** 同类商品[ 商品信息 ] */
similarProducts: GoodsItem[]
/** sku集合[ sku信息 ] */
skus: SkuItem[]
/** 可选规格集合备注[ 可选规格信息 ] */
specs: SpecItem[]
/** 用户地址列表[ 地址信息 ] */
userAddresses: AddressItem[]
}
/** 商品详情: 包含详情属性 + 详情图片 */
export type Details = {
/** 商品属性集合[ 属性信息 ] */
properties: DetailsPropertyItem[]
/** 商品详情图片集合[ 图片链接 ] */
pictures: string[]
}
/** 属性信息 */
export type DetailsPropertyItem = {
/** 属性名称 */
name: string
/** 属性值 */
value: string
}
/** sku信息 */
export type SkuItem = {
/** id */
id: string
/** 库存 */
inventory: number
/** 原价 */
oldPrice: number
/** sku图片 */
picture: string
/** 当前价格 */
price: number
/** sku编码 */
skuCode: string
/** 规格集合[ 规格信息 ] */
specs: SkuSpecItem[]
}
/** 规格信息 */
export type SkuSpecItem = {
/** 规格名称 */
name: string
/** 可选值名称 */
valueName: string
}
/** 可选规格信息 */
export type SpecItem = {
/** 规格名称 */
name: string
/** 可选值集合[ 可选值信息 ] */
values: SpecValueItem[]
}
/** 可选值信息 */
export type SpecValueItem = {
/** 是否可售 */
available: boolean
/** 可选值备注 */
desc: string
/** 可选值名称 */
name: string
/** 可选值图片链接 */
picture: string
}
/** 地址信息 */
export type AddressItem = {
/** 收货人姓名 */
receiver: string
/** 联系方式 */
contact: string
/** 省份编码 */
provinceCode: string
/** 城市编码 */
cityCode: string
/** 区/县编码 */
countyCode: string
/** 详细地址 */
address: string
/** 默认地址,1为是,0为否 */
isDefault: number
/** 收货地址 id */
id: string
/** 省市区 */
fullLocation: string
}
2、定义接口
import type { GoodsResult } from '@/types/goods'
import { http } from '@/utils/http'
export const getGoodsDetailApi = (id: string) => {
return http<GoodsResult>({
method: 'GET',
url: '/goods',
data: { id: id },
})
}
3、组件代码
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { getGoodsDetailApi } from '@/services/goods'
import { ref } from 'vue'
import type { GoodsResult } from '@/types/goods'
import ServicePannel from './components/ServicePannel.vue'
import AddressPanel from './components/AddressPanel.vue'
import GoodsSkeleton from './components/GoodsSkeleton.vue'
const goodsInfo = ref<GoodsResult>()
//获取商品详情
const getGoodsInfo = async () => {
const res = await getGoodsDetailApi(query.id)
goodsInfo.value = res.result
}
//启动骨架屏
const isLoading = ref(false)
onLoad(() => {
isLoading.value = true
getGoodsInfo()
isLoading.value = false
})
// uniapp 获取页面参数
const query = defineProps<{
id: string
}>()
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
//高亮的指示点
const activeIndex = ref(0)
//当swiper下标发生变化时出发
const onChange: UniHelper.SwiperOnChange = (ev) => {
// console.log(ev.detail?.current)
activeIndex.value = ev.detail!.current
}
const onPreviewImage = (url: string) => {
uni.previewImage({
urls: goodsInfo.value!.mainPictures,
current: url,
})
}
const popup = ref<{
open: (type?: UniHelper.UniPopupType) => void
close: () => void
}>()
const isAddress = ref<0 | 1>(0)
const openPopup = (isAddr: 0 | 1) => {
isAddress.value = isAddr
popup.value?.open()
}
</script>
<template>
<GoodsSkeleton v-if="isLoading" />
<scroll-view scroll-y class="viewport" v-else>
<!-- 基本信息 -->
<view class="goods">
<!-- 商品主图 -->
<view class="preview">
<swiper circular @change="onChange">
<swiper-item
@click="onPreviewImage(item)"
v-for="item in goodsInfo?.mainPictures"
:key="item"
>
<image mode="aspectFill" :src="item" />
</swiper-item>
</swiper>
<view class="indicator">
<text class="current">{{ activeIndex + 1 }}</text>
<text class="split">/</text>
<text class="total">{{ goodsInfo?.mainPictures.length }}</text>
</view>
</view>
<!-- 商品简介 -->
<view class="meta">
<view class="price">
<text class="symbol">¥</text>
<text class="number">{{ goodsInfo?.price }}</text>
</view>
<view class="name ellipsis">{{ goodsInfo?.name }} </view>
<view class="desc"> {{ goodsInfo?.desc }} </view>
</view>
<!-- 操作面板 -->
<view class="action">
<view class="item arrow">
<text class="label">选择</text>
<text class="text ellipsis"> 请选择商品规格 </text>
</view>
<view class="item arrow" @tap="openPopup(1)">
<text class="label">送至</text>
<text class="text ellipsis"> 请选择收获地址 </text>
</view>
<view class="item arrow" @tap="openPopup(0)">
<text class="label">服务</text>
<text class="text ellipsis"> 无忧退 快速退款 免费包邮 </text>
</view>
</view>
</view>
<uni-popup ref="popup" type="bottom" background-color="#fff">
<ServicePannel v-show="isAddress === 0" @close="popup?.close" />
<AddressPanel v-show="isAddress === 1" @close="popup?.close" />
</uni-popup>
<!-- 商品详情 -->
<view class="detail panel">
<view class="title">
<text>详情</text>
</view>
<view class="content">
<view class="properties">
<!-- 属性详情 -->
<view class="item" v-for="item in goodsInfo?.details.properties" :key="item.name">
<text class="label">{{ item.name }}</text>
<text class="value">{{ item.value }}</text>
</view>
</view>
<!-- 图片详情 -->
<image
:key="item"
v-for="item in goodsInfo?.details.pictures"
mode="widthFix"
:src="item"
></image>
</view>
</view>
<!-- 同类推荐 -->
<view class="similar panel">
<view class="title">
<text>同类推荐</text>
</view>
<view class="content">
<navigator
v-for="item in goodsInfo?.similarProducts"
:key="item.id"
class="goods"
hover-class="none"
:url="`/pages/goods/goods?id=${item.id}`"
>
<image class="image" mode="aspectFill" :src="item.picture"></image>
<view class="name ellipsis">{{ item.name }}</view>
<view class="price">
<text class="symbol">¥</text>
<text class="number">{{ item.price }} </text>
</view>
</navigator>
</view>
</view>
</scroll-view>
<!-- 用户操作 -->
<view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
<view class="icons">
<button class="icons-button"><text class="icon-heart"></text>收藏</button>
<button class="icons-button" open-type="contact">
<text class="icon-handset"></text>客服
</button>
<navigator class="icons-button" url="/pages/cart/cart" open-type="switchTab">
<text class="icon-cart"></text>购物车
</navigator>
</view>
<view class="buttons">
<view class="addcart"> 加入购物车 </view>
<view class="buynow"> 立即购买 </view>
</view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.viewport {
background-color: #f4f4f4;
}
.panel {
margin-top: 20rpx;
background-color: #fff;
.title {
display: flex;
justify-content: space-between;
align-items: center;
height: 90rpx;
line-height: 1;
padding: 30rpx 60rpx 30rpx 6rpx;
position: relative;
text {
padding-left: 10rpx;
font-size: 28rpx;
color: #333;
font-weight: 600;
border-left: 4rpx solid #27ba9b;
}
navigator {
font-size: 24rpx;
color: #666;
}
}
}
.arrow {
&::after {
position: absolute;
top: 50%;
right: 30rpx;
content: '\e6c2';
color: #ccc;
font-family: 'erabbit' !important;
font-size: 32rpx;
transform: translateY(-50%);
}
}
/* 商品信息 */
.goods {
background-color: #fff;
.preview {
height: 750rpx;
position: relative;
.image {
width: 750rpx;
height: 750rpx;
}
.indicator {
height: 40rpx;
padding: 0 24rpx;
line-height: 40rpx;
border-radius: 30rpx;
color: #fff;
font-family: Arial, Helvetica, sans-serif;
background-color: rgba(0, 0, 0, 0.3);
position: absolute;
bottom: 30rpx;
right: 30rpx;
.current {
font-size: 26rpx;
}
.split {
font-size: 24rpx;
margin: 0 1rpx 0 2rpx;
}
.total {
font-size: 24rpx;
}
}
}
.meta {
position: relative;
border-bottom: 1rpx solid #eaeaea;
.price {
height: 130rpx;
padding: 25rpx 30rpx 0;
color: #fff;
font-size: 34rpx;
box-sizing: border-box;
background-color: #35c8a9;
}
.number {
font-size: 56rpx;
}
.brand {
width: 160rpx;
height: 80rpx;
overflow: hidden;
position: absolute;
top: 26rpx;
right: 30rpx;
}
.name {
max-height: 88rpx;
line-height: 1.4;
margin: 20rpx;
font-size: 32rpx;
color: #333;
}
.desc {
line-height: 1;
padding: 0 20rpx 30rpx;
font-size: 24rpx;
color: #cf4444;
}
}
.action {
padding-left: 20rpx;
.item {
height: 90rpx;
padding-right: 60rpx;
border-bottom: 1rpx solid #eaeaea;
font-size: 26rpx;
color: #333;
position: relative;
display: flex;
align-items: center;
&:last-child {
border-bottom: 0 none;
}
}
.label {
width: 60rpx;
color: #898b94;
margin: 0 16rpx 0 10rpx;
}
.text {
flex: 1;
-webkit-line-clamp: 1;
}
}
}
/* 商品详情 */
.detail {
padding-left: 20rpx;
.content {
margin-left: -20rpx;
.image {
width: 100%;
}
}
.properties {
padding: 0 20rpx;
margin-bottom: 30rpx;
.item {
display: flex;
line-height: 2;
padding: 10rpx;
font-size: 26rpx;
color: #333;
border-bottom: 1rpx dashed #ccc;
}
.label {
width: 200rpx;
}
.value {
flex: 1;
}
}
}
/* 同类推荐 */
.similar {
.content {
padding: 0 20rpx 200rpx;
background-color: #f4f4f4;
display: flex;
flex-wrap: wrap;
.goods {
width: 340rpx;
padding: 24rpx 20rpx 20rpx;
margin: 20rpx 7rpx;
border-radius: 10rpx;
background-color: #fff;
}
.image {
width: 300rpx;
height: 260rpx;
}
.name {
height: 80rpx;
margin: 10rpx 0;
font-size: 26rpx;
color: #262626;
}
.price {
line-height: 1;
font-size: 20rpx;
color: #cf4444;
}
.number {
font-size: 26rpx;
margin-left: 2rpx;
}
}
navigator {
&:nth-child(even) {
margin-right: 0;
}
}
}
/* 底部工具栏 */
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
background-color: #fff;
height: 100rpx;
padding: 0 20rpx var(--window-bottom);
border-top: 1rpx solid #eaeaea;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: content-box;
.buttons {
display: flex;
& > view {
width: 220rpx;
text-align: center;
line-height: 72rpx;
font-size: 26rpx;
color: #fff;
border-radius: 72rpx;
}
.addcart {
background-color: #ffa868;
}
.buynow,
.payment {
background-color: #27ba9b;
margin-left: 20rpx;
}
}
.icons {
padding-right: 10rpx;
display: flex;
align-items: center;
flex: 1;
.icons-button {
flex: 1;
text-align: center;
line-height: 1.4;
padding: 0;
margin: 0;
border-radius: 0;
font-size: 20rpx;
color: #333;
background-color: #fff;
&::after {
border: none;
}
}
text {
display: block;
font-size: 34rpx;
}
}
}
</style>
骨架屏
<template name="skeleton">
<view class="sk-container">
<scroll-view :scroll-y="true" class="viewport viewport" :enable-back-to-top="true">
<view class="goods goods">
<view class="preview preview">
<swiper :circular="true" :current="0" :autoplay="false">
<swiper-item
style="
position: absolute;
width: 100%;
height: 100%;
transform: translate(0%, 0px) translateZ(0px);
"
>
<image mode="aspectFill" class="sk-image"></image>
</swiper-item>
</swiper>
<view class="indicator indicator">
<text class="current sk-transparent sk-opacity">1</text>
<text class="split sk-transparent sk-opacity">/</text>
<text class="total sk-transparent sk-opacity">5</text>
</view>
</view>
<view class="meta meta">
<view class="price price">
<text class="symbol sk-transparent sk-opacity">¥</text>
<text class="number sk-transparent sk-text-14-2857-813 sk-text">168.00</text>
</view>
<view class="name ellipsis sk-transparent sk-text-14-2857-290 sk-text"
>梅乃宿梅酒720毫升</view
>
<view class="desc sk-transparent sk-text-0-0000-205 sk-text"
>小藏手工酿造,百年名酒app</view
>
</view>
<view class="action action">
<view class="item arrow sk-pseudo sk-pseudo-circle">
<text class="label sk-transparent sk-text-14-2857-92 sk-text">选择</text>
<text class="text ellipsis sk-transparent sk-text-14-2857-598 sk-text">
请选择商品规格
</text>
</view>
<view class="item arrow sk-pseudo sk-pseudo-circle">
<text class="label sk-transparent sk-text-14-2857-857 sk-text">送至</text>
<text class="text ellipsis sk-transparent sk-text-14-2857-937 sk-text">
请选择收获地址
</text>
</view>
<view class="item arrow sk-pseudo sk-pseudo-circle">
<text class="label sk-transparent sk-text-14-2857-847 sk-text">服务</text>
<text class="text ellipsis sk-transparent sk-text-14-2857-959 sk-text">
无忧退 快速退款 免费包邮
</text>
</view>
</view>
</view>
<view is="node-modules/@dcloudio/uni-ui/lib/uni-popup/uni-popup" class="r r"></view>
<view class="detail detail panel panel">
<view class="title title">
<text class="sk-transparent sk-text-0-0000-548 sk-text">详情</text>
</view>
<view class="content content">
<view class="properties properties">
<view class="item item">
<text class="label sk-transparent sk-text-25-0000-324 sk-text">品名</text>
<text class="value sk-transparent sk-text-25-0000-661 sk-text">梅乃宿梅酒</text>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="toolbar toolbar" style="padding-bottom: 34px">
<view class="icons icons">
<button class="icons-button sk-transparent sk-button sk-pseudo sk-pseudo-circle">
<text class="icon-heart sk-pseudo sk-pseudo-circle"></text>收藏
</button>
<button
class="icons-button sk-transparent sk-button sk-pseudo sk-pseudo-circle"
open-type="contact"
>
<text class="icon-handset sk-pseudo sk-pseudo-circle"></text>客服
</button>
<navigator class="icons-button sk-transparent" open-type="switchTab">
<text class="icon-cart sk-pseudo sk-pseudo-circle"></text>购物车
</navigator>
</view>
<view class="buttons buttons">
<view
class="addcart sk-transparent sk-text-32-9268-309 sk-text"
style="background-position-x: 50%"
>
加入购物车
</view>
<view
class="buynow sk-transparent sk-text-32-9268-304 sk-text"
style="background-position-x: 50%"
>
立即购买
</view>
</view>
</view>
</view>
</template>
<style setup>
.sk-transparent {
color: transparent !important;
}
.sk-opacity {
opacity: 0 !important;
}
.sk-text-14-2857-813 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 78.1395rpx;
position: relative !important;
}
.sk-text {
background-origin: content-box !important;
background-clip: content-box !important;
background-color: transparent !important;
color: transparent !important;
background-repeat: repeat-y !important;
}
.sk-text-14-2857-290 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 43.9535rpx;
position: relative !important;
}
.sk-text-0-0000-205 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 22.6744rpx;
position: relative !important;
}
.sk-text-14-2857-92 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-14-2857-598 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-14-2857-857 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-14-2857-937 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-14-2857-847 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-14-2857-959 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 34.186rpx;
position: relative !important;
}
.sk-text-0-0000-548 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 27.907rpx;
position: relative !important;
}
.sk-text-25-0000-324 {
background-image: linear-gradient(
transparent 25%,
#eeeeee 0%,
#eeeeee 75%,
transparent 0%
) !important;
background-size: 100% 48.8372rpx;
position: relative !important;
}
.sk-text-25-0000-661 {
background-image: linear-gradient(
transparent 25%,
#eeeeee 0%,
#eeeeee 75%,
transparent 0%
) !important;
background-size: 100% 48.8372rpx;
position: relative !important;
}
.sk-text-32-9268-309 {
background-image: linear-gradient(
transparent 32.9268%,
#eeeeee 0%,
#eeeeee 67.0732%,
transparent 0%
) !important;
background-size: 100% 71.5116rpx;
position: relative !important;
}
.sk-text-32-9268-304 {
background-image: linear-gradient(
transparent 32.9268%,
#eeeeee 0%,
#eeeeee 67.0732%,
transparent 0%
) !important;
background-size: 100% 71.5116rpx;
position: relative !important;
}
.sk-button {
color: #efefef !important;
background: #efefef !important;
border: none !important;
box-shadow: none !important;
}
.sk-image {
background: #efefef !important;
}
.sk-pseudo::before,
.sk-pseudo::after {
background: #efefef !important;
background-image: none !important;
color: transparent !important;
border-color: transparent !important;
}
.sk-pseudo-rect::before,
.sk-pseudo-rect::after {
border-radius: 0 !important;
}
.sk-pseudo-circle::before,
.sk-pseudo-circle::after {
border-radius: 50% !important;
}
.sk-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: transparent;
}
</style>
服务面板
// ServicePanel.vue
<script setup lang="ts">
//
const emit = defineEmits<{
(even: 'close'): void
}>()
</script>
<template>
<view class="service-panel">
<!-- 关闭按钮 -->
<text class="close icon-close" @tap="emit('close')"></text>
<!-- 标题 -->
<view class="title">服务说明</view>
<!-- 内容 -->
<view class="content">
<view class="item">
<view class="dt">无忧退货</view>
<view class="dd">
自收到商品之日起30天内,可在线申请无忧退货服务(食品等特殊商品除外)
</view>
</view>
<view class="item">
<view class="dt">快速退款</view>
<view class="dd">
收到退货包裹并确认无误后,将在48小时内办理退款,
退款将原路返回,不同银行处理时间不同,预计1-5个工作日到账
</view>
</view>
<view class="item">
<view class="dt">满88元免邮费</view>
<view class="dd">
单笔订单金额(不含运费)满88元可免邮费,不满88元, 单笔订单收取10元邮费
</view>
</view>
</view>
</view>
</template>
<style lang="scss">
.service-panel {
padding: 0 30rpx;
border-radius: 10rpx 10rpx 0 0;
position: relative;
background-color: #fff;
}
.title {
line-height: 1;
padding: 40rpx 0;
text-align: center;
font-size: 32rpx;
font-weight: normal;
border-bottom: 1rpx solid #ddd;
color: #444;
}
.close {
position: absolute;
right: 24rpx;
top: 24rpx;
}
.content {
padding: 20rpx 20rpx 100rpx 20rpx;
.item {
margin-top: 20rpx;
}
.dt {
margin-bottom: 10rpx;
font-size: 28rpx;
color: #333;
font-weight: 500;
position: relative;
&::before {
content: '';
width: 10rpx;
height: 10rpx;
border-radius: 50%;
background-color: #eaeaea;
transform: translateY(-50%);
position: absolute;
top: 50%;
left: -20rpx;
}
}
.dd {
line-height: 1.6;
font-size: 26rpx;
color: #999;
}
}
</style>
地址面板
// AddressPanel.vue
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
const emit = defineEmits<{
(even: 'close'): void
}>()
//高亮的选项
const activeIndex = ref(0)
onLoad(() => {})
</script>
<template>
<view class="address-panel">
<!-- 关闭按钮 -->
<text class="close icon-close" @tap="emit('close')"></text>
<!-- 标题 -->
<view class="title">配送至</view>
<!-- 内容 -->
<view class="content">
<view class="item" v-for="addr in 3" :key="addr">
<view class="user">李明 13824686868</view>
<view class="address">北京市顺义区后沙峪地区安平北街6号院</view>
<text class="icon icon-checked"></text>
</view>
</view>
<view class="footer">
<view class="button primary"> 新建地址 </view>
<view v-if="false" class="button primary">确定</view>
</view>
</view>
</template>
<style lang="scss">
.address-panel {
padding: 0 30rpx;
border-radius: 10rpx 10rpx 0 0;
position: relative;
background-color: #fff;
}
.title {
line-height: 1;
padding: 40rpx 0;
text-align: center;
font-size: 32rpx;
font-weight: normal;
border-bottom: 1rpx solid #ddd;
color: #444;
}
.close {
position: absolute;
right: 24rpx;
top: 24rpx;
}
.content {
min-height: 300rpx;
max-height: 540rpx;
overflow: auto;
padding: 20rpx;
.item {
padding: 30rpx 50rpx 30rpx 60rpx;
background-size: 40rpx;
background-repeat: no-repeat;
background-position: 0 center;
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/locate.png);
position: relative;
}
.icon {
color: #999;
font-size: 40rpx;
transform: translateY(-50%);
position: absolute;
top: 50%;
right: 0;
}
.icon-checked {
color: #27ba9b;
}
.icon-ring {
color: #444;
}
.user {
font-size: 28rpx;
color: #444;
font-weight: 500;
}
.address {
font-size: 26rpx;
color: #666;
}
}
.footer {
display: flex;
justify-content: space-between;
padding: 20rpx 0 40rpx;
font-size: 28rpx;
color: #444;
.button {
flex: 1;
height: 72rpx;
text-align: center;
line-height: 72rpx;
margin: 0 20rpx;
color: #fff;
border-radius: 72rpx;
}
.primary {
color: #fff;
background-color: #27ba9b;
}
.secondary {
background-color: #ffa868;
}
}
</style>