Vue多文件学习项目综合案例——购物车,黑马vue教程

一、项目截图

二、主要知识点

  • vuex的使用

  • json-server的使用

    shell 复制代码
    json-server --watch index.json

三、需要注意的点

四、Main.js

js 复制代码
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

五、App.vue

html 复制代码
<template>
  <div class="app-container">
    <!-- Header 区域 -->
    <cart-header></cart-header>

    <!-- 商品 Item 项组件 -->
    <cart-item v-for="item in list" :key="item.id" :item="item"></cart-item>

    <!-- Foote 区域 -->
    <cart-footer></cart-footer>
  </div>
</template>

<script>
import CartHeader from '@/components/cart-header.vue'
import CartFooter from '@/components/cart-footer.vue'
import CartItem from '@/components/cart-item.vue'
import {mapState} from "vuex";

export default {
  name: 'App',
  components: {
    CartHeader,
    CartFooter,
    CartItem
  },
  computed:{
    ...mapState('cart',['list'])
  },
  created() {
    this.$store.dispatch('cart/getList')
  }
}
</script>

<style lang="less" scoped>
.app-container {
  padding: 50px 0;
  font-size: 14px;
}
</style>

六、components

cart-footer.vue

html 复制代码
<template>
  <div class="footer-container">
    <!-- 中间的合计 -->
    <div>
      <span>共 {{total}} 件商品,合计:</span>
      <span class="price">¥{{ totalPrice}}</span>
    </div>
    <!-- 右侧结算按钮 -->
    <button class="btn btn-success btn-settle">结算</button>
  </div>
</template>

<script>
import {mapGetters} from 'vuex'

export default {
  name: 'CartFooter',
  computed: {
    ...mapGetters('cart', ['total', 'totalPrice'])
  }
}
</script>

<style lang="less" scoped>
.footer-container {
  background-color: white;
  height: 50px;
  border-top: 1px solid #f8f8f8;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 0 10px;
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  z-index: 999;
}

.price {
  color: red;
  font-size: 13px;
  font-weight: bold;
  margin-right: 10px;
}

.btn-settle {
  height: 30px;
  min-width: 80px;
  margin-right: 20px;
  border-radius: 20px;
  background: #42b983;
  border: none;
  color: white;
}
</style>

cart-header.vue

html 复制代码
<template>
  <div class="header-container">购物车案例</div>
</template>

<script>
export default {
  name: 'CartHeader'
}
</script>

<style lang="less" scoped>
.header-container {
  height: 50px;
  line-height: 50px;
  font-size: 16px;
  background-color: #42b983;
  text-align: center;
  color: white;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 999;
}
</style>

cart-item.vue

html 复制代码
<template>
  <div class="goods-container">
    <!-- 左侧图片区域 -->
    <div class="left">
      <img :src="item.thumb" class="avatar" alt="">
    </div>
    <!-- 右侧商品区域 -->
    <div class="right">
      <!-- 标题 -->
      <div class="title">{{ item.name }}</div>
      <div class="info">
        <!-- 单价 -->
        <span class="price">{{ item.price }}</span>
        <div class="btns">
          <!-- 按钮区域 -->
          <button class="btn btn-light" @click="btnClick(-1)">-</button>
          <span class="count">{{ item.count }}</span>
          <button class="btn btn-light" @click="btnClick(1)">+</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CartItem',
  props: {
    item: {
      type: Object,
      request: true
    }
  },
  methods: {
    btnClick(step) {
      const newCount = this.item.count + step;
      const id = this.item.id;
      if (newCount < 1) return;
      this.$store.dispatch('cart/updateCountAsync', {
        id,
        newCount
      })
    }
  }
}
</script>

<style lang="less" scoped>
.goods-container {
  display: flex;
  padding: 10px;

  + .goods-container {
    border-top: 1px solid #f8f8f8;
  }

  .left {
    .avatar {
      width: 100px;
      height: 100px;
    }

    margin-right: 10px;
  }

  .right {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;

    .title {
      font-weight: bold;
    }

    .info {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .price {
        color: red;
        font-weight: bold;
      }

      .btns {
        .count {
          display: inline-block;
          width: 30px;
          text-align: center;
        }
      }
    }
  }
}

.custom-control-label::before,
.custom-control-label::after {
  top: 3.6rem;
}
</style>

七、store

index.js

js 复制代码
import Vue from 'vue'
import Vuex from 'vuex'
import cart from "./modules/cart";

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    cart
  }
})

modules/cart.js

js 复制代码
import axios from "axios";

export default {
    namespaced: true,
    state() {
        return {
            //购物车数据
            list: []
        }
    },
    mutations: {
        updateList(state, newList) {
            state.list = newList
        }
    },
    actions: {
        async getList(context) {
            const res = await axios.get("http://localhost:3000/cart")
            context.commit('updateList', res.data)
        },
        async updateCountAsync(context, obj) {
            await axios.patch(`http://localhost:3000/cart/${obj.id}`, {
                count: obj.newCount
            })
            //当前的this指向$store
            this.dispatch('cart/getList')
        }
    },
    getters: {
        //商品总数
        total(state) {
            return state.list.reduce((sum, item) => sum + item.count, 0);
        },
        //商品总价
        totalPrice(state) {
            return state.list.reduce((sum, item) => sum + item.count * item.price, 0);
        }
    }
}
相关推荐
默_笙17 分钟前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
李日华大战鸡红1 小时前
FOC状态空间方程模型推导(学习记录)
python·学习·线性代数
思无邪661 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
kkkkkkkkkk_Z3 小时前
新手自学嵌入式 | 学习日记:异常与中断基础、i.MX6ULL裸机开发环境搭建、GPIO模块与点灯原理
学习
福兮说3 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
m4Rk_3 小时前
【论文阅读】Agent 记忆机制(94):MemGen——在推理过程中动态生成并织入潜在记忆
论文阅读·人工智能·学习·开源·github
晓德4 小时前
0、LLM大模型安全学习系列(启)
学习·安全
可乐鸡翅yeah_4 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放
Titan20244 小时前
MySQL索引学习笔记
笔记·学习·mysql
JWASX5 小时前
Java 转 go 学习 - kitex(5)
学习·golang