电商APP:axios封装+Vuex=列表页面+详情页面+购物车

1、axios封装在src 中创建network文件夹并创建三个文件

在这里插入图片描述

2、创建core文件放主接口 ,创建APIConfig存放数据接口,创建index文件放请求方式 ,并抛出在main.js中设定

core文件

//网络模块核心代码
import axios from "axios";
import {Loading,Message} from "element-ui";
import {METHOD} from "./APIConfig";


//创建配置axios实例
const intance = axios.create({
  baseURL:"http://api.kudesoft.cn/",
  timeout:10000,
  //设置axios为form-data
  headers:{'Content-Type':'application/x-www-form-urlencoded'},

  transformRequest:[function (data) {
   let ret = ''
   for (let it in data) {
     ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
   }
   return ret
 }]

});


// 添加响应拦截器
intance.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  setTimeout(() => {
    // loading.close();
  }, 2000);
  return response;
}, function (error) {
  // 对响应错误做点什么
  Message(error);
  console.log("========>",error);
  return Promise.reject(error);
});

export function request(method,url,params){
  switch(method){
    case METHOD.GET:
      return get(url,params);
    case METHOD.POST:
      return post(url,params);
  }
}

//核心请求方法
function get(url,params){
  return intance.get(url,params)
}

function post(url,params){
  return intance.post(url,params)
}

APIConfig文件

import { request } from "./core"

export const METHOD ={
    POST:"POST",
    GET:"GET"
}
export const PATH = {
    getStoreList(params){return request(GET,path.list,params)},
    demon:"tdk/goods", //列表页面数据
    details:"tdk/details"//详情页面数据

}

index文件

import {request} from "./core";
import {METHOD,PATH} from "./APIConfig";

const APIClient = {
        godemon(params){
            return request (METHOD.GET,PATH.demon,params)
        },
        godetails(params){
            return request (METHOD.GET,PATH.details,params)
        },




}

export default APIClient

main配置

import APIClient from "./network/index"
Vue.prototype.$network = APIClient;

Vue.prototype.$APIClient = APIClient;

列表页面 和Vuex拆分

在这里插入图片描述
代码如下:

<template>
  <div>
 <!-- 搜索栏 -->
    <van-search placeholder="请输入搜索关键词" />
    <van-tabs v-model="active">
      <van-tab title="女装"></van-tab>
      <van-tab title="男装"></van-tab>
      <van-tab title="童鞋"></van-tab>
      <van-tab title="婴幼儿"></van-tab>
      <van-tab title="运动"></van-tab>

      <van-tab title="鞋包"></van-tab>

      <van-tab title="美食"></van-tab>
    </van-tabs>

<!-- 轮播图 -->
    <van-swipe class="my-swipe" :autoplay="1000" indicator-color="white">
      <van-swipe-item>
        <img src="../assets/lun1.png" width="100%" height="230px" class="img1" />
      </van-swipe-item>
      <van-swipe-item>
        <img src="../assets/lun2.png" width="100%" height="230px" class="img1" />
      </van-swipe-item>
      <van-swipe-item>
        <img src="../assets/lun3.png" width="100%" height="230px" class="img1" />
      </van-swipe-item>
      <van-swipe-item>
        <img src="../assets/lun1.png" width="100%" height="230px" class="img1" />
      </van-swipe-item>
    </van-swipe>
    <!-- //列表数据 -->
    <div v-for="(item,index) in list" :key="index" class="box" @click="goto(item.id)">
    
        <p><img :src="item.mainPic" alt width="180px" height="190px" /></p>

       <p>     {{item.title}} </p> 
       原价¥<s class="yuan">{{item.originalPrice}} </s> &nbsp; 现价¥<span class="jia">   {{item.actualPrice}} </span>
 </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      active: 2,
      // list: []
    };
  },

  mounted() {
    //通过axios封装获取的数据
    // this.$network
    //   .godemon({
    //     page: 1,
    //     pageSize: 4
    //   })
    //   .then(res => {
    //     console.log(res.data.data.data.list);
    //     this.list = res.data.data.data.list;
    //   });
      //
      this.$store.dispatch("todemon")
     

  },
    //在Vuex中获取 展示页面
  computed:{
      list:function(){
        return this.$store.state.godemon.list
      }
  },
  methods:{
      //获取id 跳转到详情页面
      goto(id){
        this.$router.push({
          path:"/details",
          query:{
            id
          }
        })
      }

  }
      
};
</script>
<style scoped>
.img1 {
  border-radius: 30px;
}
.box {
  width: 48%;
  float: left;
  font-size: 14px;
  /* display: flex;
  justify-content: space-between; */
  margin-left: 2px;
}
.jia{
  color:red
}
.yuan{
  color: gray;
  font-size: 12px;
}
</style>

## Vuex拆分 在store中创建 demon
代码:
import network from "../network/index"

const godemon = {
    state:{
        list:[]
    },
    mutations:{
        todemon(state,item){
            state.list=item
        }
    },

    actions:{
        todemon(text){
        network.godemon({
        page: 1,
        pageSize: 4
      })
      .then(res => {
        // window.console.log(res.data.data.data.list);
        text.commit ("todemon",res.data.data.data.list) 
      });
        }
    }


}

    export default godemon

在index 中接收

代码:

import Vue from 'vue'
import Vuex from 'vuex'
import godemon from "./demom"

import deta from "./details"

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    godemon,
    
  }
})

详情页面

在这里插入图片描述
代码:

<template>
  <div>
    <!-- 返回按钮 -->
    <van-nav-bar title="详情页面" left-text="返回" left-arrow @click-left="onClickLeft" />
    <!-- 轮播图 -->
    <van-swipe class="my-swipe" :autoplay="1000" indicator-color="white">
      <van-swipe-item v-for="(img,index) in goods" :key="index">
        <img :src="img" alt width="360px" height="280px" />
      </van-swipe-item>
    </van-swipe>

    <div>
      <!-- 详情渲染 -->
      <p>{{good.title}}</p>
      <p class="fu">{{good.dtitle}}</p>

      <p>
        <s class="yuan">原价:¥{{good.originalPrice}}</s>
        <span class="juan">领劵后:¥{{good.actualPrice}}</span>
      </p>

      <img v-for="(url,index) in good" :key="index" :src="url" alt width="360px" />
    </div>

    <van-goods-action>
      <van-goods-action-icon icon="chat-o" text="客服" color="#07c160" />
      <van-goods-action-icon icon="cart-o" text="购物车" :badge="cart.length" @click="go" />
      <van-goods-action-icon icon="star" text="已收藏" color="#ff5000" />
      <van-goods-action-button type="warning" text="加入购物车" @click="gou" />
      <van-goods-action-button type="danger" text="立即购买" />
    </van-goods-action>
  </div>
</template>

<script>
export default {
  data() {
    return {
      goods: [],
      good: [],
      show: false,
      cart: []
    };
  },

  // computed:{
  //   good:function(){
  //     return this.$store.state.deta.good
  //   }
  // },
  mounted() {
    // 接受列表id 和axios渲染
    let id = this.$route.query.id;
    console.log(id);
    // this.$store.dispatch("gotodetails",id)

    this.$network
      .godetails({
        params: {
          id
        }
      })
      .then(res => {
        console.log(res.data.data.data);
        this.goods = res.data.data.data.imgs.split(",");
        this.good = res.data.data.data;
      });
  },
  // 初始化
  created() {
    let cart = localStorage.cart;
    if (cart) {
      this.cart = JSON.parse(cart);
    }
  },
  // 返回上一页
  methods: {
    onClickLeft() {
      window.history.back();
    },

    // 去重
    gou() {
      let rel = true;
      this.cart.map(item => {
        if (item.cart.id == this.good.id) {
          rel = false;
          item.num++;
          return;
        }
      });

      if (rel) {
        this.cart.push({
          cart: this.good,
          num: 1
        });
      }
      localStorage.cart = JSON.stringify(this.cart);
    },
    // 点击跳转购物车
    go() {
      this.$router.push({
        path: "/carts"
      });
    }
  }
};
</script>

<style scoped>
.fu {
  font-size: 14px;
  color: gray;
}
.yuan {
  color: gray;
  font-size: 14px;
}
.juan {
  color: red;
}
.tan {
  background: rgb(214, 200, 200);
  font-size: 14px;
}
.wei {
  position: absolute;
  left: 300px;
}
</style>

购物车页面

在这里插入图片描述
代码:

<template>
  <div>
    <!-- 头部 -->
    <van-nav-bar title="购物车" left-text="返回" left-arrow fixed @click-left="back" />

    <!-- 商品卡片 -->
    <div class="quan">
      <van-checkbox-group v-model="result" ref="CheckboxGroup" @change="allChange">
        <van-row
          v-for="(item,index) in cart"
          style="margin: 10px 0px;background-color: #FAFAFA;"
          :key="index"
        >
          <!-- 复选框 -->
          <van-col span="2" style="margin-top: 40px;">
            <van-checkbox :name="index" checked-color="red" />
          </van-col>

          <button class="sc" @click="del(index)">删除</button>

          <van-col span="22">
            <van-card
              :price="item.cart.actualPrice"
              :title="item.cart.title"
              :thumb="item.cart.mainPic"
            >
              <template #num>
                <van-stepper v-model="item.num" @change="numChange" />
              </template>
            </van-card>
          </van-col>
        </van-row>
      </van-checkbox-group>
    </div>

    <!-- 底部导航 -->
    <van-submit-bar :price="total" button-text="提交订单">
      <van-checkbox v-model="checked" @change="quan">全选</van-checkbox>
    </van-submit-bar>

    <!-- 空状态 -->
    <van-empty
      class="custom-image"
      image="https://img.yzcdn.cn/vant/custom-empty-image.png"
      description="穷的头皮发麻"
      v-show="show"
      style="margin-top: 1rem;"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      cart: [],
      checked: false,
      total: 0, //默认0
      result: [] //卡片数组
    };
  },
  computed: {
    show() {
      let isShow = this.cart.length > 0 ? false : true;
      return isShow;
    }
  },
  created() {
    let cart = localStorage.cart;
    if (cart != undefined) {
      this.cart = JSON.parse(cart);
    }
  },
  methods: {
    back() {
      //返回上一级
      window.history.back();
    },
    del(index) {
      this.cart.splice(index, 1);
      localStorage.cart = JSON.stringify(this.cart);
    },
    zongjia() {
      this.total = 0; //清空历史
      this.result.map(i => {
        let cart = this.cart[i]; //获取购物车的商品对象
        let money = cart.num * cart.cart.actualPrice * 100; //单位分
        this.total += money;
        console.log(this.total);
      });
    },
    numChange() {
      if (this.cart.length > 0) {
        this.zongjia();
      }
      localStorage.cart = JSON.stringify(this.cart);
    },
    allChange() {
      this.zongjia();
    },
    quan(checked) {
      this.$refs.CheckboxGroup.toggleAll(checked);
    }
  }
};
</script>

<style scoped="scoped">
.sc {
  width: 40px;
  height: 24px;
  font-size: 0.1rem;
  float: right;
  margin-right: 5px;
  background: rgb(211, 202, 202);
  color: rgb(95, 93, 93);
}
.quan {
  margin-top: 2.5rem;
}
</style>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张清悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值