IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue购物车(购物车进阶版) -> 正文阅读

[JavaScript知识库]Vue购物车(购物车进阶版)

效果流程

  1. 我们在vue项目中views中创建两个组件一个购物页,一个购物车
  2. 我们通过localStorage本地储存,来实现页面刷新不掉
  3. 使用Vuex来进行传值
  4. 使用Tap来实现切换和是筛选
  5. 给我们加入购物画册女页的数据添加状态,判断是否选中
  6. 通过状态来判断选中删除

代码实现流程

Vuex代码逻辑实现:

首先在vuex中通过localStoage来拿取本地数据,先创建一个空对象,来存放拿取的数据,在创建一个来访,我们添加购物车的数据,在创意两个空数组来存放我们的总价和总数量

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

Vue.use(Vuex)

export default new Vuex.Store({
  state:{
    goodsData:[],
    cartData:[],
    totalMount:0,
    totalPrice:0,
  },
  getters:{
   
  },
  mutations:{
    SET_DOODS_DATA(state,data){
      const {goodsData}=data;
      state.goodsData=goodsData;
    },
    SET_CART_DATA(state,data){
      const {cartData,totalmount,totalprice}=data
      state.cartData=cartData
      state.totalMount=totalmount
      state.totalPrice=totalprice
    },
  },
  actions:{
    setDoodsData({commit}){
      const goodsData=JSON.parse(localStorage.getItem('goodsData'))||[];
      commit('SET_DOODS_DATA',{goodsData})
    },
    setCratData({commit}){
      const cartData=JSON.parse(localStorage.getItem('cartData'))||[];
      const totalmount=JSON.parse(localStorage.getItem('totalmount'))||0;
      const totalprice=JSON.parse(localStorage.getItem('totalprice'))||0;
      commit('SET_CART_DATA',{
        cartData,
        totalmount,
        totalprice,
      })
    },
    
  },
  modules:{
   
  }
})

购物页效果实现:

首先页面跳转我们通过路由来实现,然后我们在computed中获取我们商品数据进行渲染,在生命周期函数created中异步拿取数据,让我们刷新之后利己执行,再过我们导航栏的数据加上状态,给它定义一个初始状态,最后通过switch来进行筛选,然后当我们点击加的时候给我们创建的购物车页里面添加数据

代码如下:

<template>
  <div class="page">
    <header>
      <router-link class="acrt" to="/cart">购物车</router-link>
      <span class="header-title">商品列表</span>
    </header>
    <div class="page-list">
      <div class="top-wrap">
        <ul>
          <li :class="{'tab-active':type==item.type}" v-for="item in Type" :key="item.id" @click="type=item.type">{{item.name}}</li>
        </ul>
      </div>  
    </div>
    <ul class="filter">
      <li :class="{'filter-title' :status=='all'}" @click="status='all'">综合排序</li>
      <li :class="{'filter-title' :status=='sales'}" @click="status='sales'">销量优先</li>
      <li :class="{'filter-title' :status=='priceMax'||status=='priceMin'}" @click="priceMaxMin">价格</li>
    </ul>
    <ul class="goods-list">
       <li class="goods-item" v-for="item in showGoods" :key="item.id">
          <div class="goods-img">
            <img :src="item.img" alt="item.name">
            <!---->
          </div>
          <div class="goods-info">
            <p class="goods-title">{{item.name}}</p>
            <p class="goods-price">${{item.price}}</p>
            <span class="des">{{item.sales}}人付款</span>
            <span class="save" @click="JOIO(item,'ADD')">+</span>
          </div>
        </li>
    </ul>
  </div>
</template>

<script>
import { mapState } from 'vuex'
const Type=[
  {
        id:0,
        name:'推荐',
        type:0
    },
    {
        id:1,
        name:'母婴',
        type:1
    },
    {
        id:2,
        name:'鞋包饰品',
        type:2
    },
    {
        id:3,
        name:'食品',
        type:3
    },
    {
        id:4,
        name:'数码家电',
        type:4
    },
    {
        id:5,
        name:'居家百货',
        type:5
    },
]
let boo=true
export default {
  data() {
    return {
      Type, 
      type:0,
      status:'all'
    }
  },
  created() {
    this.$store.dispatch('setDoodsData')
  },
  computed:{
    ...mapState(['goodsData']),
    showGoods(){
      let data=null;
      if(this.type==0){
         data=this.goodsData.map(item=>item);
      }else{
        data=this.goodsData.filter(item=>item.type==this.type);
      }
      console.log(data)
      switch(this.status){
        case "all":
          return data
          case "sales":
            return data.sort((a,b)=>b.sales-a.sales)
            case "priceMax":
              return data.sort((a,b)=>b.price-a.price)
              case "priceMin":
                return data.sort((a,b)=>a.price-b.price);
      }
    }
  },
  methods: {
    priceMaxMin(){
      if(boo){
        this.status='priceMax'
        boo=false
      }else{
        this.status='priceMin'
        boo=true
      }
    },
    JOIO(item,_type){
      this.$store.dispatch('setCart',{
        id:item.id,
        img:item.img,
        name:item.name,
        price:item.price,
        stock:item.stock,
        _type
      })
    }
  },
}
</script>

<style lang="less" scoped>
  .page{
    width: 100%;
    header{
      line-height: .4rem;
      display: flex;
      justify-content: center;
      align-items: center;
      .acrt{
        width: .8rem;
        text-align: center;
      }
      .header-title{
        padding-left: 20%;
        flex: 1;
      }
    }
    .page-list{
      .top-wrap{
        width: 100%;
        height: .6rem;
        background: red;
        overflow: hidden;
        ul{
          white-space: nowrap;
          overflow-x: scroll;
          -webkit-overflow-scrolling: touch;
          background-color: #5D4285;
          li{
            display: inline-block;
            width: .8rem;
            height: .7rem;
            color: #fff;
            line-height: .6rem;
            text-align: center;
          }
          .tab-active {
            background-color: #9A51FF;
          }
        }
      }
    }
    .filter{
      line-height: .3rem;
      display: flex;
      justify-content: center;
      align-items: center;
      li{
        flex: 3;
        text-align: center;
      }
      .filter-title{
        color: red;
      }
    }
    .goods-list{
      width: 100%;
      padding-bottom: .45rem;
      .goods-item{
        margin-top: .1rem;
        border-bottom: .05rem solid #ccc;
        min-width: .6rem;
        .goods-img{
          width: .6rem;
          height: .6rem;
          padding: 0 .1rem;
          float: left;
          left: 0;
          overflow: hidden;
          img{
            width: 100%;
            height: 100%;
          }
        }
        .goods-info{
          position: relative;
          .goods-title{
            width: 70%;
            height: 38px;
            color: #363636;
            line-height: 1.4;
            display: -webkit-box;
            -webkit-box-orient: vertical;
            -webkit-line-clamp: 2;
            overflow: hidden;
          }
          .goods-price{
            font-size: 15px;
            color: #7a45e5;
          }
          .des{
            font-size: 12px;
            color: #888;
          }
          .save{
            position: absolute;
            right: 10px;
            bottom: 2px;
            width: 32px;
            height: 22px;
            background-color: #7a45e5;
            font-size: 16px;
            line-height: 19px;
            text-align: center;
            color: #fff;
            border-radius: 12px;
            overflow: hidden;
          }
        }
      }
    }
  }
</style>

购物车页效果实现:

我们点击编辑和完成我们在vuex中定义一个布尔值,然后用v-show来实现显示和隐藏,我们要实现刷新不掉,我们在生命周期函数created中获取一边数据,然后我们computed中获取vuex中的数据,我们的总价和总数量,然后methods中计算加减,在通过我们在vuex中定义的布尔值进行删除

代码如下:

<template>
  <div class="page">
    <header>
      <router-link class="acrt" to="/">返回</router-link>
      <span class="header-title">购物列表</span>
      <span class="header-edit">
        <span v-show="failureShow" @click="SET_FAILURE_SHOW(false)">编辑</span> 
        <span v-show="!failureShow"  @click="SET_FAILURE_SHOW(true)">完成</span>
      </span>
    </header>
     <ul class="cart-list">
       <li class="cart-item" v-for="item in cartData" :key="item.id">
          <div class="cart-icon" :class="{'select-active':item.select}">
            <input type="checkbox" @click="aaa(item)">
          </div>
          <div class="cart-img">
            <img :src="item.img" alt="item.name">
          </div>
          <div class="cart-info">
            <p class="cart-title">{{item.name}}</p>
            <p class="cart-price">${{item.price}}</p>
            <p class="cart-des">库存{{item.stock}}件</p>
            <div class="cart-subtract">
              <p class="cart-save" @click="addAND(item.id,item.price,item,'ADD')">+</p>
              <p class="cart-save">{{item.mount}}</p>
              <p class="cart-save" @click="addAND(item.id,item.price,item,'AND')">-</p>
            </div>
          </div>
        </li>
    </ul>
    <div class="action-bar">
      <div class="item-selector">
        <div class="action-icon" :class="{'select-active': tSelect }">
          <input type="checkbox" v-model="tSelect">
        </div>
        <span>全选</span>
      </div>
      <div class="total">
        合计:<span>¥{{totalPrice}}</span>
      </div>
      <div class="action-btn" v-show="failureShow">去结算({{totalMount}})</div>
      <div class="action-btn del-btn" v-show="!failureShow" @click="delectData">删除({{totalMount}})</div>
    </div>
  </div>
</template>

<script>
import { mapActions, mapMutations, mapState } from 'vuex'
export default {
  created() {
    this.$store.dispatch('setCratData')
  },
  computed:{
    ...mapState(['cartData','totalMount','totalPrice','failureShow']),
    tSelect:{
      get(){
        const boo=this.cartData.every(item=>item.select);
        // localStorage.setItem('totalSelect',boo);
        return boo;
      },
      set(value){
        console.log(value);
        this.$store.dispatch('setTotalSelect',value)
      }
    }
  },
  methods: {
    ...mapMutations(['SET_FAILURE_SHOW']),
    ...mapActions(['delectData','setTotal']),
    addAND(id,price,item,_type){
      if(item.select){
        if(_type=="ADD"){
          this.setTotal({
            select:item.select,
            Price:item.price,
            mount:1
          });
        }else if(_type=="AND"){
          if(item.mount>1){
            this.setTotal({
              select:item.select,
              Price:-item.price,
              mount:-1
            });
          }
        }
      }
      this.$store.dispatch('setCart',{
        id,
        price,
        _type
      });
    },
    aaa(item){
      console.log(item)
      this.$store.dispatch('setSelect',item.id);
      this.$store.dispatch('setTotal',{
        select:item.select,
        Price:item.Price,
        mount:item.mount
      })
    }
  },
}
</script>

<style lang="less" scoped>
  .page{
    max-width: 12rem;
    min-width: .32rem;
    header{
      width: 100%;
      line-height: .4rem;
      display: flex;
      justify-content: center;
      align-items: center;
      .acrt{
        width: .8rem;
        text-align: center;
      }
      .header-title{
        text-align: center;
        flex: 1;
      }
      .header-edit{
        width: .8rem;
        text-align: center;
      }
    }
    .cart-list{
      width: 100%;
      padding-bottom: 1rem;
      .cart-item{
        margin-top: .1rem;
        border-bottom: .05rem solid #ccc;
        min-width: .6rem;
        .cart-icon{
          position: relative;
          margin: .16rem auto 0 .1rem;
          width: .16rem;
          height: .16rem;
          border-radius: 50%;
          border: .02rem solid red;
          cursor: pointer;
          float: left;
          z-index: 1;
          input{
            width: .16rem;
            height: .16rem;
            opacity: 0;
          }
        }
        .select-active{
          background-color: red;
        }
        .cart-img{
          width: .6rem;
          height: .6rem;
          padding: 0 .1rem;
          float: left;
          left: 0;
          overflow: hidden;
          img{
            height: 100%;
          }
        }
        .cart-info{
          position: relative;
          .cart-title{
            width: 60%;
            height: 38px;
            color: #363636;
            line-height: 1.4;
            display: -webkit-box;
            -webkit-box-orient: vertical;
            -webkit-line-clamp: 2;
            overflow: hidden;
          }
          .cart-price{
            font-size: 15px;
            color: #7a45e5;
          }
          .cart-des{
            font-size: 12px;
            color: #888;
          }
          .cart-subtract{
            position: absolute;
            right: 10px;
            top: 4px;
            width: 32px;
            color: #999;
            text-align: center;
            .cart-save{
              width: 100%;
              height: 24px;
              font-size: 20px;
              line-height: 20px;
              cursor: pointer;
            }
          }
        }
      }
    }
    .action-bar{
      line-height: 0.3rem;
      display: flex;
      justify-content: center;
      align-items: center;
      padding-bottom: 50px;
      position: fixed;
      bottom: 0;
      width: 100%;
      background-color: #fff;
      .item-selector{
        flex: 1;
        line-height: .5rem;
        .action-icon{
          position: relative;
          margin: .16rem .1rem 0 .1rem;
          width: .16rem;
          height: .16rem;
          border-radius: 50%;
          border: .02rem solid #ccc;
          cursor: pointer;
          float: left;
          input{
            width: .16rem;
            height: .16rem;
            opacity: 0;
          }
        }
        .select-active{
          background-color: red;
        }
      }
      .action-btn{
        width: 120px;
        height: 100%;
        color: #fff;
        text-align: center;
        font-weight: 300;
        line-height: 52px;
        cursor: pointer;
        background-color: #7A45E5;
      }
      .del-btn{
        background-color: #FF4069;
      }
      .total{
        color: #363636;
        font-size: 14px;
        line-height: 50px;
        margin-right: 20px;
        span{
          color: red;
        }
      }
    }
  }
</style>

写的不太详细以后会努力写详细的

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 12:08:26  更:2021-10-06 12:10:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 22:02:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码