vue项目之购物流程

vue 项目之购物流程

首页商品展示

  • 使用宫格组件,实现首页商品的两列展示
    • https://vant-contrib.gitee.io/vant/#/zh-CN/grid
    • 属性介绍
      • column-num 展示的列数
      • @click="gotoDetails(value._id)" 点击去往详情页
  • 一般来说,在created钩子函数之中,获取到商品数据,因为这时候的数据是已经初始化好了
    • 然后把这些数据,存储在data之中,用于列表的渲染
<template>
  <div class="home">
    <!-- 商品列表 -->
    <van-grid class="my-goods" :column-num="2">
      <van-grid-item v-for="value in goodsList" :key="value._id" @click="gotoDetails(value._id)">
        <van-image class="goodsImg" :src="value.imgurl" />
        <h4>{{ value.name}}</h4>
      </van-grid-item>
    </van-grid>
  </div>
</template>

<script>
import Vue from "vue";

export default {
  name: "Home",
  data() {
    return {
      //商品列表的数据
      goodsList: [],
    };
  },
  async created() {
    //商品列表的请求
    const { data: goodsList } = await this.$request.get("/goods");
    // console.log("我是商品列表", goodsList);
    this.goodsList = goodsList;
  },
  methods: {
    //点击 具体的商品 去往详情页!
    gotoDetails(id) {
      // this.$router.push("/gotoDetails/" + id);
      this.$router.push({
        name: "Details",
        params: {
          id,
        },
      });
    },
  },
};
</script>

商品详情页

  • 需求:
    • 详情页的展示 img
      • 一进入页面的时候,拿到url中的id,发起请求,拿到当前商品的详情数据 然后数据渲染
      • 点击这个img 进入图片预览模式 https://vant-contrib.gitee.io/vant/#/zh-CN/image-preview
      • @click="showBig"
    • 点击购物车,去往购物车页面 购物车之中显示多少商品,这需要使用到vuex数据共享了!
      • :badge="cartLength" 徽标的使用(显示多少商品)
      • 这需要从vuex中拿到对应的购物车商品数组长度
        • cartList 一般都是存储在数据库之中,就是拿到当前登陆的用户的id值,去查询数据库是否含有购物车数据,返回后,存放在vuex之中!
          computed: {
            cartLength() {
              return this.$store.state.cartList.length;
            },
          },
        
    • 点击假如购物车
      • 假如购物车之中有商品了,那么就数量加1,否则的话,就是给购物车添加一个商品数据
      • 先拿到当前商品的id,需要从商品数据中结构出来
      • 拿着当前的id去,引用vuex中的购物车数组,查询是否有当前id
      • 如果当前id存在,那么就修改当前商品的数量,否则的话,就新增一条商品数据 (这些需要
    • 是否显示下面的tabbar
<!--  -->
<template>
  <div class="details">
    <!-- 导航栏目 -->
    <van-nav-bar left-text="返回" @click-left="backHome" left-arrow></van-nav-bar>

    <!-- 图书详情 -->
    <div class="smallImg-box">
      <van-image class="smallImg" @click="showBig" :src="goodsDetails.imgurl"></van-image>
      <div class="recommend-box">
        <h1>{{ goodsDetails.name}}</h1>
        <h4>{{ goodsDetails.auth}}</h4>
        <h5>连载中</h5>
      </div>
    </div>
    <div class="validity-con">
      <h3>内容简介</h3>
      <p>{{ goodsDetails.intro }}</p>
    </div>
    <!-- 图书推荐 -->
    <div class="recomment-box">
      <h3>图书推荐</h3>
      <van-grid class="my-goods" :column-num="3">
        <van-grid-item
          v-for="value in goodsRecomemnt"
          :key="value._id"
          @click="gotoDetails(value._id)"
        >
          <van-image class="goodsImg" :src="value.imgurl" />
          <h4>{{ value.name}}</h4>
        </van-grid-item>
      </van-grid>
    </div>
    <!-- 购物车 -->
    <van-goods-action>
      <van-goods-action-icon icon="chat-o" text="客服" color="#07c160" />
      <van-goods-action-icon :badge="cartLength" @click="gotoCart" icon="cart-o" text="购物车" />
      <van-goods-action-icon icon="star" text="已收藏" color="#ff5000" />
      <van-goods-action-button @click="addToCart" type="warning" text="加入购物车" />
      <van-goods-action-button @click="buyNow" type="danger" text="立即购买" />
    </van-goods-action>
  </div>
</template>

<script>
import Vue from "vue";
import {
  ImagePreview,
  GoodsAction,
  GoodsActionButton,
  GoodsActionIcon,
  NavBar,
} from "vant";

Vue.use(ImagePreview);
Vue.use(GoodsAction);
Vue.use(GoodsActionButton);
Vue.use(GoodsActionIcon);
Vue.use(NavBar);

export default {
  name: "GotoDetails",
  data() {
    return {
      goodsDetails: [],
      goodsRecomemnt: [],
    };
  },
  created() {
    const id = this.$route.params.id;
    this.getDetail(id);
    this.getRecomment();
  },
  computed: {
    cartLength() {
      return this.$store.state.cartList.length;
    },
  },
  methods: {
    //点击返回首页
    backHome() {
      this.$router.push({
        name: "Home",
      });
    },
    // 获取详情页的数据
    async getDetail(id) {
      //拿着id 发起请求 拿到详情页的数据
      const {
        data: {
          data: { result: goods },
        },
      } = await this.$request.get("/goods/" + id);

      // console.log("我是详情页111", goods[0]);
      this.goodsDetails = goods[0];
    },
    // 显示大图片
    showBig() {
      //图片传入到数组之中
      ImagePreview([this.goodsDetails.imgurl]);
    },
    // 获取推荐页的数据
    async getRecomment() {
      const { data } = await this.$request.get("/goods");
      // console.log("我是推荐的", data);
      this.goodsRecomemnt = data;
    },
    //跳转到 详情页
    gotoDetails(id) {
      // console.log("我是跳转的id", id);
      this.$router.push({
        name: "Details",
        params: {
          id,
        },
      });
    },
    //去往购物车
    gotoCart() {
      this.$router.push({
        name: "Cart",
      });
    },
    //加入购物车
    addToCart() {
      //判断购物车里面是否有这个商品 有的话 数量+1 没有的话 就qty为1
      const { _id: id } = this.goodsDetails; //拿到当前商品的id
      //根据id 去查询购物车 里面是否含有该id的商品!
      const current = this.$store.state.cartList.filter(
        (item) => item._id === id
      )[0];
      // console.log("我是当前的", current); // 如果有的话 那么qty++ 没有的话添加商品!
      if (current) {
        this.$store.dispatch("changeQtyAsunc", { id, qty: current.qty + 1 });
      } else {
        const goods = {
          ...this.goodsDetails,
          qty: 1,
        };
        // 调用mutation 中的addToCart方法
        // this.$store.commit("addToCart", goods);   
        this.$store.dispatch("addToCart", goods);
      }
    },
    //立即购买
    buyNow() {
      this.addToCart();
      //跳转到购物车
      this.$router.push({
        name: "Cart",
      });
    },
  },
  beforeRouteUpdate(to, from, next) {
    console.log(to.params.id, from.params.id);
    if (to.params.id !== from.params.id) {
      // console.log("我是去的id", to.params.id);
      this.getDetail(to.params.id);
      this.getRecomment();
    }
    next();
  },
  mounted() {
    //触发销毁事件
    this.$store.commit("isShowMenu", false);
  },
  destroyed() {
    //触发销毁事件
    this.$store.commit("isShowMenu", true);
  }
};
</script>

vuex中的数据

这是在vuex数据,缺少操作数据库的步骤

import Vue from 'vue'
import Vuex from 'vuex'

import $request from "../network/request"
import {
  Notify
} from 'vant';
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //是否显示那个tabbar
    isShowMemu: true,
    totalPrice: "", //总价
    //购物车的数据
    cartList: [{
      "_id": "5f4f5e38aaf12252fb74c93b",
      "name": "鼎定乾坤",
      "date": "2020 08-19 11:28",
      "intro": "玄黄缔造者……极致超脱之路,哪怕天难葬其身,地难灭其魂。亦难以跳出那个圈。星空崩塌,万族凋零。如何以一己之力逆转乾坤,颠倒阴阳。且看那一袭青衫,一柄长剑,一方圆鼎:脚踏修真,拳碎仙域,剑斩神界,鼎定至尊,极致超脱。书群,1141419286扣扣",
      "auth": "浅山深水",
      "imgurl": "imgbook1/f3aa24ea917f79a95b81ea86c91b4043.jpeg",
      "price": 123.2,
      "qty": 1,
      "check": false
    }, {
      "_id": "5f4f5e38aaf12252fb74c93e",
      "name": "雷神传之雷神再世",
      "date": "2020 08-18 22:47",
      "intro": "以武侠小说的名义 ,说一段刻骨铭心的爱情故事 !",
      "auth": "猛士七",
      "imgurl": "imgbook1/ba83c1528c275b6c154ffd482d4541c3.jpeg",
      "price": 12,
      "qty": 1,
      "check": false
    }]
  },
  getters: {
    //计算总价
    totalPrice(state) {
      return state.cartList.reduce((pre, cue) => pre + cue.price * cue.qty, 0) * 100
    },
  },
  mutations: {
    //显示
    isShowMenu(state, payload) {
      // console.log("我是mutations", payload);
      state.isShowMemu = payload
    },
    //修改购物车数量
    changeQty(state, payload) {
      console.log("mu修改数量", payload);
      state.cartList = state.cartList.map(item => {
        if (item._id === payload.id) {
          item.qty = payload.qty
        }
        return item
      })
    },
    // 添加购物车
    addToCart(state, payload) {
      // console.log("我是添加购物车", payload);
      state.cartList.unshift(payload)
    },
    //删除购物车 item
    delGoods(state, payload) {
      // console.log("我是删除的item", payload);
      state.cartList = state.cartList.filter(item => item._id !== payload)
    },
    //清空购物车
    clearCart(state) {
      console.log("我是清空触发");
      state.cartList = []
    }
  },
  actions: {
    //请求 查询库存多少! /:id/kucun
    async changeQtyAsunc(context, payload) {
      const {
        data
      } = await $request.get(`/goods/${payload.id}/kucun`)
      if (payload.qty > data.kucun) {
        Notify({
          type: 'danger',
          message: '超过库存,仅能下单这些!'
        });
        payload.qty = data.kucun

      }
      // console.log("我是修改后的", payload);
      context.commit("changeQty", payload)
    },

    // async getCart() {
    //   console.log("我被调用了!");
    //   const data = await $request.get(`/goods/:cart`)
    //   console.log("我是获取购物车列表", data);
    // }
  },
  modules: {}
})

这是一个添加商品的数据

  • 设计到向数据库写入数据,相对完善
import request from "../newwork/request"

const bookCategory = {
  state: {
    shelfList: [], //书架的数据, cartList需要发起请求获取的数据
    totalPrice: "", //总价
  },
  getters: {
    //计算总价
    totalPrice(state) {
      return state.cartList.reduce((pre, cue) => pre + cue.price * cue.qty, 0) * 100
    },
  },
  mutations: {
    //显示
    isShowMenu(state, payload) {
      // console.log("我是mutations", payload);
      state.isShowMemu = payload
    },
    // 获取书架列表
    async getShelfList(state) {
      // console.log("我是获取书架列表", state);
      const {
        data: getShelf
      } = await request.get("/shelf");
      state.shelfList = getShelf.data;
    },

    //加入书架
    async joinShelf(state, payload) {
      const {
        bookid
      } = payload

      const {
        data: joinShelfList
      } = await request.get(`/shelf/repeat/${bookid}`);

      if (joinShelfList.code === 0) { //证明里面没有图书 那么就可以添加
        await request.post("/shelf", {
          ...payload
        });
      } 
    }
  },
  actions: {
    // 加入书架
    joinShelf(context, payload) {
      return new Promise((resolve) => {
        context.commit("joinShelf", payload)
        resolve("添加成功")
      })
    },
    // 添加商品
    // 删除商品
    // 清空商品 
    // 都需要 提交到mutations之中
  }

}

export default bookCategory;
  • 这是 部分忘记操作 数据库的 代码
import Vue from 'vue'
import Vuex from 'vuex'

import $request from "../network/request"
import {
  Notify
} from 'vant';
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //是否显示那个tabbar
    isShowMemu: true,
    totalPrice: "", //总价
    //购物车的数据
    cartList: [{
      "_id": "5f4f5e38aaf12252fb74c93b",
      "name": "鼎定乾坤",
      "date": "2020 08-19 11:28",
      "intro": "玄黄缔造者……极致超脱之路,哪怕天难葬其身,地难灭其魂。亦难以跳出那个圈。星空崩塌,万族凋零。如何以一己之力逆转乾坤,颠倒阴阳。且看那一袭青衫,一柄长剑,一方圆鼎:脚踏修真,拳碎仙域,剑斩神界,鼎定至尊,极致超脱。书群,1141419286扣扣",
      "auth": "浅山深水",
      "imgurl": "imgbook1/f3aa24ea917f79a95b81ea86c91b4043.jpeg",
      "price": 123.2,
      "qty": 1,
      "check": false
    }, {
      "_id": "5f4f5e38aaf12252fb74c93e",
      "name": "雷神传之雷神再世",
      "date": "2020 08-18 22:47",
      "intro": "以武侠小说的名义 ,说一段刻骨铭心的爱情故事 !",
      "auth": "猛士七",
      "imgurl": "imgbook1/ba83c1528c275b6c154ffd482d4541c3.jpeg",
      "price": 12,
      "qty": 1,
      "check": false
    }]
  },
  getters: {
    //计算总价
    totalPrice(state) {
      return state.cartList.reduce((pre, cue) => pre + cue.price * cue.qty, 0) * 100
    },
  },
  mutations: {
    //显示
    isShowMenu(state, payload) {
      // console.log("我是mutations", payload);
      state.isShowMemu = payload
    },
    //修改购物车数量
    changeQty(state, payload) {
      console.log("mu修改数量", payload);
      state.cartList = state.cartList.map(item => {
        if (item._id === payload.id) {
          item.qty = payload.qty
        }
        return item
      })
    },
    // 添加购物车
    addToCart(state, payload) {
      // console.log("我是添加购物车", payload);
      state.cartList.unshift(payload)
    },
    //删除购物车 item
    delGoods(state, payload) {
      // console.log("我是删除的item", payload);
      state.cartList = state.cartList.filter(item => item._id !== payload)
    },
    //清空购物车
    clearCart(state) {
      console.log("我是清空触发");
      state.cartList = []
    }
  },
  actions: {
    //请求 查询库存多少! /:id/kucun
    async changeQtyAsunc(context, payload) {
      const {
        data
      } = await $request.get(`/goods/${payload.id}/kucun`)
      if (payload.qty > data.kucun) {
        Notify({
          type: 'danger',
          message: '超过库存,仅能下单这些!'
        });
        payload.qty = data.kucun

      }
      // console.log("我是修改后的", payload);
      context.commit("changeQty", payload)
    },

    // async getCart() {
    //   console.log("我被调用了!");
    //   const data = await $request.get(`/goods/:cart`)
    //   console.log("我是获取购物车列表", data);
    // }
  },
  modules: {}
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值