文章目录

  • 前言
    • 1、使用到的技术
    • 2、使用到的软件
    • 3、使用代码步骤
  • 一、首页
  • 二、分类列表
  • 三、商品列表
  • 四、商品详情
  • 五、加入购物车
  • 六、购物车列表

前言

1、使用到的技术

1-vant ui框架
2-less-css预编译语言
3-vue
4-vue router
5-vuex
6-axios
7-javascript
8-html5
9-css3
10-vue-cli
11-webpack

2、使用到的软件

1.visua lstudio code,官网https://code.visualstudio.com/
2.navicat


3、使用代码步骤

代码地址 链接:https://pan.baidu.com/s/1xVw9nVNf-Hg-N3S_3IoNvA 提取码:f786

1、用navicat创建一个新的数据库

导入数据库,运行SQL文件

导入mall-server文件下的nideshop.sql文件
导入成功后就会出现这些表(可能要等待一点时间)
** 2、使用visua lstudio code打开文件**

打开红线路径的文件,database是数据库名称、user,password是数据库账户和密码(需要改),prefix是表的前缀

把文件mall和mall-server,分别在终端打开。打开后输入npm install安装两个文件都要安装。(还需要安装vue依赖才能使用)
安装成功后,在mall-server输入npm start,在mall输入npm run serve(要是报错看下面)

如果报错Module build failed (from ./node_modules/babel-loader/lib/index.js)
意思是babel版本冲突
安装npm install @babel/core @babel/preset-env

再用浏览器打开这个地址

浏览器打开后

打开文件mall\src\views的Home.vue

<script>
//导入接口
import axios from 'axios'
import api from '../assets/config/api'
</script>

接口地址,mall/src/assets/config/api.js

ajax请求,返回后端数据库的数据


一、首页

1、Search 搜索

打开vant框架网站,基本用法
https://vant-contrib.gitee.io/vant/#/zh-CN/search

mall\src\views的Home.vue

//Home.vue
<van-search placeholder="商品搜索 共239万款好物" input-align='center' v-model="searchData" />
//导入vant
import Vue from 'vue';
import { Lazyload } from 'vant';
Vue.use(Lazyload);
export default {name: 'home',data:function(){return {//设置v-mode的值searchData:"", data:{},    }},}

2、Swipe 轮播

https://vant-contrib.gitee.io/vant/#/zh-CN/swipe

//Home.vue<van-swipe :autoplay="3000" :width="375" :height="200"><van-swipe-item v-for="(image, index) in images" :key="index"><img class="swiperimg" v-lazy="image.image_url" /></van-swipe-item></van-swipe><scrpet>export default {data:function(){return {searchData:"",data:{},}},computed: {images:function(){//判断ajax的data.banner是否为数组,是的话返回数组,不是的话返回空数组if(typeof this.data.banner=='object'){return this.data.banner}else{return []}},}}</scrpet><style lang="less">#home{.swiperimg{width: 375px;height: 200px;}}
<style>


3、5个图标

Grid 宫格https://vant-contrib.gitee.io/vant/#/zh-CN/grid

<van-grid :column-num='5'><van-grid-item v-for="(item,index) in channel"  :key="index" :icon="item.icon_url" :text="item.name" /></van-grid><script>export default {name: 'home',data:function(){return {searchData:"",data:{},}computed: {channel:function(){//判断ajax的data.channel是否为数组,是的话返回数组,不是的话返回空数组if(typeof this.data.channel=='object'){return this.data.channel}else{return []}},}}</script>


4、品牌制造商直供

图片懒加载
https://vant-contrib.gitee.io/vant/#/zh-CN/swipe

懒加载是一种网页性能优化的方式,它能极大的提升用户体验。就比如说图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很经常的事了。如果每次进入页面就请求所有的图片资源,那么可能等图片加载出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视区域的图片资源。

<div class="brandlist"><!-- Panel 面板 --><van-panel title="品牌制造商直供"><van-grid  :column-num="2"><van-grid-item v-for="(item1,index1) in brandList" :key="index1"><van-image fit="cover" lazy-load :src="item1.new_pic_url" /><h4 class="title">{{item1.name}}</h4><p class="price">{{item1.floor_price}}元起</p></van-grid-item></van-grid></van-panel></div><script>export default {name: 'home',data:function(){return {searchData:"",data:{},}computed: {brandList:function(){//判断ajax的data.brandList是否为数组,是的话返回数组,不是的话返回空数组if(typeof this.data.brandList=='object'){return this.data.brandList}else{    return []}},}}</script><style lang="less">.brandlist{.van-grid-item__content{padding: 0;}.van-image{border: 1px solid #fff;}.title{position: absolute;top: 20px;left: 10px;}.price{position: absolute;top: 40px;left: 10px;font-size: 14px;color:#999 ;}</style>

5、新品首发

   <!-- 新品首发 --><div class="newlist"><van-panel title="品牌制造商直供"><van-grid  :column-num="2"><van-grid-item v-for="(item2,index2) in newGoodsList" :key="index2"><van-image fit="cover" lazy-load :src="item2.list_pic_url" /><h4 class="title" >{{item2.name}}</h4><p class="price">{{item2.retail_price}}元起</p></van-grid-item></van-grid></van-panel></div><script>export default {name: 'home',data:function(){return {searchData:"",data:{},}computed: {newGoodsList:function(){//判断ajax的data.newGoodsList是否为数组,是的话返回数组,不是的话返回空数组if(typeof this.data.newGoodsList=='object'){return this.data.newGoodsList}else{return []}},}}<script><style>.newlist{.title{width: 90%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}.price{font-size: 14px;color:#999 ;}}![在这里插入图片描述](https://img-blog.csdnimg.cn/20200911153220161.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpYW9qdWFqdW4=,size_16,color_FFFFFF,t_70#pic_center)</style>


6、人气面板
Card 卡片
https://vant-contrib.gitee.io/vant/#/zh-CN/card

<div class="hotlist"><van-panel title="人气推荐"><van-card v-for="(item3,index3) in hotGoodsList" :key="index3":price="item3.retail_price":desc="item3.goods_brief":title="item3.name":thumb="item3.list_pic_url"/></van-panel></div><script>export default {name: 'home',data:function(){return {searchData:"",data:{},}computed: {hotGoodsList:function(){//判断ajax的data.hotGoodsList=是否为数组,是的话返回数组,不是的话返回空数组if(typeof this.data.hotGoodsList=='object'){return this.data.hotGoodsList}else{return []}},},}}<script><style>.hotlist{.van-card__content{justify-content: center;text-align:left;}.van-card__title{font-weight: 900;color: #333;font-size: 14px;padding: 5px 0;}.van-card__price{color: red;}}</style>

二、分类列表

1、创建分类列表的页面

//mall/src/router/index.js
{path:'/category',name:'category',component:Category},

在mall/scr/views,创建一个文件category.vue 然后导入页面

//mall/src/router/index.js
import Category from '@/views/category'

2、创建Tabbar 标签栏

Tabbar 标签栏https://vant-contrib.gitee.io/vant/#/zh-CN/tabbar#dai-ma-yan-shi


在mall/src/components,创建新的文件tabBtn.vue

//mall/src/components/tabBtn.vue
<template>
<van-tabbar v-model="tabActive"><van-tabbar-item icon="home-o">首页</van-tabbar-item><van-tabbar-item icon="medal-o">专题</van-tabbar-item><van-tabbar-item icon="qr">分类</van-tabbar-item><van-tabbar-item icon="shopping-cart-o">购物车</van-tabbar-item><van-tabbar-item icon="manager-o" badge="20">我的</van-tabbar-item></van-tabbar></template><script>export default {name: 'home',data:function(){return {tabActive:"0",}}</script>

引入tabBtn文件

//mall/src/views/Home.vue
import tabBtn from '@/components/tabBtn.vue'

把tabBar显示在页面上

//mall/src/views/Home.vue<tab-btn></tab-btn>

设置id为category,导入tabBa

//mall/src/views/category.vue
<template>
//设置id为category<div id="category">//  把tabBar放进来<tab-btn></tab-btn></div>
</template><script>//导入tabBarimport tabBtn from '@/components/tabBtn.vue'
export default {data(){return {          }},//导入components:{tabBtn}}   </script>

to跳转到分类页面category

//mall/src/components/tabBtn.vue<van-tabbar-item icon="home-o" to="/">首页</van-tabbar-item><van-tabbar-item icon="qr" to="/category">分类</van-tabbar-item>

监听路由变化,改变v-model的tabActive值

 mounted() {// 监听路由switch(this.$route.path){case "/category":this.tabActive = 2;break;case '/':this.tabActive = 0;break;default:this.tabActive = 0;}},

当点击分类时页面就会发生改变

3、分类选择

TreeSelect 分类选择
https://vant-contrib.gitee.io/vant/#/zh-CN/tree-select

4、ajax请求获取数据

//mall/src/views/category.vue
<template><div id="category"><van-search placeholder="商品搜索 共239万款好物" input-align='center' v-model="searchData" /><tab-btn></tab-btn></div>
</template>
<script>
import tabBtn from '@/components/tabBtn.vue'
import axios from 'axios'
import api from '@/assets/config/api.js'
export default {data(){return {searchData:"",}},async created() {// ajax请求let res = await axios.get(api.CatalogList)let data = res.data;console.log(data)},components:{tabBtn}}
</script>

data里面的categoryList数据

还有里面的子数据subCategoryList

5、获取数组categoryList,并进行循环

//mall/src/views/category.vue
<template><div id="category"><van-search placeholder="商品搜索 共239万款好物" input-align='center' v-model="searchData" /> <van-tree-select:items="items":main-active-index.sync="activeIndex">//子内容,九宫格<template slot="content">            </template><tab-btn></tab-btn></div>
</template>
<script>
import tabBtn from '@/components/tabBtn.vue'
import axios from 'axios'
import api from '@/assets/config/api.js'
export default {data(){return {searchData:"",activeIndex: 0,data:{},}},async created() {// ajax请求let res = await axios.get(api.CatalogList)let data = res.data;this.data = data.data;},computed: {items:function(){//判断ajax的data.categoryList是否undefined,是的话返回空数组,不是的话返回数组进行循环if(this.data.categoryList==undefined){return []}else{// console.log(123)let arr = []//对数据进行循环this.data.categoryList.forEach((item,index)=>{// console.log(index)item.text = item.name// 修改数据arr.push(item)})// 返回数组arrreturn arr;}components:{tabBtn}}

6、修改分类选择的高度

//mall/src/views/category.vue<van-tree-select:items="items":main-active-index.sync="activeIndex"//减去搜索框和标签栏高度height='calc(100vh - 104px)'@click-nav='changeRight'>

7、添加点击事件@click-nav,获取回调参数index

//mall/src/views/category.vue
<van-tree-select:items="items":main-active-index.sync="activeIndex"height='calc(100vh - 104px)'@click-nav='changeRight'><script>methods: {//点击事件获取activeIndex索引值changeRight:function(index){console.log(index)  }},</script>

8、监听activeIndex改变,获取categoryList的id

//mall/src/views/category.vue// 监听activeIndex改变watch: {activeIndex:async function(){//判断有没有数据,没有的话返回空数组if(this.items.length!==0){//通过当前的id去请求数据let id = this.items[this.activeIndex].idconsole.log(id)}else{this.subCategoryList =  []}}},

    watch: {activeIndex:async function(){//判断有没有数据,没有的话返回空数组if(this.items.length!==0){//通过当前的id去请求数据let id = this.items[this.activeIndex].id// console.log(id)//通过id请求数据//传参需要里面写对象paramslet res = await axios.get(api.CatalogCurrent,{params:{id}})console.log(res)this.subCategoryList = res.data.data.currentCategory.subCategoryList//获取九宫格上面的图片地址this.bannerImg = this.data.currentCategory.img_url;}else{this.subCategoryList =  []}}},

9、将数据渲染在九宫格上

//自定义内容,九宫格<template slot="content"><div class='imgbanner'><img width="100%" :src="bannerImg" alt=""></div><van-grid :column-num="3"><van-grid-item v-for="(item,index) in subCategoryList" :key="index" :icon="item.wap_banner_url" :text="item.name" :to="'/categoryList/'+item.id" ></van-grid-item></van-grid></template>

三、商品列表

1、标签页

Tab 标签页,标签栏滚动
https://vant-contrib.gitee.io/vant/#/zh-CN/tab

在mall/src/views创建新的页面categorylist.vue

//mall/src/views/categorylist.vue
<template><div id="categoryList">
<van-tabs v-model="active"><van-tab title="标签 1">内容 1</van-tab><van-tab title="标签 2">内容 2</van-tab><van-tab title="标签 3">内容 3</van-tab><van-tab title="标签 4">内容 4</van-tab>
</van-tabs></div>
</template><script>
export default {//设定propsprops:['id'],data(){return {tabActive:0,}},created() {console.log(this.id)}}
</script>

2、在index.js设置props

//mall/src/router/index.js
import categorylist from '@/views/categorylist'
{path:'/categorylist/:id',name:'categorylist',component: categorylist,//通过props传进来,props改为trueprops:true}

**3、在main.js进行全局导入**

//mall/src/main.js
import api from '@/assets/config/api.js'
new Vue({data:{api:api}
})
<script>
//mall/src/views/categorylist.vue
import axios from 'axios'
export default {//设定propsprops:['id'],data(){return {tabActive:0,}},created() {console.log(this.$root.api)}}
</script>

然后就能得到数据


**4、获取数据**

<script>
//mall/src/views/categorylist.vue
import axios from 'axios'
export default {//设定propsprops:['id'],data(){return {tabActive:0,}
/    },created() {let res = await axios.get(this.$root.api.GoodsCategory,{params:{id:this.id}})console.log(res.data)}}
</script>

5、将数据渲染在页面上

<template><div id="categoryList">
<van-tabs v-model="tabActive"><van-tab v-for="(item,index) in clist" :key="index":title="item.name"><h3>{{item.name}}</h3><p>{{item.front_name}}</p></van-tab>
</van-tabs></div>
</template><script>
import axios from 'axios'
export default {//设定propsprops:['id'],data(){return {tabActive:0,clist:[]}},async created() {// console.log(this.id)// console.log(this.$root.api)let res = await axios.get(this.$root.api.GoodsCategory,{params:{id:this.id}})this.clist = res.data.data.brotherCategoryconsole.log(res.data)}, }
</script>

6、获取商品列表数据

async created() {//ajax请求let res = await axios.get(this.$root.api.GoodsCategory,{params:{id:this.id}})console.log(res.data)this.clist = res.data.data.brotherCategorylet id = this.clist[0].id;this.clist.forEach(async (item,index)=>{//获取函数getlist的数据item.plist= await this.getlist(item.id,1)console.log(item.plist)this.$forceUpdate()})},methods: {async getlist(cid,page){let res = await axios.get(`${this.$root.api.GoodsList}?categoryId=${cid}&page=${page}&size=20`)console.log(res)return res.data.data},},

**7、将商品列表的数据渲染在页面上**

//mall/src/views/categorylist.vue
<template><div id="categoryList">//Tab 标签页<van-tabs v-model="tabActive"><van-tab v-for="(item,index) in clist" :key="index":title="item.name"><h3>{{item.name}}</h3><p>{{item.front_name}}</p><div v-if="item.plist">//九宫格<van-grid :border="true" :column-num="2">         <van-grid-item   v-for="(item1,index1) in item.plist.data" :to="'/product/'+item1.id" :key="index1"><van-imagewidth="100"height="100":src="item1.list_pic_url"/><h4 class="van-ellipsis">{{item1.name}}</h4><p class="price">¥{{item1.retail_price}}</p></van-grid-item></van-grid></div></van-tab></van-tabs></div>
</template><script>
import axios from 'axios'
export default {//设定propsprops:['id'],data(){return {tabActive:0,clist:[]}},async created() {//ajax请求let res = await axios.get(this.$root.api.GoodsCategory,{params:{id:this.id}})console.log(res.data)this.clist = res.data.data.brotherCategorylet id = this.clist[0].id;this.clist.forEach(async (item,index)=>{//获取函数getlist的数据item.plist= await this.getlist(item.id,1)console.log(item.plist)this.$forceUpdate()})},methods: {async getlist(cid,page){let res = await axios.get(`${this.$root.api.GoodsList}?categoryId=${cid}&page=${page}&size=20`)console.log(res)return res.data.data},},}
</script><style lang="less">#categoryList{.van-ellipsis{width: 100%;font-size: 14px;font-weight: 500;padding: 0 10px;}.van-grid-item{overflow: hidden;box-sizing: border-box;}.price{color:red;}}
</style>

四、商品详情

1、新建页面

在mall/src/views新建一个页面product.vue

//mall/src/views/product.vue
<template><div><h1>product</h1></div>
</template>

在categorylist.vue ,设置路由入口to

//mall/src/views/categorylist.vue    <van-grid-item   v-for="(item1,index1) in item.plist.data" :to="'/product/'+item1.id" :key="index1">


2、NavBar 导航栏
https://vant-contrib.gitee.io/vant/#/zh-CN/nav-bar

van-nav-bartitle="商品"left-text="返回"left-arrow@click-left="onClickLeft"/>methods:{onClickLeft:function(){this.$router.go(-1);},

3、轮播


<van-swipe :autoplay="3000"><van-swipe-item v-for="(image, index) in images" :key="index"><img class="swipeImg" v-lazy="image.img_url" /></van-swipe-item></van-swipe>computed:{images:function(){if(this.data.gallery==undefined){return []}else{return this.data.gallery;}}},export default {props:['id'],data() {return {data:{},}
async created(){this.$store.dispatch('AjaxCart');let res = await axios.get(this.$root.api.GoodsDetail,{params:{id:this.id}})console.log(res.data)this.data = res.data.data;}}.swipeImg{width: 100%;}


4、0天无忧退货

 <div class='info'><span>30天无忧退货</span><span>48小时快速退款</span><span>满88元免邮费</span></div>.info{display: flex;justify-content: space-around;font-size: 12px;color: #999;height: 24px;line-height: 24px;background: #efefef;span{position: relative;}span::before{content:"";display: block;position: absolute;left: -10px;top: 8px;width: 4px;height: 4px;border-radius: 2px;border: 1px solid red;}

5、商品参数


<van-cell title="请选择规格数量" is-link /><div class="proParams"><h3>商品参数</h3><div class="proItem" v-for="(item1,index1) in attribute" :key="index1"><span class="title">{{item1.name}}</span><span class="value">{{item1.value}}</span></div></div>async created(){this.attribute = this.data.attribute;}.van-cell__title{text-align: left;}.proItem{width: 90%;margin: 0 auto;display: flex;justify-content: space-between;height: 24px;color: #999;font-size: 12px;background: #efefef;line-height: 24px;text-align: left;span.title{width:45px;padding: 0 10px;border-right: 1px solid #ccc;}span.value{width: 260px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}}


6、商品详情

//引入html
<div class="proDetail" v-html="info.goods_desc"></div>.proDetail{width: 100%;img{width: 100%}p{margin: 0;padding: 0;display: flex;}}

五、加入购物车

1、GoodsAction 商品导航
https://vant-contrib.gitee.io/vant/#/zh-CN/goods-action


Sku 商品规格
https://vant-contrib.gitee.io/vant/#/zh-CN/sku

2、修改加入购物车时的商品规格sku

         //商品导航<van-goods-action><van-goods-action-icon to="/buycart" :info="$store.state.cartTotal.goodsCount==0?'':$store.state.cartTotal.goodsCount" icon="cart-o" text="购物车" /><van-goods-action-icon icon="star-o" text="已收藏"  /><van-goods-action-button @click="chooseSku" type="warning" text="加入购物车" /><van-goods-action-button type="danger" text="立即购买" /></van-goods-action>//选择商品规格<<van-skuv-model="showSku":sku="sku":goods="goods"@buy-clicked="onBuyClicked"@add-cart="onAddCartClicked"/></div>export default {props:['id'],data(){return {data:{},info:{},attribute:[],showSku:false,sku:sku,   goods: {// 商品标题title: '测试商品',// 默认商品 sku 缩略图picture: 'https://img.yzcdn.cn/1.jpg'   }}  let sku = {// 所有sku规格类目与其值的从属关系,比如商品有颜色和尺码两大类规格,颜色下面又有红色和蓝色两个规格值。// 可以理解为一个商品可以有多个规格类目,一个规格类目下可以有多个规格值。tree: [{k: '颜色', // skuKeyName:规格类目名称v: [{id: '30349', // skuValueId:规格值 idname: '红色', // skuValueName:规格值名称},{id: '1215',name: '蓝色',}],k_s: 's1' // skuKeyStr:sku 组合列表(下方 list)中当前类目对应的 key 值,value 值会是从属于当前类目的一个规格值 id}],// 所有 sku 的组合列表,比如红色、M 码为一个 sku 组合,红色、S 码为另一个组合list: [{id: 2259, // skuId,下单时后端需要price: 100, // 价格(单位分)'s-1': '2', // 规格类目 k_s 为 s1 的对应规格值 id's-2': '3', // 规格类目 k_s 为 s2 的对应规格值 idstock_num: 110 // 当前 sku 组合对应的库存},{id: 2259, // skuId,下单时后端需要price: 100, // 价格(单位分)'s-1': '1', // 规格类目 k_s 为 s1 的对应规格值 id's-2': '4', // 规格类目 k_s 为 s2 的对应规格值 idstock_num: 130 // 当前 sku 组合对应的库存}],price: '1.00', // 默认价格(单位元)stock_num: 227, // 商品总库存}}

添加点击事件,控制商品规格的显示,showSku为true弹出,,showSku为flase收起

 methods:{    //商品规格按钮 onBuyClicked:function(){// 将当前的内容提交到订单页this.showSku = false;},//购物车按钮chooseSku(){this.showSku = true;}

把数据库数据商品图片和价格放进去sku里面

async created(){     //把商品图片名字从数据放在页面上this.goods.picture = this.info.primary_pic_url;this.goods.title = this.info.name;//修改价格this.sku.price = this.info.retail_price;//修改剩余数this.sku.stock_num = this.info.goods_number;}

从specificationList拿到数据后,进行循环再赋值给sku(其他商品specificationList可能是空,这会导致sku无效,) 下图的商品specificationList有数据

  async created(){this.$store.dispatch('AjaxCart');let res = await axios.get(this.$root.api.GoodsDetail,{params:{id:this.id}})console.log(res.data)this.data = res.data.data;this.info = this.data.info;this.attribute = this.data.attribute;this.goods.picture = this.info.primary_pic_url;this.goods.title = this.info.name;this.sku.price = this.info.retail_price;this.sku.stock_num = this.info.goods_number;//将数据进行循环let tree = []this.data.specificationList.forEach((item,index)=>{let arr = []item.valueList.forEach((product,i)=>{arr.push({id: product.id, // skuValueId:规格值 idname: product.value, // skuValueName:规格值名称})})
//  把数据放到sku里面tree.push({k: item.name, // skuKeyName:规格类目名称v: arr,k_s: "s-"+item.specification_id // skuKeyStr:sku 组合列表(下方 list)中当前类目对应的 key 值,value 值会是从属于当前类目的一个规格值 id})})this.sku.tree = tree;}
}

然后再添加list数组,不然商品规格无法选取,变成灰色

let sku ={list: [{id: 2259, // skuIds1: '1', // 规格类目 k_s 为 s1 的对应规格值 ids2: '1', // 规格类目 k_s 为 s2 的对应规格值 idprice: 100, // 价格(单位分)stock_num: 110 // 当前 sku 组合对应的库存},{id: 2259, // skuId's-1': '2', // 规格类目 k_s 为 s1 的对应规格值 id's-2': '3', // 规格类目 k_s 为 s2 的对应规格值 idprice: 110, // 价格(单位分)stock_num: 110 // 当前 sku 组合对应的库存},{id: 2259, // skuId's-1': '1', // 规格类目 k_s 为 s1 的对应规格值 id's-2': '4', // 规格类目 k_s 为 s2 的对应规格值 idprice: 110, // 价格(单位分)stock_num: 130 // 当前 sku 组合对应的库存}],}

3、把商品数据放进购物车
点击事件获取回调函数,获取商品规格

onAddCartClicked(skuData){console.log(skuData)}

获取goods_id、goods_number…

onAddCartClicked(skuData){this.showSku = false;// console.log(skuData)let chooseContent = skuData.selectedSkuComb['s-1']+'_'+skuData.selectedSkuComb['s-2']console.log(chooseContent)let resultPro = this.data.productList.filter((item,index)=>{//判断选择的内容是否等于服务器内容。if(item.goods_specification_ids==chooseContent){return true}else{return false}})console.log(resultPro)},

加入购物车的数量selectedNum

把商品规格数据通过ajax发到后端(如果用户发送数据,会显示用户的特定值)

let cartRes = await axios.post(this.$root.api.CartAdd,{ goodsId:resultPro[0].goods_id , number: skuData.selectedNum, productId: resultPro[0].id })

apj接口

let cartRes = await axios.post(this.$root.api.CartAdd,{ goodsId:resultPro[0].goods_id , number: skuData.selectedNum, productId: resultPro[0].id })let data = cartRes.data.dataconsole.log(cartRes.data)

商品的数量,总价格

将购物车数据放到全局使用

//mall/scr/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)import api from '@/assets/config/api.js'
import axios from 'axios'
export default new Vuex.Store({state: {cartTotal:{goodsCount: 0,goodsAmount: 0,checkedGoodsCount: 0,checkedGoodsAmount: 0},cartList:[],},mutations: {setCarList:function(state,cartList){state.cartList = cartList},setCartTotal:function(state,cartTotal){state.cartTotal = cartTotal}},actions: {AjaxCart:async function(content){let cartRes = await axios.get(api.CartList)// console.log(cartRes.data)content.commit('setCarList',cartRes.data.data.cartList)content.commit('setCartTotal',cartRes.data.data.cartTotal)}},modules: {}
})
     //三元运算<van-goods-action-icon :info="$store.state.cartTotal.goodsCount==0?'':$store.state.cartTotal.goodsCount" icon="cart-o" text="购物车" />export default {methods:{async onAddCartClicked(skuData){// 修改提交let data = cartRes.data.datathis.$store.commit('setCarList',data.cartList),this.$store.commit('setCartTotal',data.cartTotal)}async created(){// 调用mall/scr/store/index.js的AjaxCartthis.$store.dispatch('AjaxCart');}}

这是点击加入购物车,选择商品规格,这样就能将总商品数显示在购物车上

六、购物车列表

1、新建购物车页面

//mall/src//views/buycart.vue
<template><div id="buycart"><div class='info'><span>30天无忧退货</span><span>48小时快速退款</span><span>满88元免邮费</span></div></div>
</template>style lang="less">
//mall/src//views/product.vue#buycart{.info{display: flex;justify-content: space-around;font-size: 12px;color: #999;height: 24px;line-height: 24px;background: #efefef;span{position: relative;}span::before{content:"";display: block;position: absolute;left: -10px;top: 8px;width: 4px;height: 4px;border-radius: 2px;border: 1px solid red;}}}</style>

在product.vue页面商品导航加上进入购物车页面的入口

//mall/src//views/product.vue
<van-goods-action-icon to="/buycart" :info="$store.state.cartTotal.goodsCount==0?'':$store.state.cartTotal.goodsCount" icon="cart-o" text="购物车" />

设置路由

//mall/src/router/index.jsimport buycart from '@/views/buycart'{path:"/buycart",name:"buycart",component:buycart}

2、获取购物车的商品规格数据

//mall/src//views/buycart.vue
//导入//mall/scr/store/index.js数据
import {mapState} from 'vuex';
import axios from 'axios'//导入mall/scr/store/index.js里面的'cartTotal','cartList'
let mapStateObj = mapState(['cartTotal','cartList'])
export default {data(){return {}},computed:{//解析构造...mapStateObj,},created(){//获取mall/scr/store/index.js里面的'AjaxCart'数据this.$store.dispatch('AjaxCart')},mounted(){//输出mall/scr/store/index.js的cartListconsole.log(this.cartList)},}

输出this.cartList(点击购物车才会出来,刷新页面没有反应)

3、列表

Card 卡片 https://vant-contrib.gitee.io/vant/#/zh-CN/card

Checkbox 复选框
https://vant-contrib.gitee.io/vant/#/zh-CN/checkbox

把cartList的数据渲染到页面上

  <div class="list"><div class="cartItem" v-for="(item,index) in cartList" :key="index">// 复选框<van-checkbox v-model="item.checked"></van-checkbox>//fit='cover'填充模式<van-imagefit='cover'width="70"height="70":src="item.list_pic_url"/><div class="proBrief"><div class="title"><span>{{item.goods_name}}</span> <span class="num">X{{item.number}}</span></div><p class="brief">{{item.goods_specifition_name_value}}</p><p class="price">¥ {{item.retail_price}}</p></div></div></div><style lang="less">#buycart{.info{display: flex;justify-content: space-around;font-size: 12px;color: #999;height: 24px;line-height: 24px;background: #efefef;span{position: relative;}span::before{content:"";display: block;position: absolute;left: -10px;top: 8px;width: 4px;height: 4px;border-radius: 2px;border: 1px solid red;}}.cartItem{padding: 0 5px;display: flex;align-items: center;padding: 10px 5px;.van-checkbox{margin: 0 5px;}.van-image{background: #efefef;}.proBrief{flex: 1;display: flex;flex-direction: column;justify-content: space-between;align-items: flex-start;height: 70px;padding: 0 10px;.title{width: 100%;font-size: 14px;display: flex;justify-content: space-between;}.brief{color: #999;font-size: 12px;}}}}</style>

把数据渲染到提交订单上

  <van-submit-bar:price="cartTotal.checkedGoodsAmount*100"button-text="提交订单"@submit="onSubmit"><van-checkbox v-model="checkedAll">全选</van-checkbox></van-submit-bar>

SubmitBar 提交订单栏
https://vant-contrib.gitee.io/vant/#/zh-CN/submit-bar


<van-checkbox v-model="checkedAll">全选</van-checkbox>computed:{checkedAll:{set(val){console.log(val,'设置全选')},get(){//选中的数量goodsCount是否==checkedGoodsCountif(this.cartTotal.goodsCount==this.cartTotal.checkedGoodsCount){return true;}else{return false;}}},...mapStateObj,},


给复选框添加点击事件

<van-checkbox @change="checkEvent($event)" v-model="item.checked"></van-checkbox>checkEvent:async function(event){console.log(event)}

在@change="checkEvent"里传入参数

               <van-checkbox @change="checkEvent($event,item)" v-model="item.checked"></van-checkbox>checkEvent:async function(event,item){console.log(event)console.log(item)}

输出item,其中checked为true,表示选中

修改发送并储存isChecked,productIds值。isChecked改为1或者0

   checkEvent:async function(event,item){// console.log(event)// console.log(item)let res = await axios.post(this.$root.api.CartChecked,{isChecked: Number(event),productIds: item.product_id})let data = res.data.dataconsole.log(data)this.$store.commit('setCarList',data.cartList),this.$store.commit('setCartTotal',data.cartTotal)}

这样页面刷新复选框的选择也不会改变

选择的商品总价也会自动更新

vue之仿网易严选详解相关推荐

  1. 小程序 node.js mysql_基于Node.js+MySQL开发的开源微信小程序B2C商城(页面高仿网易严选)...

    高仿网易严选的微信小程序商城(微信小程序客户端) 界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易严选商城 功能和数据库参考ecshop 服务端api基于Node.js+Think ...

  2. node 小程序 php,基于Node.js+MySQL开发的开源微信小程序B2C商城(页面高仿网易严选)...

    高仿网易严选的微信小程序商城(微信小程序客户端) 界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易严选商城 功能和数据库参考ecshop 服务端api基于Node.js+Think ...

  3. 07 仿网易严选微信小程序商城

    仿网易严选微信小程序商城 一.代码 一.代码 github,国外最大的开源项目中心,https://www.oschina.net/ 码云,https://gitee.com/?from=osc-in ...

  4. 基于Node.js+MySQL开发的开源微信小程序B2C商城(页面高仿网易严选)

    高仿网易严选的微信小程序商城(微信小程序客户端) 界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易严选商城 功能和数据库参考ecshop 服务端api基于Node.js+Think ...

  5. Node.js+MySQL开发的B2C商城系统源码+数据库(微信小程序端+服务端),界面高仿网易严选商城

    下载地址:Node.js+MySQL开发的B2C商城系统源码+数据库(微信小程序端+服务端) NideShop商城(微信小程序端) 界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易 ...

  6. 基于Node.js+MySQL开发的开源微信小程序B2C商城(页面高仿网易严选) 1

    高仿网易严选的微信小程序商城(微信小程序客户端) 界面高仿网易严选商城(主要是2016年wap版) 测试数据采集自网易严选商城 功能和数据库参考ecshop 服务端api基于Node.js+Think ...

  7. keep alive PHP,vue中keep-alive使用方法详解

    这次给大家带来vue中keep-alive使用方法详解,vue中keep-alive使用的注意事项有哪些,下面就是实战案例,一起来看一下. 1.keep-alive的作用以及好处 在做电商有关的项目中 ...

  8. php动态写入vue,Vue自定义动态组件使用详解

    这次给大家带来Vue自定义动态组件使用详解,Vue自定义动态组件的注意事项有哪些,下面就是实战案例,一起来看一下. 现在基于vue的UI组件库有很多,比如iview,element-ui等.但有时候这 ...

  9. html 仿word页面,HTML+CSS入门 HTML页面仿WORD样式详解

    本篇教程介绍了HTML+CSS入门 HTML页面仿WORD样式详解,希望阅读本篇文章以后大家有所收获,帮助大家HTML+CSS入门. < 要求不再浏览器中添加office插件的前提下.展示WOR ...

  10. Vue的生命周期过程详解

    Vue的生命周期 Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.销毁等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的 ...

最新文章

  1. 安卓mysql导出excel_Android开发实现的导出数据库到Excel表格功能【附源码下载】...
  2. [云炬python3玩转机器学习] 5-6最好的衡量线性回归法的指标: R Squared
  3. 闲话 - 火车硬座座位分布图
  4. LeetCode题解-23 合并K个排序链表 Hard
  5. 一文了解元宇宙最新发展
  6. 深信服单点登入代理服务取AD
  7. nc 模拟服务器_Linux网络利器netcat/nc
  8. 从零开始学android
  9. 用人话说说希尔伯特空间??
  10. 显微镜C接口_激光共聚焦扫描显微镜搭建DIY
  11. 质量功能展开(QFD)基础知识必备
  12. oracle autovue是什么软件,AutoVue
  13. OpenGL ES 与原生窗口之间的接口——EGL
  14. 数据挖掘竞赛预测模型——五折交叉验证
  15. 谷歌搜索中一些十分有趣的特效现象
  16. Linux系统下的文件传输
  17. 【网络安全】——服务端安全(注入攻击、认证与会话管理和访问控制、访问控制、加密算法与随机数、Web框架安全、应用层拒绝服务攻击DDOS)
  18. 强化网络互连设备安全配置脚本
  19. Axure RP9——【导航栏二级菜单的展开效果】
  20. 联邦滤波matlab程序,联邦滤波器仿真

热门文章

  1. 7.09—057—周二
  2. 计算机控制实验室装置,自控/计控原理实验箱 实验仪 实验装置 教学实训设备...
  3. 数据库系统概念第6版第三章答案
  4. STM32+SIM800C采用MQTT协议登录OneNet上传温湿度、MQ2烟雾浓度、GPS数据
  5. 一维码与二维码对比介绍
  6. 2020美亚团队赛复盘
  7. Android input touchpanel双击灭屏
  8. 电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析)
  9. 基于切比雪夫多项式的简单GCN网络
  10. 计算机鼠标左右键作用,鼠标的左右键的用途