黑马 小兔鲜儿 uniapp 小程序开发- 商品详情模块- day05

黑马 小兔鲜儿 uniapp 小程序开发- 分类模块- day04-CSDN博客

小兔鲜儿 - 商品详情(登录前)-day05

商品详情页分为两部分讲解:

  1. 登录前:展示商品信息,轮播图交互(当前模块)
  2. 登录后:加入购物车,立即购买(SKU 模块)

准备工作

参考效果

用户点击商品列表,跳转到对应的商品详情页。

静态结构

新建商品详情页。

// src/pages/goods/goods.vue
<script setup lang="ts">
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
</script><template><scroll-view scroll-y class="viewport"><!-- 基本信息 --><view class="goods"><!-- 商品主图 --><view class="preview"><swiper circular><swiper-item><imagemode="aspectFill"src="https://yanxuan-item.nosdn.127.net/99c83709ca5f9fd5c5bb35d207ad7822.png"/></swiper-item><swiper-item><imagemode="aspectFill"src="https://yanxuan-item.nosdn.127.net/f9107d47c08f0b99c097e30055c39e1a.png"/></swiper-item><swiper-item><imagemode="aspectFill"src="https://yanxuan-item.nosdn.127.net/754c56785cc8c39f7414752f62d79872.png"/></swiper-item><swiper-item><imagemode="aspectFill"src="https://yanxuan-item.nosdn.127.net/ef16f8127610ef56a2a10466d6dae157.jpg"/></swiper-item><swiper-item><imagemode="aspectFill"src="https://yanxuan-item.nosdn.127.net/1f0c3f5d32b0e804deb9b3d56ea6c3b2.png"/></swiper-item></swiper><view class="indicator"><text class="current">1</text><text class="split">/</text><text class="total">5</text></view></view><!-- 商品简介 --><view class="meta"><view class="price"><text class="symbol">¥</text><text class="number">29.90</text></view><view class="name ellipsis">云珍·轻软旅行长绒棉方巾 </view><view class="desc"> 轻巧无捻小方巾,旅行便携 </view></view><!-- 操作面板 --><view class="action"><view class="item arrow"><text class="label">选择</text><text class="text ellipsis"> 请选择商品规格 </text></view><view class="item arrow"><text class="label">送至</text><text class="text ellipsis"> 请选择收获地址 </text></view><view class="item arrow"><text class="label">服务</text><text class="text ellipsis"> 无忧退 快速退款 免费包邮 </text></view></view></view><!-- 商品详情 --><view class="detail panel"><view class="title"><text>详情</text></view><view class="content"><view class="properties"><!-- 属性详情 --><view class="item"><text class="label">属性名</text><text class="value">属性值</text></view><view class="item"><text class="label">属性名</text><text class="value">属性值</text></view></view><!-- 图片详情 --><imagemode="widthFix"src="https://yanxuan-item.nosdn.127.net/a8d266886d31f6eb0d7333c815769305.jpg"></image><imagemode="widthFix"src="https://yanxuan-item.nosdn.127.net/a9bee1cb53d72e6cdcda210071cbd46a.jpg"></image></view></view><!-- 同类推荐 --><view class="similar panel"><view class="title"><text>同类推荐</text></view><view class="content"><navigatorv-for="item in 4":key="item"class="goods"hover-class="none":url="`/pages/goods/goods?id=`"><imageclass="image"mode="aspectFill"src="https://yanxuan-item.nosdn.127.net/e0cea368f41da1587b3b7fc523f169d7.png"></image><view class="name ellipsis">简约山形纹全棉提花毛巾</view><view class="price"><text class="symbol">¥</text><text class="number">18.50</text></view></navigator></view></view></scroll-view><!-- 用户操作 --><viewclass="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><navigatorclass="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;.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;}.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 {padding-left: 20rpx;.content {padding: 0 20rpx 20rpx;margin-left: -20rpx;background-color: #f4f4f4;overflow: hidden;navigator {width: 345rpx;padding: 24rpx 20rpx 20rpx;margin: 20rpx 20rpx 0 0;border-radius: 10rpx;background-color: #fff;float: left;}.image {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 {background-color: #fff;height: 100rpx;padding: 0 20rpx;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 {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;}text {display: block;font-size: 34rpx;}}
}
</style>

获取数据

获取页面参数

根据商品的 id 查询到某个商品的详细信息,如图片、价格、型号等展示给用户。

// 接收页面参数
const query = defineProps<{id: string
}>()

接口调用

接口信息如下:

接口地址:/goods

请求方式:GET

请求参数:

Query

字段名称

是否必须

默认值

备注

id

商品 id

请求封装

/*** 商品详情* @param id 商品id*/
export const getGoodsByIdAPI = (id: string) => {return http<GoodsResult>({method: 'GET',url: '/goods',data: { id },})
}

类型声明

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
}

接下来,将获取到的数据结合模板语法渲染到页面中。

轮播图交互

参考效果

当轮播图滑动切换的时候更新自定义下标,当图片被点击的时候大图预览

参考代码

商品详情页轮播图交互

<script setup lang="ts">
// 轮播图变化时
const currentIndex = ref(0)
const onChange: UniHelper.SwiperOnChange = (ev) => {currentIndex.value = ev.detail.current
}// 点击图片时
const onTapImage = (url: string) => {// 大图预览uni.previewImage({current: url,urls: goods.value!.mainPictures,})
}
</script><template><!-- 商品主图 --><view class="preview"><swiper @change="onChange" circular><swiper-item v-for="item in goods?.mainPictures" :key="item"><image @tap="onTapImage(item)" mode="aspectFill" :src="item" /></swiper-item></swiper><view class="indicator"><text class="current">{{ currentIndex + 1 }}</text><text class="split">/</text><text class="total">{{ goods?.mainPictures.length }}</text></view></view>
</template>

弹出层交互

参考效果

uni-ui 弹出层组件:uni-popup

静态结构

提供 服务说明收获地址 两个组件的静态结构,实现弹出层交互。

组件 1:服务说明

// ServicePanel.vue
<script setup lang="ts">
//
</script><template><view class="service-panel"><!-- 关闭按钮 --><text class="close icon-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>

组件 2:收获地址组件

// AddressPanel.vue
<script setup lang="ts">
//
</script><template><view class="address-panel"><!-- 关闭按钮 --><text class="close icon-close"></text><!-- 标题 --><view class="title">配送至</view><!-- 内容 --><view class="content"><view class="item"><view class="user">李明 13824686868</view><view class="address">北京市顺义区后沙峪地区安平北街6号院</view><text class="icon icon-checked"></text></view><view class="item"><view class="user">王东 13824686868</view><view class="address">北京市顺义区后沙峪地区安平北街6号院</view><text class="icon icon-ring"></text></view><view class="item"><view class="user">张三 13824686868</view><view class="address">北京市朝阳区孙河安平北街6号院</view><text class="icon icon-ring"></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>

参考代码

商品详情页:通过组件 ref 获取弹出层组件实例,调用打开弹出层方法。

<script setup lang="ts">
import AddressPanel from './components/AddressPanel.vue'
import ServicePanel from './components/ServicePanel.vue'// uni-ui 弹出层组件 ref
const popup = ref<{open: (type?: UniHelper.UniPopupType) => voidclose: () => void
}>()// 弹出层条件渲染
const popupName = ref<'address' | 'service'>()
const openPopup = (name: typeof popupName.value) => {// 修改弹出层名称popupName.value = name// 打开弹出层popup.value?.open()
}
</script><template><!-- 操作面板 --><view class="action"><view class="item arrow"><text class="label">选择</text><text class="text ellipsis"> 请选择商品规格 </text></view><view @tap="openPopup('address')" class="item arrow"><text class="label">送至</text><text class="text ellipsis"> 请选择收获地址 </text></view><view @tap="openPopup('service')" class="item arrow"><text class="label">服务</text><text class="text ellipsis"> 无忧退 快速退款 免费包邮 </text></view></view><!-- uni-ui 弹出层 --><uni-popup ref="popup" type="bottom" background-color="#fff"><AddressPanel v-if="popupName === 'address'" @close="popup?.close()" /><ServicePanel v-if="popupName === 'service'" @close="popup?.close()" /></uni-popup>
</template>

服务说明收获地址 组件通讯:通过子调父,关闭弹出层。

<script setup lang="ts">
// 子调父
const emit = defineEmits<{(event: 'close'): void
}>()
</script><template><view class="service-panel"><!-- 关闭按钮 --><text class="close icon-close" @tap="emit('close')"></text>...省略</view>
</template>

骨架屏

参考效果

课后练习,大家自主独立完成。

参考代码(总)

商品详情页

<script setup lang="ts">
import { getGoodsByIdAPI } from '@/services/goods'
import type { GoodsResult } from '@/types/goods'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import AddressPanel from './components/AddressPanel.vue'
import ServicePanel from './components/ServicePanel.vue'// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()// 接收页面参数
const query = defineProps<{id: string
}>()// 获取商品详情信息
const goods = ref<GoodsResult>()
const getGoodsByIdData = async () => {const res = await getGoodsByIdAPI(query.id)goods.value = res.result
}// 页面加载
onLoad(() => {getGoodsByIdData()
})// 轮播图变化时
const currentIndex = ref(0)
const onChange: UniHelper.SwiperOnChange = (ev) => {currentIndex.value = ev.detail!.current
}// 点击图片时
const onTapImage = (url: string) => {// 大图预览uni.previewImage({current: url,urls: goods.value!.mainPictures,})
}// uni-ui 弹出层组件 ref
const popup = ref<{open: (type?: UniHelper.UniPopupType) => voidclose: () => void
}>()// 弹出层条件渲染
const popupName = ref<'address' | 'service'>()
const openPopup = (name: typeof popupName.value) => {// 修改弹出层名称popupName.value = namepopup.value?.open()
}
</script><template><scroll-view scroll-y class="viewport"><!-- 基本信息 --><view class="goods"><!-- 商品主图 --><view class="preview"><swiper @change="onChange" circular><swiper-item v-for="item in goods?.mainPictures" :key="item"><image @tap="onTapImage(item)" mode="aspectFill" :src="item" /></swiper-item></swiper><view class="indicator"><text class="current">{{ currentIndex + 1 }}</text><text class="split">/</text><text class="total">{{ goods?.mainPictures.length }}</text></view></view><!-- 商品简介 --><view class="meta"><view class="price"><text class="symbol">¥</text><text class="number">{{ goods?.price }}</text></view><view class="name ellipsis">{{ goods?.name }}</view><view class="desc"> {{ goods?.desc }} </view></view><!-- 操作面板 --><view class="action"><view class="item arrow"><text class="label">选择</text><text class="text ellipsis"> 请选择商品规格 </text></view><view @tap="openPopup('address')" class="item arrow"><text class="label">送至</text><text class="text ellipsis"> 请选择收获地址 </text></view><view @tap="openPopup('service')" class="item arrow"><text class="label">服务</text><text class="text ellipsis"> 无忧退 快速退款 免费包邮 </text></view></view></view><!-- 商品详情 --><view class="detail panel"><view class="title"><text>详情</text></view><view class="content"><view class="properties"><!-- 属性详情 --><viewclass="item"v-for="item in goods?.details.properties":key="item.name"><text class="label">{{ item.name }}</text><text class="value">{{ item.value }}</text></view></view><!-- 图片详情 --><imagev-for="item in goods?.details.pictures":key="item"mode="widthFix":src="item"></image></view></view><!-- 同类推荐 --><view class="similar panel"><view class="title"><text>同类推荐</text></view><view class="content"><navigatorv-for="item in goods?.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><!-- 用户操作 --><viewclass="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"><text class="icon-cart"></text>购物车</navigator></view><view class="buttons"><view class="addcart"> 加入购物车 </view><view class="payment"> 立即购买 </view></view></view><!-- uni-ui 弹出层 --><uni-popup ref="popup" type="bottom" background-color="#fff"><AddressPanel v-if="popupName === 'address'" @close="popup?.close()" /><ServicePanel v-if="popupName === 'service'" @close="popup?.close()" /></uni-popup>
</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;.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;}.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 {padding-left: 20rpx;.content {padding: 0 20rpx 20rpx;margin-left: -20rpx;background-color: #f4f4f4;overflow: hidden;navigator {width: 345rpx;padding: 24rpx 20rpx 20rpx;margin: 20rpx 20rpx 0 0;border-radius: 10rpx;background-color: #fff;float: left;}.image {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 {background-color: #fff;height: 100rpx;padding: 0 20rpx;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;}.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;}text {display: block;font-size: 34rpx;}}
}
</style>

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

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

相关文章

机器视觉能不能再火爆?大多数企业订单减少是现实,大多数企业维持现有的经营状态将会非常困难,就看人工智能和新兴产业能不能破门而入

每个人都讲机器视觉代替大量人工&#xff0c;可是真的吗&#xff1f;没有订单&#xff0c;人工的存在都没必要&#xff0c;需要什么机器视觉检测。 我们首先有一个问题&#xff0c;机器视觉行业之前有没有火爆过&#xff1f; 有&#xff0c;但是出现短暂之后是内卷。深度学习A…

LeetCode字符串题库 之 罗马数字转整数

题目链接&#x1f517;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 1. 题目分析 我们在做题的时候&#xff0c;一定要知道题目的目的是什么&#xff0c;我们可以结合测试用例和提示来看。 我们可以分析以下几点&#xff1a; 1. 每一个罗马数字都…

【Java】LinkedList 集合

LinkedList集合特点 LinkedList 底层基于双向链表实现增删 效率非常高&#xff0c;查询效率非常低。 LinkedList源码解读分析 LinkedList 是双向链表实现的 ListLinkedList 是非线程安全的&#xff08;线程是不安全的&#xff09;LinkedList 元素允许为null,允许重复元素Linked…

2023-在mac下安装Homebrew的国内镜像

mac安装Homebrew的国内镜像 尝试使用其他下载源&#xff1a;GitHub 可能会受到访问限制&#xff0c;尝试使用其他镜像或下载源。您可以使用清华大学、中科大或阿里云的 Homebrew 镜像&#xff0c;以提高下载速度和可靠性。例如&#xff0c;可以使用阿里云的镜像来安装 Homebre…

HTML5+CSS3+Vue小实例:路飞出海的动画特效

实例:路飞出海的动画特效 技术栈:HTML+CSS+Vue 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&…

亚马逊云科技为奇点云打造全面、安全、可扩展的数据分析解决方案

刘莹奇点云联合创始人、COO&#xff1a;伴随云计算的发展&#xff0c;数据技术也在快速迭代&#xff0c;成为客户迈入DT时代、实现高质量发展的关键引擎。我们很高兴能和云计算领域的领跑者亚马逊云科技一同&#xff0c;不断为客户提供安全可靠的产品与专业的服务。 超过1500家…

【广州华锐互动】飞机诊断AR远程指导系统为工程师提供更多支持

随着科技的发展&#xff0c;飞机的维护工作也在不断进步。其中&#xff0c;AR&#xff08;增强现实&#xff09;技术的应用使得远程运维成为可能。本文将探讨AR在飞机诊断远程指导系统中的应用&#xff0c;以及它对未来航空维护模式的影响。 AR远程指导系统是一种使用增强现实技…

云安全—K8S API Server 未授权访问

0x00 前言 master节点的核心就是api服务&#xff0c;k8s通过REST API来进行控制&#xff0c;在k8s中的一切都可以抽象成api对象&#xff0c;通过api的调用来进行资源调整&#xff0c;分配和操作。 通常情况下k8s的默认api服务是开启在8080端口&#xff0c;如果此接口存在未授…

JVM第二十三讲:Java动态调试技术原理

Java动态调试技术原理 本文是JVM第二十三讲&#xff0c;Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践&#xff0c;通过学习java agent方式进行动态调试&#xff0c;了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …

el-dropdown自定义样式,不影响其他组件

原来的样式: 修改后的样式: 给el-dropdown-menu添加类名dropdown-menu <el-dropdown-menu slot"dropdown" class"dropdown-menu"><router-link to"/user/profile"><el-dro…

html+js+css实现一个圆形滑块

htmljscss实现一个圆形滑块&#xff0c;可以拖动&#xff0c;可以点击&#xff0c;先看效果再讲原理&#xff0c;最后附上源码&#xff1a; 产品经理设计了这样一个需求&#xff0c;通过拖动圆形滑块实现时间的设置功能&#xff0c;虽然看着有点复杂&#xff0c;但是确实有点复…

万字解析设计模式之原型模式与建造者模式

一、原型模式 1.1概述 原型模式是一种创建型设计模式&#xff0c;其目的是使用已有对象作为原型来创建新的对象。原型模式的核心是克隆&#xff0c;即通过复制已有对象来创建新对象&#xff0c;而不是通过创建新对象的过程中独立地分配和初始化所有需要的资源。这种方式可以节…

excel求差公式怎么使用?

利用excel求差&#xff0c;可能有许多的小伙伴已经会了&#xff0c;不过还是存在一些不太熟悉的朋友们&#xff0c;所以这里有必要讲解一下。其实求差的实现主要就是一个公式&#xff0c;就是用一个单元格中的数字“减去”另一个单元格中的数字“等于”第三个单元格。此公式掌握…

手把手教你如何实现TNAS与云盘之间的无缝同步技巧

嘿&#xff0c;铁粉们&#xff01; 云盘的下载速度总是让我们抓耳挠腮 数据安全隐私问题让人担心不已 但在购入NAS之前 众多数据存放在云盘里 同时也想把NAS的数据备份在云盘里 实现备份321法则&#xff1f; 不用烦恼 铁威马来帮忙 无需其他多余操作 只要下载CloudSyn…

华为OD机考算法题:生日礼物

题目部分 题目生日礼物难度易题目说明小牛的孩子生日快要到了&#xff0c;他打算给孩子买蛋糕和小礼物&#xff0c;蛋糕和小礼物各买一个&#xff0c;他的预算不超过x元。蛋糕 cake 和小礼物 gift 都有多种价位的可供选择。输入描述第一行表示cake的单价&#xff0c;以逗号分隔…

通过python操作neo4j

在neo4j中创建结点和关系 创建结点 创建电影结点 例如&#xff1a;创建一个Movie结点&#xff0c;这个结点上带有三个属性{title:‘The Matrix’, released:1999, tagline:‘Welcome to the Real World’} CREATE (TheMatrix:Movie {title:The Matrix, released:1999, tagl…

Python Django 之模板继承详解(extends)

文章目录 1 概述1.1 目的1.2 标签&#xff1a;block、extends1.3 目录结构 2 templates 目录2.1 base.html&#xff1a;父页面2.2 login.html&#xff1a;子页面 3 其它代码3.1 settings.py3.2 views.py3.3 urls.py 1 概述 1.1 目的 模板继承 和 类继承 的目的是一样的&#…

【P2P owt】owt-client-native-p2p-e2e-test vs2017构建7:依赖库及路径

依赖库 G:\CDN\LiveServiceMesh\cdnsignal\third_party\libeva\thirdparty\janbar-openssl\out32\ssl\Debug\libssl-

2、NLP文本预处理技术:词干提取和词形还原

一、说明 在上一篇文章中&#xff0c;我们解释了文本预处理的重要性&#xff0c;并解释了一些文本预处理技术。在本文中&#xff0c;我们将介绍词干提取和词形还原主题。 词干提取和词形还原是两种文本预处理技术&#xff0c;用于将单词还原为其基本形式或词根形式。这些技术的…

SpringBoot集成与应用Neo4j

文章目录 前言集成使用定义实体配置定义Repository查询方法方式一&#xff1a;Query方式二&#xff1a;Cypher语法构建器方式三&#xff1a;Example条件构建器方式四&#xff1a;DSL语法 自定义方法自定义接口继承自定义接口实现自定义接口neo4jTemplateNeo4jClient 自定义抽象…