js+vue+vuex点击步进器加入购物车、计算价格、点单列表,点单总数,单个列表点单数量,总价格,vuex版(增加,删除,金额计算,存储,总数,单个列表点单数量,总价格)

24 篇文章 0 订阅
6 篇文章 0 订阅
该文展示了如何使用Vue和Vuex构建一个点餐系统,包括点击步进器增加或减少商品数量,计算单个商品价格,存储点单列表,以及计算总价。利用Vuex的状态管理来同步数据,并使用vuex-persistedstate插件持久化状态。
摘要由CSDN通过智能技术生成

js+vue+vuex点击步进器加入购物车、计算价格、点单列表,点单总数,单个列表点单数量,总价格,vuex版(增加,删除,金额计算,存储,总数,单个列表点单数量,总价格)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

vuex

写在package.json 的"dependencies"方法中 然后重新安装依赖
“vuex-persistedstate”: “^4.1.0”

import Vue from 'vue'
import Vuex from 'vuex'
import persistedState from 'vuex-persistedstate'
Vue.use(Vuex)
const state = {
  orderList: [], //食堂列表数据
  payList: [], //已点餐列表
  num: 0, //总金额
  listNum: 0, //总数量
}

const mutations = {
  orderList(state, data) {
    console.log(data)
    state.orderList = data
  },
  payList(state, data) {
    state.payList = data
  },
  num(state, data) {
    state.num = data
  },
  listNum(state, data) {
    state.listNum = data
  },
}

const store = new Vuex.Store({
  state,
  mutations,
  modules: {},
  plugins: [persistedState({ storage: window.sessionStorage })],
})

export default store

vue页面

<template>
  <div class="home">
    <div class="list">
      <div class="top flex-s">
        <div class="top-left flex">
          <div class="image">
            <img alt="" src="../../assets/images/order/dc_dw@2x.png" />
          </div>
          <div class="title">鲜辣面食店(中海大厦店)</div>
        </div>
        <div class="top-right flex">
          <div class="num-title">桌号:</div>
          <div class="num-text">A09</div>
        </div>
      </div>
      <div class="search">
        <van-search
          v-model="value"
          placeholder="请输入搜索关键词"
          @clear="clear"
          @search="search"
        />
      </div>
      <div class="list-item flex-s">
        <div class="item-left">
          <div
            v-for="(item, index) in $store.state.orderList"
            :key="index"
            :class="activeKey == index ? 'tab-items' : 'tab-item'"
            @click="getTab(index)"
          >
            <div class="item-tab flex">
              <div v-if="item.url" class="image">
                <img alt="" src="../../assets/images/order/dc_rq@2x.png" />
              </div>
              <div class="title">
                {{ item.title }}
                <div v-if="item.badge" class="text-red">
                  {{ item.badge }}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="item-right">
          <div
            v-for="(item, index) in $store.state.orderList[activeKey].list"
            :key="index"
            class="flex item-list"
          >
            <div class="item-left-image">
              <img alt="" :src="item.url" />
            </div>
            <div class="item-right-list">
              <div class="list-title">{{ item.title }}</div>
              <div class="list-center flex">
                <div class="center-img">
                  <img alt="" src="../../assets/images/order/dc_zk@2x.png" />
                </div>
                <div class="center-text">{{ item.value }}</div>
              </div>
              <div class="list-footer flex-s">
                <div class="list-left">
                  <span class="list-text">¥</span>
                  <span class="list-num">{{ item.price }}</span>
                  <span class="list-text">/份</span>
                </div>
                <div class="list-right">
                  <van-stepper
                    v-model="item.num"
                    button-size="22"
                    disable-input
                    max="10"
                    min="0"
                    theme="round"
                    @minus="minus(index, item)"
                    @plus="plus(index, item)"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="popup">
      <div></div>
      <div class="num">
        总价格{{ num }}&emsp;&emsp;&emsp;总数量{{ listNum }}
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    components: {
    },
    data() {
      return {
        value: '',
        activeKey: 0,
        data: [
          {
            title: '人气',
            badge: 0,
            url: require('../../assets/images/order/dc_dd.png'),
            list: [
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 1,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 2,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 3,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 4,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 5,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 6,
              },
            ],
          },
          {
            title: '面食系列',
            badge: 0,
            list: [
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 7,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 8,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 9,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 10,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 11,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 12,
              },
            ],
          },
          {
            title: '套餐系列',
            badge: 0,
            list: [
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 13,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 14,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 15,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 16,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 17,
              },
              {
                url: require('@/assets/images/order/dc_tu@2x.png'),
                title: '红烧肉酸辣米线辣辣米',
                value: '5.4折',
                num: 0,
                price: 42.0,
                id: 18,
              },
            ],
          },
        ],
        num: this.$store.state.num || 0, //总金额
        listNum: this.$store.state.listNum || 0, //总数量
      }
    },
    computed: {
      Total() {
        //在这里定义一个total为0,来存放他的总价
        let total = 0
        //循环data
        for (let i = 0; i < this.$store.state.orderList.length; i++) {
          //循环data下标的list
          for (let v = 0; v < this.$store.state.orderList[i].list.length; v++) {
            //相当于 total = list每一个数量 * list每一个的价钱
            total +=
              this.$store.state.orderList[i].list[v].num *
              this.$store.state.orderList[i].list[v].price
          }
        }
        return total
      },
      listTotal() {
        let num = 0
        //循环data
        for (let i = 0; i < this.$store.state.orderList.length; i++) {
          //相当于 num = datax下标的badge
          num += this.$store.state.orderList[i].badge
        }
        return num
      },
    },
    watch: {
      Total(val) {
        this.num = val
        this.$store.commit('num', val)
      },
      listTotal(val) {
        this.listNum = val
        this.$store.commit('listNum', val)
      },
    },
    mounted() {
      this.$store.commit('orderList', this.data)
    },
    methods: {
      // 搜索
      search(val) {
        console.log(val)
      },
      // 清空
      clear() {
        this.value = ''
      },
      // 点击切换
      getTab(index) {
        this.activeKey = index
      },
      // 减
      minus(index) {
        this.$store.state.orderList[this.activeKey].badge--
        this.$store.state.orderList[this.activeKey].list[index].num--
        this.$store.state.payList.filter((i, v) => {
          if (i.num == 0) {
            this.$store.state.payList.splice(v, 1)
          }
        })
      },
      //查询函数
      findPlus(key, val, arr) {
        let open = false
        arr.forEach((item) => {
          if (item[key] == val) {
            open = true
          }
        })
        return open
      },
      // 加
      plus(index, item) {
        this.$store.state.orderList[this.activeKey].badge++
        this.$store.state.orderList[this.activeKey].list[index].num++
        let open = this.findPlus('id', item.id, this.$store.state.payList)
        if (!open) {
          this.$store.state.payList.push(item)
        }
      },
    },
  }
</script>

<style lang="scss" scoped>
  .home {
    height: 100vh;
    background: #fff;
    .list {
      height: calc(100vh - 120px);
      overflow: hidden;
      .top {
        padding: 38px 24px 0 24px;
        margin-bottom: 20px;
        .top-left {
          display: flex;
          align-items: center;
          .image {
            width: 28px;
            height: 32px;
            margin: 5px 12px 0 0;
            img {
              width: 100%;
              height: 100%;
            }
          }
          .title {
            margin: auto 0;
            width: 60vw;
            min-height: 44px;
            font-weight: 500;
            font-size: 32px;
            color: #333333;
          }
        }
        .top-right {
          .num-title {
            line-height: 74px;
            font-weight: 500;
            font-size: 26px;
            color: #666666;
          }
          .num-text {
            font-weight: 500;
            font-size: 52px;
            color: #fb6c1e;
          }
        }
      }
      .search {
        margin-bottom: 20px;
        ::v-deep {
          .van-search {
            margin: 0 24px;
            display: -webkit-box;
            display: -webkit-flex;
            display: flex;
            -webkit-box-align: center;
            -webkit-align-items: center;
            align-items: center;
            box-sizing: border-box;
            height: 72px;
            background: #ffffff;
            border: 2px solid #dddddd;
            border-radius: 46px;
          }
          .van-search__content {
            display: -webkit-box;
            display: -webkit-flex;
            display: flex;
            -webkit-box-flex: 1;
            -webkit-flex: 1;
            flex: 1;
            padding-left: 12px;
            background-color: #ffffff;
            border-radius: 2px;
          }
        }
      }
      .list-item {
        height: 74vh;
        overflow: hidden;
        .item-left {
          width: 164px;
          height: 74vh;
          overflow-y: scroll;
          .tab-item {
            display: flex;
            align-items: center;
            min-width: 82px;
            background: #f8f8f8;
            .item-tab {
              margin: 0 auto;
              .image {
                width: 30px;
                height: 30px;
                margin: auto 6px auto 0;
                img {
                  width: 100%;
                  height: 100%;
                }
              }
              .title {
                font-size: 24px;
                color: #333333;
                position: relative;
                height: 100px;
                // line-height: 100px;
                display: flex;
                align-items: center;
                .text-red {
                  position: absolute;
                  top: 14px;
                  right: -20px;
                  box-sizing: border-box;
                  min-width: 32px;
                  padding: 0 6px;
                  color: #fff;
                  font-weight: 500;
                  font-size: 24px;
                  font-family: -apple-system-font, Helvetica Neue, Arial,
                    sans-serif;
                  line-height: 24px;
                  text-align: center;
                  background-color: #ee0a24;
                  border: 1px solid #fff;
                  border-radius: 32px;
                }
              }
            }
          }
          .tab-items {
            height: 60px;
            line-height: 60px;
            display: flex;
            align-items: center;
            min-width: 82px;
            background: #fff;
            border-left: 8px solid red;
            margin: 20px 0;
            .item-tab {
              height: 34px;
              margin: 0 auto;
              .image {
                width: 30px;
                height: 30px;
                margin: auto 6px auto 0;
                img {
                  width: 100%;
                  height: 100%;
                }
              }
              .title {
                font-size: 24px;
                color: #333333;
                position: relative;
                // height: 100px;
                // line-height: 100px;
                display: flex;
                align-items: center;
                .text-red {
                  position: absolute;
                  top: -16px;
                  right: -20px;
                  z-index: 33;
                  box-sizing: border-box;
                  min-width: 32px;
                  padding: 0 3px;
                  color: #fff;
                  font-weight: 500;
                  font-size: 24px;
                  font-family: -apple-system-font, Helvetica Neue, Arial,
                    sans-serif;
                  height: 32px;
                  line-height: 32px;
                  text-align: center;
                  background-color: #ee0a24;
                  border: 1px solid #fff;
                  border-radius: 32px;
                }
              }
            }
          }
        }
        .item-right {
          width: 588px;
          height: 74vh;
          overflow-y: scroll;
          background: #fff;
          .item-list {
            margin: 20px;
            height: 168px;
            .item-left-image {
              width: 168px;
              height: 168px;
              margin-right: 20px;
              img {
                width: 100%;
                height: 100%;
              }
            }
            .item-right-list {
              width: 356px;
              height: 168px;
              position: relative;
              .list-title {
                font-size: 26px;
                color: #333333;
                margin-bottom: 8px;
              }
              .list-center {
                width: 104px;
                background: #ffeee5;
                border-radius: 4px;
                padding: 8px;
                .center-img {
                  width: 16px;
                  height: 16px;
                  margin: auto 10px auto 0;
                  img {
                    width: 100%;
                    height: 100%;
                  }
                }
                .center-text {
                  font-size: 24px;
                  color: #fb6c1e;
                }
              }
              .list-footer {
                position: absolute;
                bottom: 0;
                .list-left {
                  .list-text {
                    color: #999999;
                    font-size: 16px;
                  }
                  .list-num {
                    color: #333333;
                    font-size: 28px;
                    font-weight: 500;
                  }
                }
                .list-right {
                  ::v-deep {
                    .van-stepper--round .van-stepper__minus {
                      color: #000;
                      background-color: #fff;
                      border: 1px solid #fb6c1e;
                    }
                    .van-stepper--round .van-stepper__plus {
                      color: #fff;
                      background-color: #fb6c1e;
                    }
                    .van-stepper {
                      font-size: 0;
                      -webkit-user-select: none;
                      user-select: none;
                      position: absolute;
                      bottom: 0;
                      right: -30vw;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    .popup {
      position: fixed;
      bottom: 140px;
      left: 20px;
      right: 20px;
      height: 104px;
      background: #333333;
      box-shadow: 0 4px 20px 0 #00000033;
      border-radius: 52px;
      .num {
        color: #fff;
      }
    }
  }
  .flex {
    display: flex;
  }
  .flex-s {
    display: flex;
    justify-content: space-between;
  }
</style>

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
对于在VSCode中配置Vue3、Vuex和Uniapp的开发环境,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了Node.js和npm(Node.js的包管理)。你可以在官网上下载并安装它们。 2. 接下来,你需要全局安装Vue CLI。在命令行中执行以下命令: ``` npm install -g @vue/cli ``` 3. 创建一个新的Vue项目。在命令行中进入你想要创建项目的目录,并执行以下命令: ``` vue create your-project-name ``` 根据提示选择你需要的特性和插件,包括Vuex,以及是否使用TypeScript等。 4. 安装Uniapp插件。在命令行中进入项目目录,并执行以下命令: ``` vue add uni-app ``` 根据提示选择适用于你的平台(如H5、微信小程序等)以及是否使用TypeScript等。 5. 配置Vuex。在项目目录中找到src目录,然后创建一个store目录,在其中创建一个index.js文件。在index.js中编写你的Vuex配置,例如: ```javascript import { createStore } from 'vuex' const store = createStore({ state: { // 状态 }, mutations: { // 修改状态的方法 }, actions: { // 异步操作 }, getters: { // 计算属性 } }) export default store ``` 然后,在src目录的main.js中引入Vuex并使用它: ```javascript import { createApp } from 'vue' import App from './App.vue' import store from './store/index' createApp(App).use(store).mount('#app') ``` 6. 在VSCode中打开你的项目,在扩展商店中搜索并安装VueVuex和Uniapp相关的插件,例如"Vetur"和"uniapp-snippet"等。这些插件将提供语法高亮、代码提示和其他开发工具。 现在,你已经成功配置了VSCode中的Vue3、Vuex和Uniapp开发环境。你可以开始开发你的项目了。祝你好运!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周亚鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值