文章目录
- 17-商品详情-标签页组件
- 18-商品详情-热榜组件
- 19-商品详情-详情组件
- 20-商品详情-注意事项组件
17-商品详情-标签页组件
目的:实现商品详情组件和商品评价组件的切换
大致步骤:
- 完成基础的tab的导航布局
- 完成tab标签页的切换样式效果
- 使用动态组件完成可切换 详情 和 评论 组件
落的代码:
- 标签页基础布局
src/vies/goods/components/goods-tabs.vue
<div class="goods-tabs">
<nav>
<a class="active" href="javascript:;">商品详情</a>
<a href="javascript:;">商品评价<span>(500+)</span></a>
</nav>
<!-- 切换内容的地方 -->
</div>
.goods-tabs {
min-height: 600px;
background: #fff;
nav {
height: 70px;
line-height: 70px;
display: flex;
border-bottom: 1px solid #f5f5f5;
a {
padding: 0 40px;
font-size: 18px;
position: relative;
> span {
color: @priceColor;
font-size: 16px;
margin-left: 10px;
}
&:first-child {
border-right: 1px solid #f5f5f5;
}
&.active {
&::before {
content: "";
position: absolute;
left: 40px;
bottom: -1px;
width: 72px;
height: 2px;
background: @xtxColor;
}
}
}
}
}
- tabs组件切换
src/vies/goods/components/goods-tabs.vue
<template>
<div class="goods-tabs">
<nav>
<a
:class="{ active: activeName === 'detail' }"
href="javascript:;"
@click="clickTab('detail')"
>商品详情</a
>
<a
:class="{ active: activeName === 'comment' }"
href="javascript:;"
@click="clickTab('comment')"
>商品评价<span>(500+)</span></a
>
</nav>
<!-- 这个位置显示对应的组件 GoodsDetail 或者 GoodsComment -->
<component :is="'goods-'+activeName" />
</div>
</template>
<script>
import { ref } from 'vue'
import GoodsDetail from './goods-detail'
import GoodsComment from './goods-comment'
export default {
name: 'GoodsTabs',
components: { GoodsDetail, GoodsComment },
setup () {
// detail-->详情 comment-->评价
const activeName = ref('detail')
const clickTab = (name) => {
activeName.value = name
}
return { activeName, clickTab }
}
}
</script>
- 使用tabs组件
src/views/goods/index.vue
+import GoodsTabs from './components/goods-tabs'
// ... 省略
export default {
name: 'XtxGoodsPage',
+ components: { GoodsRelevant, GoodsImage, GoodsSales, GoodsName, GoodsSku, GoodsTabs },
setup () {
<div class="goods-article">
<!-- 商品+评价 -->
+ <GoodsTabs :goods="goods" />
<!-- 注意事项 -->
<div class="goods-warn"></div>
</div>
-.goods-tabs {
- min-height: 600px;
- background: #fff;
-}
- 定义详情组件,评价组件。
src/vies/goods/components/goods-detail.vue
<template>
<div class="goods-detail">详情</div>
</template>
<script>
export default {
name: 'GoodsDetail'
}
</script>
<style scoped lang="less"></style>
src/vies/goods/components/goods-comment.vue
<template>
<div class="goods-comment">评价</div>
</template>
<script>
export default {
name: 'GoodsComment'
}
</script>
<style scoped lang="less"></style>
18-商品详情-热榜组件
目的:展示24小时热榜商品,和周热榜商品。
大致步骤:
- 定义一个组件,完成多个组件展现型态,根据传入组件的类型决定。
- 1代表24小时热销榜 2代表周热销榜 3代表总热销榜
- 获取数据,完成商品展示和标题样式的设置。
落的代码:
- 定义组件
src/views/goods/components/goods-hot.vue
<template>
<div class="goods-hot">
<h3>{{title}}</h3>
</div>
</template>
<script>
import { computed } from 'vue'
export default {
name: 'GoodsHot',
props: {
type: {
type: Number,
default: 1
}
},
setup (props) {
const titleObj = { 1: '24小时热销榜', 2: '周热销榜', 3: '总热销榜' }
const title = computed(() => {
return titleObj[props.type]
})
return { title }
}
}
</script>
<style scoped lang="less"></style>
- 使用组件
src/views/goods/index.vue
+import GoodsHot from './components/goods-hot'
// ... 省略
name: 'XtxGoodsPage',
+ components: { GoodsRelevant, GoodsImage, GoodsSales, GoodsName, GoodsSku, GoodsTabs, GoodsHot },
setup () {
<!-- 24热榜+专题推荐 -->
<div class="goods-aside">
<GoodsHot :goodsId="goods.id" :type="1" />
<GoodsHot :goodsId="goods.id" :type="2" />
</div>
- 获取数据,设置组件样式
src/api/goods.js
/**
* 获取热榜商品
* @param {Number} type - 1代表24小时热销榜 2代表周热销榜 3代表总热销榜
* @param {Number} limit - 获取个数
*/
export const findHotGoods = ({id,type, limit = 3}) => {
return request('/goods/hot', 'get', {id, type, limit })
}
src/views/goods/components/goot-hot.vue
import { computed, ref } from 'vue'
import GoodsItem from '../../category/components/goods-item'
import { findHotGoods } from '@/api/goods'
export default {
name: 'GoodsHot',
props: {
type: {
type: Number,
default: 1
},
goodsId: {
type: String
}
},
components: { GoodsItem },
setup (props) {
// 处理标题
const titleObj = { 1: '24小时热销榜', 2: '周热销榜', 3: '总热销榜' }
const title = computed(() => {
return titleObj[props.type]
})
// 商品列表
const goodsList = ref([])
findHotGoods({ id: props.goodsId, type: props.type }).then(data => {
goodsList.value = data.result.map(item => {
item.tag = item.desc
return item
})
})
return { title, goodsList }
}
}
<template>
<div class="goods-hot">
<h3>{{title}}</h3>
<div v-if="goodsList">
<GoodsItem v-for="item in goodsList" :key="item.id" :goods="item"/>
</div>
</div>
</template>
.goods-hot {
h3 {
height: 70px;
background: @helpColor;
color: #fff;
font-size: 18px;
line-height: 70px;
padding-left: 25px;
margin-bottom: 10px;
font-weight: normal;
}
::v-deep .goods-item {
background: #fff;
width: 100%;
margin-bottom: 10px;
img {
width: 200px;
height: 200px;
}
p {
margin: 0 10px;
}
&:hover {
transform: none;
box-shadow: none;
}
}
}
19-商品详情-详情组件
目的:展示商品属性和商品详情。
大致步骤:
- 完成基础布局,主要是属性,详情是图片。
goods/index.vue
提供goods数据,子孙组件注入goods数据,渲染展示即可。
落的代码:
- 传递goods数据
src/views/goods/index.vue
setup中提供数据
provide('goods', goods)
- 使用goods数据,展示评价数量
src/views/goods/components/goods-tabs.vue
setup () {
const goods = inject('goods')
return { goods }
},
+ >商品评价<span>({{goods.commentCount}})</span></a
- 使用goods数据,展示商品详情
src/views/goods/components/goods-detail.vue
<template>
<div class="goods-detail">
<!-- 属性 -->
<ul class="attrs">
<li v-for="item in goods.details.properties" :key="item.value">
<span class="dt">{{item.name}}</span>
<span class="dd">{{item.value}}</span>
</li>
</ul>
<!-- 图片 -->
<img v-for="item in goods.details.pictures" :key="item" :src="item" alt="">
</div>
</template>
<script>
export default {
name: 'GoodsDetail',
setup () {
const goods = inject('goods')
return { goods }
}
}
</script>
<style scoped lang="less">
.goods-detail {
padding: 40px;
.attrs {
display: flex;
flex-wrap: wrap;
margin-bottom: 30px;
li {
display: flex;
margin-bottom: 10px;
width: 50%;
.dt {
width: 100px;
color: #999;
}
.dd {
flex: 1;
color: #666;
}
}
}
> img {
width: 100%;
}
}
</style>
20-商品详情-注意事项组件
目的:展示购买商品的注意事项。
src/views/goods/index.vue
+import GoodsWarn from './components/goods-warn'
name: 'XtxGoodsPage',
+ components: { GoodsRelevant, GoodsImage, GoodsSales, GoodsName, GoodsSku, GoodsTabs, GoodsHot, GoodsWarn },
setup () {
<!-- 注意事项 -->
+ <GoodsWarn />
src/views/goods/components/goods-warn.vue
<template>
<!-- 注意事项 -->
<div class="goods-warn">
<h3>注意事项</h3>
<p class="tit">• 购买运费如何收取?</p>
<p>
单笔订单金额(不含运费)满88元免邮费;不满88元,每单收取10元运费。(港澳台地区需满500元免邮费;不满500元,每单收取30元运费)
</p>
<br />
<p class="tit">• 使用什么快递发货?</p>
<p>默认使用顺丰快递发货(个别商品使用其他快递)</p>
<p>配送范围覆盖全国大部分地区(港澳台地区除外)</p>
<br />
<p class="tit">• 如何申请退货?</p>
<p>
1.自收到商品之日起30日内,顾客可申请无忧退货,退款将原路返还,不同的银行处理时间不同,预计1-5个工作日到账;
</p>
<p>2.内裤和食品等特殊商品无质量问题不支持退货;</p>
<p>
3.退货流程:
确认收货-申请退货-客服审核通过-用户寄回商品-仓库签收验货-退款审核-退款完成;
</p>
<p>
4.因小兔鲜儿产生的退货,如质量问题,退货邮费由小兔鲜儿承担,退款完成后会以现金券的形式报销。因客户个人原因产生的退货,购买和寄回运费由客户个人承担。
</p>
</div>
</template>
<style lang="less" scoped>
.goods-warn {
margin-top: 20px;
background: #fff;
padding-bottom: 40px;
h3 {
height: 70px;
line-height: 70px;
border-bottom: 1px solid #f5f5f5;
padding-left: 50px;
font-size: 18px;
font-weight: normal;
margin-bottom: 10px;
}
p {
line-height: 40px;
padding: 0 25px;
color: #666;
&.tit {
color: #333;
}
}
}
</style>