当前位置: 首页 > article >正文

【全栈】SprintBoot+vue3迷你商城(10)

【全栈】SprintBoot+vue3迷你商城(10)

往期的文章都在这里啦,大家有兴趣可以看一下

后端部分:

【全栈】SprintBoot+vue3迷你商城(1)
【全栈】SprintBoot+vue3迷你商城(2)
【全栈】SprintBoot+vue3迷你商城-扩展:利用python爬虫爬取商品数据
【全栈】SprintBoot+vue3迷你商城(3)
【全栈】SprintBoot+vue3迷你商城(4)
【全栈】SprintBoot+vue3迷你商城(5)
【全栈】SprintBoot+vue3迷你商城(6)

前端部分:

【全栈】SprintBoot+vue3迷你商城-扩展:vue的基本用法

【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍

【全栈】SprintBoot+vue3迷你商城(7)

【全栈】SprintBoot+vue3迷你商城(8)

【全栈】SprintBoot+vue3迷你商城(9)

本期我们来写商品详情页面、我的商品页面(限商家)以及添加商品页面(限商家)

文章目录

  • 【全栈】SprintBoot+vue3迷你商城(10)
    • 1.商品详情页面的开发
      • 1.1.搭建页面,绑定数据与函数
      • 1.2.制定与后端接口交互的函数
      • 1.3.效果展示
    • 2.我的商品页面开发
      • 2.1.搭建页面,绑定数据与函数
      • 2.2.制定与后端接口交互的函数
      • 2.3.效果展示
    • 3.添加商品页面的开发
      • 3.1.搭建页面,绑定数据与函数
      • 3.2.制定与后端接口交互的函数
      • 3.3.效果展示
    • 4.总结

1.商品详情页面的开发

1.1.搭建页面,绑定数据与函数

/src/views/goods/GoodsDetail.vue

<script lang="ts" setup>
import { ref } from 'vue'
import {getGoodsDetailService} from '@/api/goods'
import { useRoute } from 'vue-router';
const route = useRoute();
import { useRouter } from 'vue-router';
const router=useRouter();
const activeIndex = ref('0')
const handleSelect = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
}
const goodsDetailModel=ref({
    goodsName:'',
    goodsImgUrl:'',
    goodsPrice:'',
    merchantName:'',
    merchantImgUrl:''
})
import { useUserInfoStore } from '@/stores/userInfo';
const userInfoStore = useUserInfoStore();
const userInfoModel= ref(userInfoStore.info)

const goodsDetail=async()=>{
    let result= await getGoodsDetailService(route.query.id);
    goodsDetailModel.value.goodsName=result.data.goodsName;
    goodsDetailModel.value.goodsImgUrl=result.data.goodsImgUrl;
    goodsDetailModel.value.goodsPrice=result.data.goodsPrice;
    goodsDetailModel.value.merchantName=result.data.merchantName;
    goodsDetailModel.value.merchantImgUrl=result.data.merchantImgUrl;
}

import {userAddGoodsToCartService} from "@/api/user"
import { ElMessage } from 'element-plus';
const addGoodsToCart=async()=>{
    await userAddGoodsToCartService(route.query.id)
    ElMessage.success('添加成功')
    router.push('/user/cart')
}

goodsDetail()

import { Avatar,  SwitchButton } from '@element-plus/icons-vue';


import { useTokenStore } from '@/stores/token'; 
const tokenStore=useTokenStore();
const showLogoutDialog = ref(false);
const logout = () => {
  ElMessage.success('成功退出登录');
  tokenStore.removeToken();
  router.push('/login'); 
  showLogoutDialog.value = false; 
};

const handleClose = (done) => {
  ElMessage({
    message: '对话框已关闭',
    type: 'warning'
  });
  done();
};
</script>



<template>
    <div class="common-layout">
        <el-container class="bg">
            <el-header>
                <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" :ellipsis="false"
          @select="handleSelect">
          <el-menu-item index="0" @click="router.push('/')">
            <el-icon><ShoppingTrolley /></el-icon>
            <img style="width: 100px" src="@/assets/logo2.jpg" alt="logo" />
          </el-menu-item>
          <span style="font-size: medium;">
              <el-avatar style="margin-top:5px" :src="userInfoModel.userPic"  />
            
            {{ userInfoModel.userType }}:{{ userInfoModel.username }}
          </span>
          <el-menu-item index="1" @click="router.push('/user/info')"><el-icon>
              <Avatar />
            </el-icon>我的</el-menu-item>
          <el-sub-menu index="2">
            <template #title>工具栏</template>
            <el-menu-item v-if="userInfoModel.userType==='商家'" index="2-1" @click="router.push('/user/goods')">我的商品</el-menu-item>
            <el-menu-item index="2-2" @click="router.push('/user/cart')">购物车</el-menu-item>
            <el-menu-item index="2-3" @click="showLogoutDialog = true;">
              <el-icon>
                <SwitchButton />
              </el-icon>
              退出登录
            </el-menu-item>
          </el-sub-menu>
        </el-menu>
        <el-dialog title="确认退出登录" v-model="showLogoutDialog" width="30%" :before-close="handleClose">
              <span>确定要退出登录吗?</span>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="showLogoutDialog = false">取消</el-button>
                  <el-button type="primary" @click="logout">确定</el-button>
                </span>
              </template>
            </el-dialog>
            </el-header>
            <el-main>
                <el-card style="max-width: 100%">
                    <template #header>
                        <div class="card-header">
                            <span>
                                <el-icon>
                                    <ShoppingBag />
                                </el-icon>
                                商品
                            </span>
                        </div>
                    </template>

                    <el-row :gutter="20">

                        <el-col :span="12">
                            <div class="grid-content ep-bg-purple" />
                            <img :src="goodsDetailModel.goodsImgUrl"
                                style="width: 80%" />
                        </el-col>
                        <el-col :span="12">
                            <div class="grid-content ep-bg-purple" />
                            <div style="font-size: 30px;margin-bottom: 30px;">{{ goodsDetailModel.goodsName }}</div>
                            商家:
                            <el-avatar style="margin-top:5px"
                                :src="goodsDetailModel.merchantImgUrl" />
                            {{ goodsDetailModel.merchantName }}
                            <div class="price" style="font-size: 50px;">{{ goodsDetailModel.goodsPrice }}¥</div>

                            <el-button type="danger" style="margin-top: 50px;" @click="ElMessage.success('成功购买该商品')">购买</el-button>
                            <el-button type="danger" style="margin-top: 50px;margin-left: 100px;" @click="addGoodsToCart()">添加到购物车</el-button>

                        </el-col>

                    </el-row>




                </el-card>
            </el-main>
        </el-container>
    </div>
    <hr>
    <div style="width: 300px;height: 200px;margin-left: auto;margin-right: auto;">
        <div style="margin-top: 100px;">
            <p style="text-align: center;margin-top: 10px;filter: opacity(50%);font-size: small;">迷你商城,本网站为练习网站。
                本站商品全在淘宝:"https://www.taobao.com"中获取,若对站内商品感兴趣,请到淘宝搜索相关商品并购买</p>
        </div>
    </div>
</template>




<style>
.el-menu--horizontal>.el-menu-item:nth-child(1) {
    margin-right: auto;
}

.bg {
    background-color: pink;
}

.el-menu-demo {
    background-color: coral;
}

.list div {
    display: inline-block;
    width: 300px;
    height: 300px;
}



.el-row {
    margin-bottom: 20px;
}

.el-row:last-child {
    margin-bottom: 0;
}

.el-col {
    border-radius: 4px;
}

.grid-content {
    border-radius: 4px;
    min-height: 36px;
}

.price {
    text-align: end;
    margin-top: 30%;
}
</style>

1.2.制定与后端接口交互的函数

/src/api/goods.js

export const getGoodsDetailService=(id)=>{
    return request.get('/goods/detail?id='+id)
}

1.3.效果展示

在这里插入图片描述

2.我的商品页面开发

2.1.搭建页面,绑定数据与函数

/src/views/user/UserGoods.vue

<script lang="ts" setup>
import { useUserInfoStore } from '@/stores/userInfo';
const userInfoStore = useUserInfoStore();
const userInfoModel= ref(userInfoStore.info)
import { ref } from 'vue'
import { useRouter } from 'vue-router';
const router=useRouter();
const activeIndex = ref('2-1')
const handleSelect = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}

import {userGoodsService} from "@/api/user"
const userGoodsList=ref([])
const userGoods=async()=>{
  let result =await userGoodsService();
  userGoodsList.value=result.data;
}
userGoods();


import { ElMessage } from 'element-plus';
import { Avatar,  SwitchButton } from '@element-plus/icons-vue';


import { useTokenStore } from '@/stores/token'; 
const tokenStore=useTokenStore();
const showLogoutDialog = ref(false);
const logout = () => {
  ElMessage.success('成功退出登录');
  tokenStore.removeToken();
  router.push('/login'); 
  showLogoutDialog.value = false; 
};

const handleClose = (done) => {
  ElMessage({
    message: '对话框已关闭',
    type: 'warning'
  });
  done();
};
</script>

<template>
  <div class="common-layout">
    <el-container class="bg">
      <el-header>
        <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" :ellipsis="false"
          @select="handleSelect">
          <el-menu-item index="0" @click="router.push('/')">
            <el-icon><ShoppingTrolley /></el-icon>
            <img style="width: 100px" src="@/assets/logo2.jpg" alt="logo" />
          </el-menu-item>
          <span style="font-size: medium;">
              <el-avatar style="margin-top:5px" :src="userInfoModel.userPic"  />
            
            {{ userInfoModel.userType }}:{{ userInfoModel.username }}
          </span>
          <el-menu-item index="1" @click="router.push('/user/info')"><el-icon>
              <Avatar />
            </el-icon>我的</el-menu-item>
          <el-sub-menu index="2">
            <template #title>工具栏</template>
            <el-menu-item v-if="userInfoModel.userType==='商家'" index="2-1" @click="router.push('/user/goods')">我的商品</el-menu-item>
            <el-menu-item index="2-2" @click="router.push('/user/cart')">购物车</el-menu-item>
            <el-menu-item index="2-3" @click="showLogoutDialog = true;">
                            <el-icon>
                                <SwitchButton />
                            </el-icon>
                            退出登录
                        </el-menu-item>
          </el-sub-menu>
        </el-menu>
        <el-dialog title="确认退出登录" v-model="showLogoutDialog" width="30%" :before-close="handleClose">
              <span>确定要退出登录吗?</span>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="showLogoutDialog = false">取消</el-button>
                  <el-button type="primary" @click="logout">确定</el-button>
                </span>
              </template>
            </el-dialog>
      </el-header>
      <el-main>

        <div style="font-size: 50px;">
          <el-icon>
            <GoodsFilled />
          </el-icon>
          我的商品

          <el-button type="danger" @click="router.push('/user/goods/add')">添加商品</el-button>
        </div>
        <el-descriptions direction="vertical" border style="margin-top: 20px" v-for="goods in userGoodsList">
          <el-descriptions-item :rowspan="2" :width="140" label="商品图片" align="center">
            <el-image style="width: 100px; height: 100px"
              :src="goods.goodsImgUrl" />
          </el-descriptions-item>

          <el-descriptions-item label="商品名/价格">
            {{goods.goodsName}}
            <span style="font-size: large;margin-left: 100px;">{{goods.goodsPrice}}¥</span>
          </el-descriptions-item>
          <el-descriptions-item label="商家">{{ goods.merchantName }}</el-descriptions-item>
        </el-descriptions>



      </el-main>
    </el-container>
  </div>
  <hr>
  <div style="width: 300px;height: 200px;margin-left: auto;margin-right: auto;">
    <div style="margin-top: 100px;">
      <p style="text-align: center;margin-top: 10px;filter: opacity(50%);font-size: small;">迷你商城,本网站为练习网站。
        本站商品全在淘宝:"https://www.taobao.com"中获取,若对站内商品感兴趣,请到淘宝搜索相关商品并购买</p>
    </div>
  </div>
</template>




<style>
.el-menu--horizontal>.el-menu-item:nth-child(1) {
  margin-right: auto;
}

.bg {
  background-color: pink;
}

.el-menu-demo {
  background-color: coral;
}
</style>

2.2.制定与后端接口交互的函数

/src/api/user.js

export const userGoodsService=()=>{
    return request.get('/user/myGoods')
}

2.3.效果展示

在这里插入图片描述

3.添加商品页面的开发

3.1.搭建页面,绑定数据与函数

/src/views/user/UserAddGoods.vue

<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

import type { UploadProps } from 'element-plus'

import { useUserInfoStore } from '@/stores/userInfo';
const userInfoStore = useUserInfoStore();
const userInfoModel = ref(userInfoStore.info)

const imageUrl = ref('')

const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response,
    uploadFile
) => {
    imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}



import { addGoodsService } from "@/api/goods"

const activeIndex = ref('1')
const handleSelect = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
}

import { useRouter } from 'vue-router';
const router = useRouter();
const price = ref()

const goodsAddModel = ref({
    goodsName: '',
    goodsImgUrl: '',
    goodsPrice: ''
})


const addGoods = async () => {
    await addGoodsService(goodsAddModel.value)
    ElMessage.success('添加成功')
}
const clearGoodsData = () => {
    goodsAddModel.value.goodsName = '';
    goodsAddModel.value.goodsImgUrl = '';
    goodsAddModel.value.goodsPrice = '';
}


import { Avatar, SwitchButton } from '@element-plus/icons-vue';


import { useTokenStore } from '@/stores/token';
const tokenStore = useTokenStore();
const showLogoutDialog = ref(false);
const logout = () => {
    ElMessage.success('成功退出登录');
    tokenStore.removeToken();
    router.push('/login');
    showLogoutDialog.value = false;
};

const handleClose = (done) => {
    ElMessage({
        message: '对话框已关闭',
        type: 'warning'
    });
    done();
};
</script>


<template>
    <div class="common-layout">
        <el-container class="bg">
            <el-header>
                <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" :ellipsis="false"
                    @select="handleSelect">
                    <el-menu-item index="0" @click="router.push('/')">
                        <el-icon>
                            <ShoppingTrolley />
                        </el-icon>
                        <img style="width: 100px" src="@/assets/logo2.jpg" alt="logo" />
                    </el-menu-item>
                    <span style="font-size: medium;">
                        <el-avatar style="margin-top:5px" :src="userInfoModel.userPic" />

                        {{ userInfoModel.userType }}:{{ userInfoModel.username }}
                    </span>
                    <el-menu-item index="1" @click="router.push('/user/info')"><el-icon>
                            <Avatar />
                        </el-icon>我的</el-menu-item>
                    <el-sub-menu index="2">
                        <template #title>工具栏</template>
                        <el-menu-item v-if="userInfoModel.userType === '商家'" index="2-1"
                            @click="router.push('/user/goods')">我的商品</el-menu-item>
                        <el-menu-item index="2-2" @click="router.push('/user/cart')">购物车</el-menu-item>
                        <el-menu-item index="2-3" @click="showLogoutDialog = true;">
                            <el-icon>
                                <SwitchButton />
                            </el-icon>
                            退出登录
                        </el-menu-item>
                    </el-sub-menu>
                </el-menu>
                <el-dialog title="确认退出登录" v-model="showLogoutDialog" width="30%" :before-close="handleClose">
              <span>确定要退出登录吗?</span>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="showLogoutDialog = false">取消</el-button>
                  <el-button type="primary" @click="logout">确定</el-button>
                </span>
              </template>
            </el-dialog>
            </el-header>
            <el-main>
                <el-card class="page-container" style="background-color: coral;">
                    <template #header>
                        <div class="header">
                            <span>添加商品</span>
                        </div>
                    </template>

                    <el-row>
                        <el-col :span="12">
                            <el-form label-width="100px" size="large">
                                <el-form-item label="商品名称">
                                    <el-input v-model="goodsAddModel.goodsName" type="textarea" />
                                </el-form-item>

                                <el-form-item label="商品图片地址">
                                    <el-input v-model="goodsAddModel.goodsImgUrl"></el-input>
                                </el-form-item>

                                <el-form-item label="商品价格">
                                    <el-input-number v-model="goodsAddModel.goodsPrice" :step="1" />
                                </el-form-item>

                                <el-form-item>
                                    <el-button type="primary" @click="addGoods(); clearGoodsData()">添加</el-button>
                                </el-form-item>
                            </el-form>
                        </el-col>
                    </el-row>
                </el-card>
            </el-main>
        </el-container>
    </div>
    <hr>
    <div style="width: 300px;height: 200px;margin-left: auto;margin-right: auto;">
        <div style="margin-top: 100px;">
            <p style="text-align: center;margin-top: 10px;filter: opacity(50%);font-size: small;">迷你商城,本网站为练习网站。
                本站商品全在淘宝:"https://www.taobao.com"中获取,若对站内商品感兴趣,请到淘宝搜索相关商品并购买</p>
        </div>
    </div>
</template>




<style>
.avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
    margin-bottom: 100px;
    margin-left: 200px;
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}

.el-menu--horizontal>.el-menu-item:nth-child(1) {
    margin-right: auto;
}

.bg {
    background-color: pink;
}

.el-menu-demo {
    background-color: coral;
}
</style>

3.2.制定与后端接口交互的函数

/src/api/user.js

export const userAddGoodsToCartService=(id)=>{
    return request.patch('/user/cart/add?id='+id);
}

3.3.效果展示

在这里插入图片描述

4.总结

​ 本期我们开发的商品详情、我的商品、添加商品这些页面。到此为止,我们前端的一些基本页面也都开发完毕了,这个网站的基本功能也都可以运行了。不过仍然有着很多细节以及功能还没有实现,对比我们第一期【全栈】SprintBoot+vue3迷你商城(1)提出的要求,还有用户上传、修改头像、搜索、分页等等功能没有实现,我会在以后陆续更新。而且之后肯定还会添加一些新的功能,我会在后面陆续更新。本人在这方面也是尝试阶段,有很多不懂的地方,希望边做边记录边进步。对于不足的地方,我会虚心接受大家的建议。


http://www.kler.cn/a/520216.html

相关文章:

  • < OS 有关 > 阿里云:轻量应用服务器 的使用 :轻量化 阿里云 vpm 主机
  • 网络安全 | F5-Attack Signatures-Set详解
  • SQL Server 建立每日自动log备份的维护计划
  • vue3+elementPlus之后台管理系统(从0到1)(day4-完结)
  • 人格分裂(交互问答)-我想懂Elasticsearch
  • RDMA 工作原理 | 支持 RDMA 的网络协议
  • 【深度之眼cs231n第七期】笔记(三十一)
  • 初学stm32 --- FreeRTOS移植
  • vue3中src的目录分析
  • Dev-C++分辨率低-解决办法
  • 2024年AI发展的感知回顾
  • STM32 ADC
  • 基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制
  • Python NumPy(2):NumPy 数组属性、创建数据
  • JWT实现单点登录
  • Sklearn 中的逻辑回归
  • 基于SpringBoot+WebSocket的前后端连接,并接入文心一言大模型API
  • vim如何设置自动缩进
  • RISC-V读书笔记3
  • Cursor 帮你写一个小程序
  • 关于安卓greendao打包时报错问题修复
  • 开放自己本机的mysql允许别人连接
  • coffee销售数据集分析:基于时间趋势分析的实操练习
  • 第04章 11 VTK中,Filter的多输入输出的示例说明
  • vue3 获取百度天气
  • Day32:字符串的复制