數據流轉
修改路由src\router\index.js
:
······
{
path: '/shop/:id',
name: 'Shop',
component: () => import(/* webpackChunkName: "shop" */ '../views/shop/Shop.vue')
}
······
修改src\views\home\Nearby.vue
:
......
<router-link
v-for="(item, index) in nearbyList"
:key="index"
:to="`/shop/${item.id}`"
>
......
點擊就會發現頁面能夠跳轉詳情頁。
修改詳情頁代碼,遠程請求數據。
src\views\shop\Shop.vue
:
<template>
<div class="wrapper">
<div class="search">
<div class="search__back" @click="handleBackClick">
<i class="search__back__icon custom-icon custom-icon-back"></i>
</div>
<div class="search__content">
<span
><i class="search__content__icon custom-icon custom-icon-search"></i
></span>
<input class="search__content__input" placeholder="請輸入商品名稱" />
</div>
</div>
<!-- v-show="item.headImg" 防止撕裂圖片的出現 -->
<ShopInfo :item="item" :hideBorder="true" v-if="item.headImg" />
<Toast v-if="show" :message="message" />
</div>
</template>
<script>
import { reactive, toRefs, nextTick } from 'vue' // 路由跳轉方法
import { useRouter, useRoute } from 'vue-router'
import ShopInfo from '@/components/ShopInfo/ShopInfo.vue'
import { get } from '@/utils/request.js'
import Toast, { useToastEffect } from '@/components/Toast/Toast'
const useShopInfoEffect = (toastMsg, route) => {
const data = reactive({ item: {} })
// eslint-disable-next-line no-unused-vars
const getItemData = async () => {
// 可以寫成: const resultData = await get(`/api/shop/${route.params.id}`)
const resultData = await get('/api/shop/' + route.params.id)
if (resultData?.code === 200 && resultData?.data) {
data.item = {
id: resultData.data?.id,
title: resultData.data?.name,
sales: resultData.data?.sales,
headImg: resultData.data?.imgUrl,
expressLimit: resultData.data?.expressLimit,
expressPrice: resultData.data?.expressPrice,
highlight: resultData.data?.slogon
}
nextTick()
} else {
toastMsg('沒有數據!')
}
}
const { item } = toRefs(data)
return { item, getItemData }
}
const useBackRouterEffect = router => {
const handleBackClick = () => {
router.back()
}
return { handleBackClick }
}
export default {
name: 'Shop',
components: { ShopInfo, Toast },
setup () {
const router = useRouter() // 整個大路由的信息
const route = useRoute() // 當前訪問路徑的信息
const { show, message, toastMsg } = useToastEffect()
const { item, getItemData } = useShopInfoEffect(toastMsg, route)
const { handleBackClick } = useBackRouterEffect(router)
getItemData()
return { show, message, item, handleBackClick }
}
}
</script>
新增src\views\shop\Content.vue
:
<template>
<div class="content">
<div class="category">
<div class="category__item category__item--active">全部商品</div>
<div class="category__item">折扣</div>
<div class="category__item">新鮮水果</div>
<div class="category__item">休閒食品</div>
<div class="category__item">時令蔬菜</div>
<div class="category__item">肉蛋家禽</div>
</div>
<div class="product">
<div class="product__item">
<img class="product__item__img" src="/i18n/9_16/img/tomato.png" />
<div class="product__item__detail">
<h4 class="product__item__title">番茄250g/份</h4>
<p class="product__item__sales">月售x件</p>
<p class="product__item__price">
<span class="product__item__yen">
¥33.6
</span>
<span class="product__item__origin">
¥66.6
</span>
</p>
</div>
<div class="product__number">
<span class="product__number__minus">-</span>
0
<span class="product__number__plus">+</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: ''
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
@import '@/style/mixins.scss';
.content {
display: flex;
position: absolute;
left: 0;
right: 0;
top: 1.6rem;
bottom: 0.5rem;
}
.category {
overflow-y: scroll;
width: 0.76rem;
background: $search-bg-color;
height: 100%;
&__item {
line-height: 0.4rem;
text-align: center;
font-size: 14px;
color: $content-font-color;
&--active {
background: $bg-color;
}
}
}
.product {
overflow-y: scroll;
flex: 1;
&__item {
position: relative;
display: flex;
padding: 0.12rem 0.16rem;
margin: 0 0.16rem;
border-bottom: 0.01rem solid $content-bg-color;
// 配合解決超出長度以省略號顯示而不會出現換行
&__detail {
overflow: hidden;
}
&__img {
width: 0.68rem;
height: 0.68rem;
margin-right: 0.16rem;
}
&__title {
margin: 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $content-font-color;
// 超出長度以省略號顯示而不會出現換行
@include ellipsis;
}
&__sales {
margin: 0.06rem 0;
line-height: 0.16rem;
font-size: 0.12rem;
color: $content-font-color;
}
&__price {
margin: 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $height-light-font-color;
}
&__yen {
font-size: 0.12rem;
}
&__origin {
margin-left: 0.06rem;
line-height: 0.2rem;
font-size: 0.12rem;
color: $light-font-color;
text-decoration: line-through; //中劃線
}
// 購物車選購數量和加減號
.product__number {
position: absolute;
right: 0rem;
bottom: 0.12rem;
&__minus,
&__plus {
display: inline-block;
width: 0.2rem;
height: 0.2rem;
line-height: 0.16rem;
border-radius: 50%;
font-size: 0.2rem;
text-align: center;
}
// 邊框白色
&__minus {
border: 0.01rem solid $medium-font-color;
color: $medium-font-color;
margin-right: 0.05rem;
}
//無邊框,背景藍色
&__plus {
color: $bg-color;
background: $btn-bg-color;
margin-left: 0.05rem;
}
}
}
}
</style>
優化全局,替換css:
src\style\viriables.scss
:
/**
* 內容主體文字顏色
**/
$content-font-color: #333;
/**
* 無內容、背景灰、留白灰的顏色
**/
$content-bg-color: #f1f1f1;
/**
* 文字灰色字體
*
**/
$content-notice-font-color: #777;
/**
* 搜索框的背景色
**/
$search-bg-color: #f5f5f5;
/**
* 搜索框內文字顏色
**/
$search-font-color: #b7b7b7;
/**
* 默認背景顏色
**/
$bg-color: #fff;
/**
* 亮色主題高亮文字顏色
**/
$height-light-font-color: #e83b3b;
/**
* 中亮文字顏色
**/
$medium-font-color: #666;
/**
* 亮文字顏色
**/
$light-font-color: #999;
/**
* 按鈕背景顏色
**/
$btn-bg-color: #0091ff;
優化stop.vue
<template>
<div class="wrapper">
<div class="search">
<div class="search__back" @click="handleBackClick">
<i class="search__back__icon custom-icon custom-icon-back"></i>
</div>
<div class="search__content">
<span
><i class="search__content__icon custom-icon custom-icon-search"></i
></span>
<input class="search__content__input" placeholder="請輸入商品名稱" />
</div>
</div>
<!-- v-show="item.headImg" 防止撕裂圖片的出現 -->
<ShopInfo :item="item" :hideBorder="true" v-if="item.headImg" />
<Content />
<Toast v-if="show" :message="message" />
</div>
</template>
<script>
import { reactive, toRefs, nextTick } from 'vue' // 路由跳轉方法
import { useRouter, useRoute } from 'vue-router'
import ShopInfo from '@/components/ShopInfo/ShopInfo'
import { get } from '@/utils/request.js'
import Toast, { useToastEffect } from '@/components/Toast/Toast'
import Content from '@/views/shop/Content'
// 獲取當前商鋪信息
const useShopInfoEffect = (toastMsg, route) => {
const data = reactive({ item: {} })
// eslint-disable-next-line no-unused-vars
const getItemData = async () => {
// 可以寫成: const resultData = await get(`/api/shop/${route.params.id}`)
console.log(' route.params.id:' + route.params.id)
const resultData = await get('/api/shop/' + route.params.id)
if (resultData?.code === 200 && resultData?.data) {
data.item = {
id: resultData.data?.id,
title: resultData.data?.name,
sales: resultData.data?.sales,
headImg: resultData.data?.imgUrl,
expressLimit: resultData.data?.expressLimit,
expressPrice: resultData.data?.expressPrice,
highlight: resultData.data?.slogon
}
console.log('data.item :' + JSON.stringify(data.item))
debugger
nextTick()
} else {
toastMsg('沒有數據!')
}
}
const { item } = toRefs(data)
return { item, getItemData }
}
// 後退按鈕事件
const useBackRouterEffect = router => {
const handleBackClick = () => {
router.back()
}
return { handleBackClick }
}
export default {
name: 'Shop',
components: { ShopInfo, Toast, Content },
// eslint-disable-next-line space-before-function-paren
setup() {
const router = useRouter() // 整個大路由的信息
const route = useRoute() // 當前訪問路徑的信息
const { show, message, toastMsg } = useToastEffect()
const { item, getItemData } = useShopInfoEffect(toastMsg, route)
const { handleBackClick } = useBackRouterEffect(router)
getItemData()
return { show, message, item, handleBackClick }
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables';
.wrapper {
padding: 0 0.18rem;
}
.search {
margin: 0.14rem 0 0.04rem 0;
display: flex;
line-height: 0.32rem; //高度會將父元素撐開
&__back {
width: 0.3rem;
&__icon {
font-size: 0.2rem;
color: #b6b6b6;
}
}
&__content {
display: flex;
flex: 1;
background: $search-bg-color;
border-radius: 0.16rem;
&__icon {
padding-left: 0.1rem;
padding-right: 0.1rem;
width: 0.44rem;
text-align: center;
color: $search-font-color;
}
&__input {
padding-right: 0.2rem;
width: 100%;
display: block;
border: none;
outline: none;
background: none;
height: 0.32rem;
font-size: 0.14rem;
color: $content-font-color;
&::placeholder {
color: $content-font-color;
}
}
}
}
</style>
結果如下:
其中接口
/mock/api/shop/:id
:數據如下:
{
"code": 200,
"data": {
"id": "1",
"name": "某什麼瑪1",
"imgUrl": "/i18n/9_16/img/near.png",
"sales": 200,
"expressLimit": 0,
"expressPrice": 5,
"slogon": "VIP尊享xx元減x元運費券(每月x張)"
},
"desc": "成功"
}