zoukankan      html  css  js  c++  java
  • vue项目之购物车

    简单的完成一个购物车项目,满足基本功能

    安装创建好项目以后需要引入安装elementui和vuex

    项目目录如下:(home.vue为主页面)

    ### ~home.vue

    <template>
      <div>
    
        <!-- <div>我是默认显示页面</div> -->
        <!-- 绑定自定义事件,事件函数里面执行操作 -->
        <Nav v-if="see" :NavActiveIndex="activeIndex" @fromNavVal='fromNavValfn'></Nav>
        <div v-else>折叠以后{{activeIndex2}}</div>
        <router-view />
      </div>
    </template>
    <script>
      import Nav from './Nav.vue'
      export default {
        name: 'home',
        components: {
          //nav是home的子组件
          Nav
        },
        data() {
          return {
            activeIndex: '/buycar',
            activeIndex2: '1',
            see: true,
          };
        },
        methods: {
          fromNavValfn(val) {
            //此时的val为子组件中$emit中发射过来的参数
            // console.log(val)
            this.activeIndex2 = val;
            this.see = !this.see;
          }
    
        }
      }
    </script>
    <style>
    
    </style>

    ###~About.vue

    <template>
      <div>
       This is an about page
      </div>
    </template>
    
    <script>
    </script>
    
    <style>
    </style>

    ###~Nav.vue

    <template>
        <div>
        <!-- {{NavActiveIndex}} -->
          <!-- 父子组件之间通讯用props和emit,无关系组件之间需要用eventbus和vuex -->
          <!-- 要传入默认绑定激活的路由 default-active 此处在父组件home中 activeIndex: '/about' 默认绑定根路由下的about-->
          <el-menu
            :default-active="NavActiveIndex"
            class="el-menu-demo"
            mode="horizontal"
            @select="handleSelect"
            background-color="#545c64"
            text-color="#fff"
            router
            active-text-color="#ffd04b">
            <el-menu-item index="/buycar">购物车{{buycarCount}}</el-menu-item>
            <el-submenu index="2">
              <template slot="title">我的工作台</template>
              <el-menu-item index="/about">about</el-menu-item>
              <el-menu-item index="/test">test</el-menu-item>
              <el-menu-item index="/test2">test2</el-menu-item>
            </el-submenu>
            <el-menu-item index="3"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
          </el-menu>
          <button @click="click">折叠导航栏</button>
        </div>
    </template>
    
    <script>
      import bus from '@/assets/bus.js'
      export default {
          name: 'nav',
          props:{
            NavActiveIndex:String
          },
          data() {
            return {
              activeIndex: '1',
              activeIndex2: 'nav的123',
              buycarCount : 0,
            };
          },
          created(){
            //非父子组件之间接受方法
            //$on监听事件
            //数量改变的时候触发这个事件
            bus.$on('buycarCountChange',(num) => {
                this.buycarCount = num ;
            })
          },
          methods: {
            handleSelect(key, keyPath) {
              console.log(key, keyPath);
            },
            click(){
              //第一个参数为父组件绑定的自定义事件名字,第二个为携带的参数
                this.$emit('fromNavVal',this.activeIndex2)
            }
          }
      }
    </script>
    
    <style>
    </style>

    ###~router/index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import home from '../views/Home.vue'
    import test from '../views/test.vue'
    // import about from '../views/About.vue'
    
    Vue.use(Router)
    
    export default new Router({
      mode:'history',
      routes: [
        {
          path: '/',
          name: 'home',
          component: home,
          children:[
            {
              path:'buycar',
              name:'buycar',
              component: () => import('@/components/buycar.vue')
            },
            {
              path: 'about',
              name: 'about',
              component: () => import ('../views/About.vue')
            },
            {
              path: 'test2',
              name: 'test',
              component: () => import ('../views/test2.vue')
            },
          ]
        },
        {
          path:'/test',
          component:test,
        }
    
      ]
    })

    ###~assets /bus.js

    import Vue from 'vue';
    const EventBus = new Vue();
    
    // console.log(1)
    export default EventBus;
    
    
    //事件注册中心
    //所有的事件共同使用的
    //所有的组件都可以向这个中心注册或者接受事件

    ###~main.js

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    // import store from './store'
    
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    
    Vue.use(ElementUI)
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      // store,
      components: { App },
      template: '<App/>'
    })

    ###~store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    // export default new Vuex.store({
    //     state:{
    //       buycarCount: 10
    //     },
    //     mutations:{
    //         changebuyCarCount(state,num){
    //           state.buycarCount = num ;
    //         }
    //     },
    //     actions:{
    // 
    //     }
    // 
    // 
    // })
    // 

    ###~buycar.vue

    <template>
      <div>
        <div v-if='list.length>0'>
          <div>
            <el-col :span="6">商品信息</el-col>
            <el-col :span="3">尺码/颜色</el-col>
            <el-col :span="3">吊牌价</el-col>
            <el-col :span="3">数量</el-col>
            <el-col :span="3">折扣</el-col>
            <el-col :span="3">总金额</el-col>
            <el-col :span="3">删除</el-col>
          </div>
          <div>
            <ul>
              <li v-for="item in list">
                <el-col :span="6">
                  <el-checkbox v-model="selectArrCloth" :label="item.id" @change="item.checked = ! item.checked">{{item.name}}</el-checkbox>
                  <img src="../assets/logo.png" style=" 20px; height: 20px;">
                </el-col>
                <el-col :span="3">{{item.size}} {{item.color}}</el-col>
                <el-col :span="3">{{item.price}}</el-col>
                <el-col :span="3">
                  <span @click="pre(item)">-</span>
                  {{item.count}}
                  <span @click="add(item)">+</span>
                </el-col>
                <el-col :span="3">{{item.active}}</el-col>
                <el-col :span="3">{{item.price * item.count * item.active}}</el-col>
                <el-col :span="3">
                  <img src="../assets/logo.png" @click="del(item)" style=" 30px; height: 30px;">
                </el-col>
              </li>
            </ul>
          </div>
    
        </div>
        <div v-else>购物车没有商品,快去逛逛</div>
        <div>
          <div class="cls">
          <!-- {{selectArrCloth}} -->
            <el-checkbox v-model="allCheck" @change="getAllChecked">全选</el-checkbox>
          </div>
          <div class="cls">合计 {{totalPrice}} 元</div>
          <div class="cls">已选商品 {{totalCount}} 件</div>
        </div>
      </div>
    
    </template>
    
    <script>
      import bus from '@/assets/bus.js'
      export default {
        data() {
          return {
            selectArrCloth: [],
            totalCount: 0,
            totalPrice: 0,
            allCheck: false,
            list: []
          }
        },
        created() {
          this.getList()
        },
        methods: {
          getAllChecked(val) {
            let selectArrCloth = [];
            if (val) {
              this.list.forEach(item => {
                //根据状态来添加价格,所以需要点击全选的时候循环给数组中数据给true反之给false
                item.checked = true;
                selectArrCloth.push(item.id)
              })
              this.selectArrCloth = selectArrCloth;
            } else {
              this.list.forEach(item => {
                item.checked = false;
              })
              this.selectArrCloth = [];
            }
            this.getTotalCount();
          },
          getTotalCount: function() {
            let totalCount = 0;
            let totalPrice = 0;
            //循环添加属性
            this.list.forEach(item => {
              if (item.checked) {
                totalPrice = totalPrice + (parseFloat(item.price).toFixed(2) * parseFloat(item.active) * item.count)
                totalCount = totalCount + parseInt(item.count)
              }
            })
            this.totalCount = totalCount;
            this.totalPrice = totalPrice;
          },
          getList() {
            //ajax
            let arr = [{
                name: '款式1',
                count: '2',
                size: 'L',
                color: '红色',
                price: '120',
                active: '0.5',
                id: '1'
              },
              {
                name: '款式2',
                count: '2',
                size: 'L',
                color: '红色',
                price: '103',
                active: '0.5',
                id: '2'
              },
              {
                name: '款式3',
                count: '2',
                size: 'L',
                color: '红色',
                price: '150',
                active: '0.5',
                id: '3'
              },
              {
                name: '款式4',
                count: '2',
                size: 'L',
                color: '红色',
                price: '160',
                active: '0.5',
                id: '4'
              },
            ]
            //循环给数组中元素增加一个默认checked为false的属性
            arr.forEach(item => {
              item.checked = false;
            })
            this.list = arr;
          },
          pre: function(item) {
            if (item.count == 0) return;
            item.count--;
            this.getTotalCount();
          },
          add: function(item) {
            item.count++;
            this.getTotalCount();
          },
          del: function(item) {
            //当点击这个图片的下标与数组中下标一致清除这个数据返回新数组
            let index = this.list.findIndex(cloth => {
              return cloth.id == item.id
            })
            // console.log(index)
            this.list.splice(index, 1)
            this.getTotalCount();
          },
        },
        watch: {
          //当id状态数组发生改变的时候会执行这个方法
          selectArrCloth: function() {
            this.getTotalCount();
            if (this.selectArrCloth.length == this.list.length) {
              this.allCheck = true;
            } else {
              this.allCheck = false;
            }
          },
          //监听list
          //此时list为一个对象
          list:{
            //当值为函数的时候不会进行深度遍历
            //需要让其数组进行深度遍历用handler方法
            //当deep为true的时候就会深度监听
            handler:function(){
              let count = 0;
              this.list.forEach(item => {
                count += parseInt(item.count)
              })
              bus.$emit('buycarCountChange', count)
            },
            deep: true
          }
        }
      }
    </script>
    <!-- 加上scoped为本组件生效 -->
    <style scoped>
      .cls {
        display: inline-block;
        margin-top: 50px;
        margin-left: 400px;
        color: red;
      }
    </style>

    以上为购物车demo

    本文仅提供参考,是本人闲时所写笔记,如有错误,还请赐教,作者:阿蒙不萌,大家可以随意转载

  • 相关阅读:
    python数据分析之pandas库的Series应用
    LINUX学习
    DBA日常SQL之查询数据库运行状况
    使用RMAN从磁带库恢复归档文件
    PHP系列 | PHPexcel导入xls格式 ,提示错误:iconv(): Wrong charset, conversion from `CP936' to `UTF-8' is not allowed
    工具系列 | 使用Lodop进行WEB打印程序开发
    PHP系列 | 编译安装msgpack-php
    Nginx系列 | [转]Nginx 上传文件:client_max_body_size 、client_body_buffer_size
    PHP系列 | Session 存储在Redis
    PHP系列 | PHP5.6 安装 endroid/qr-code 遇到的问题
  • 原文地址:https://www.cnblogs.com/huchong-bk/p/11871878.html
Copyright © 2011-2022 走看看