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);
        }
    }
}
相关推荐
苹果酱05672 分钟前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
eybk3 小时前
Pytorch+Mumu模拟器+萤石摄像头实现对小孩学习的监控
学习
6.943 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala
真的很上进3 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203984 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
守护者1704 小时前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
学会沉淀。5 小时前
Docker学习
java·开发语言·学习
Rinai_R5 小时前
计算机组成原理的学习笔记(7)-- 存储器·其二 容量扩展/多模块存储系统/外存/Cache/虚拟存储器
笔记·物联网·学习
吃着火锅x唱着歌5 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
ragnwang5 小时前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习