vue的简单购物车案例

发布时间:2023年12月17日

实现功能有:

1.渲染功能:v-if / v-else? ? ? ? v-for? ? ? ? :class

2.删除功能:点击传参 filter过滤覆盖原数据

3.修改个数:点击传参 find找对象

4.全选反选:计算属性computed 完整写法 get/set

5.统计选中的总价和总数量:计算属性computed reduce条件求和

6.持久化到本地:watch监视,local storage,json.stringify,json.parse

<!DOCTYPE html>

<html lang="en">

? <head>

? ? <meta charset="UTF-8" />

? ? <meta http-equiv="X-UA-Compatible" content="IE=edge" />

? ? <meta name="viewport" content="width=device-width, initial-scale=1.0" />

? ? <link rel="stylesheet" href="./css/inputnumber.css" />

? ? <link rel="stylesheet" href="./css/index.css" />

? ? <title>购物车</title>

? </head>

? <body>

? ? <div class="app-container" id="app">

? ? ? <!-- 顶部banner -->

? ? ? <div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" /></div>

? ? ? <!-- 面包屑 -->

? ? ? <div class="breadcrumb">

? ? ? ? <span>🏠</span>

? ? ? ? /

? ? ? ? <span>购物车</span>

? ? ? </div>

? ? ? <!-- 购物车主体 -->

? ? ? <div class="main" v-if="fruitList.length > 0">

? ? ? ? <div class="table">

? ? ? ? ? <!-- 头部 -->

? ? ? ? ? <div class="thead">

? ? ? ? ? ? <div class="tr">

? ? ? ? ? ? ? <div class="th">选中</div>

? ? ? ? ? ? ? <div class="th th-pic">图片</div>

? ? ? ? ? ? ? <div class="th">单价</div>

? ? ? ? ? ? ? <div class="th num-th">个数</div>

? ? ? ? ? ? ? <div class="th">小计</div>

? ? ? ? ? ? ? <div class="th">操作</div>

? ? ? ? ? ? </div>

? ? ? ? ? </div>

? ? ? ? ? <!-- 身体 -->

? ? ? ? ? <div class="tbody">

? ? ? ? ? ? <div v-for="(item, index) in fruitList" :key="item.id" class="tr" :class="{ active: item.isChecked }">

? ? ? ? ? ? ? <div class="td"><input type="checkbox" v-model="item.isChecked" /></div>

? ? ? ? ? ? ? <div class="td"><img :src="item.icon" alt="" /></div>

? ? ? ? ? ? ? <div class="td">{{ item.price }}</div>

? ? ? ? ? ? ? <div class="td">

? ? ? ? ? ? ? ? <div class="my-input-number">

? ? ? ? ? ? ? ? ? <button :disabled="item.num <= 1" class="decrease" @click="sub(item.id)"> - </button>

? ? ? ? ? ? ? ? ? <span class="my-input__inner">{{ item.num }}</span>

? ? ? ? ? ? ? ? ? <button class="increase" @click="add(item.id)"> + </button>

? ? ? ? ? ? ? ? </div>

? ? ? ? ? ? ? </div>

? ? ? ? ? ? ? <div class="td">{{ item.num * item.price }}</div>

? ? ? ? ? ? ? <div class="td"><button @click="del(item.id)">删除</button></div>

? ? ? ? ? ? </div>

? ? ? ? ? </div>

? ? ? ? </div>

? ? ? ? <!-- 底部 -->

? ? ? ? <div class="bottom">

? ? ? ? ? <!-- 全选 -->

? ? ? ? ? <label class="check-all">

? ? ? ? ? ? <input type="checkbox" v-model="isAll"/>

? ? ? ? ? ? 全选

? ? ? ? ? </label>

? ? ? ? ? <div class="right-box">

? ? ? ? ? ? <!-- 所有商品总价 -->

? ? ? ? ? ? <span class="price-box">总价&nbsp;&nbsp;:&nbsp;&nbsp;¥&nbsp;<span class="price">{{ totalPrice }}</span></span>

? ? ? ? ? ? <!-- 结算按钮 -->

? ? ? ? ? ? <button class="pay">结算( {{ totalCount }} )</button>

? ? ? ? ? </div>

? ? ? ? </div>

? ? ? </div>

? ? ? <!-- 空车 -->

? ? ? <div class="empty" v-else>🛒空空如也</div>

? ? </div>

? ? <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

? ? <script>

? ? ? const defaultArr = [

? ? ? ? ? ? {

? ? ? ? ? ? ? id: 1,

? ? ? ? ? ? ? icon: 'http://autumnfish.cn/static/火龙果.png',

? ? ? ? ? ? ? isChecked: true,

? ? ? ? ? ? ? num: 2,

? ? ? ? ? ? ? price: 6,

? ? ? ? ? ? },

? ? ? ? ? ? {

? ? ? ? ? ? ? id: 2,

? ? ? ? ? ? ? icon: 'http://autumnfish.cn/static/荔枝.png',

? ? ? ? ? ? ? isChecked: false,

? ? ? ? ? ? ? num: 7,

? ? ? ? ? ? ? price: 20,

? ? ? ? ? ? },

? ? ? ? ? ? {

? ? ? ? ? ? ? id: 3,

? ? ? ? ? ? ? icon: 'http://autumnfish.cn/static/榴莲.png',

? ? ? ? ? ? ? isChecked: false,

? ? ? ? ? ? ? num: 3,

? ? ? ? ? ? ? price: 40,

? ? ? ? ? ? },

? ? ? ? ? ? {

? ? ? ? ? ? ? id: 4,

? ? ? ? ? ? ? icon: 'http://autumnfish.cn/static/鸭梨.png',

? ? ? ? ? ? ? isChecked: true,

? ? ? ? ? ? ? num: 10,

? ? ? ? ? ? ? price: 3,

? ? ? ? ? ? },

? ? ? ? ? ? {

? ? ? ? ? ? ? id: 5,

? ? ? ? ? ? ? icon: 'http://autumnfish.cn/static/樱桃.png',

? ? ? ? ? ? ? isChecked: false,

? ? ? ? ? ? ? num: 20,

? ? ? ? ? ? ? price: 34,

? ? ? ? ? ? },

? ? ? ? ? ]

? ? ? const app = new Vue({

? ? ? ? el: '#app',

? ? ? ? data: {

? ? ? ? ? // 水果列表

? ? ? ? ? fruitList: JSON.parse(localStorage.getItem('list')) || defaultArr,

? ? ? ? },

? ? ? ? computed: {

? ? ? ? ? // 默认计算属性:只能获取不能设置,要设置需要写完整写法

? ? ? ? ? // isAll () {

? ? ? ? ? // ? // 必须所有的小选框都选中,全选按钮才选中 → every

? ? ? ? ? // ? return this.fruitList.every(item => item.isChecked)

? ? ? ? ? // }

? ? ? ? ?

? ? ? ? ? // 完整写法 = get + set

? ? ? ? ? isAll: {

? ? ? ? ? ? get () {

? ? ? ? ? ? ? return this.fruitList.every(item => item.isChecked)

? ? ? ? ? ? },

? ? ? ? ? ? set (value) {

? ? ? ? ? ? ? // 基于拿到的布尔值,要让所有的小选框 同步状态

? ? ? ? ? ? ? this.fruitList.forEach(item => item.isChecked = value)

? ? ? ? ? ? ? // forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

? ? ? ? ? ? }

? ? ? ? ? },

? ? ? ? ? // 统计选中的总数 reduce

? ? ? ? ? // reduce () 方法是 JavaScript Array 对象的一个方法,用于将数组中的每个值缩减为一个值,接收一个函数作为累加器。

? ? ? ? ? totalCount () {

? ? ? ? ? ? return this.fruitList.reduce((sum, item) => {

? ? ? ? ? ? ? if (item.isChecked) {

? ? ? ? ? ? ? ? // 选中 → 需要累加

? ? ? ? ? ? ? ? return sum + item.num

? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? // 没选中 → 不需要累加

? ? ? ? ? ? ? ? return sum

? ? ? ? ? ? ? }

? ? ? ? ? ? }, 0)

? ? ? ? ? },

? ? ? ? ? // 总计选中的总价 num * price

? ? ? ? ? totalPrice () {

? ? ? ? ? ? return this.fruitList.reduce((sum, item) => {

? ? ? ? ? ? ? if (item.isChecked) {

? ? ? ? ? ? ? ? return sum + item.num * item.price

? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? return sum

? ? ? ? ? ? ? }

? ? ? ? ? ? }, 0)

? ? ? ? ? }

? ? ? ? },

? ? ? ? methods: {

? ? ? ? ? del (id) {

? ? ? ? ? ? this.fruitList = this.fruitList.filter(item => item.id !== id)

? ? ? ? ? },

? ? ? ? ? add (id) {

? ? ? ? ? ? // 1. 根据 id 找到数组中的对应项 → find

? ? ? ? ? ? const fruit = this.fruitList.find(item => item.id === id)

? ? ? ? ? ? // 2. 操作 num 数量

? ? ? ? ? ? fruit.num++

? ? ? ? ? },

? ? ? ? ? sub (id) {

? ? ? ? ? ? // 1. 根据 id 找到数组中的对应项 → find

? ? ? ? ? ? const fruit = this.fruitList.find(item => item.id === id)

? ? ? ? ? ? // 2. 操作 num 数量

? ? ? ? ? ? fruit.num--

? ? ? ? ? }

? ? ? ? },

? ? ? ? watch: {

? ? ? ? ? fruitList: {

? ? ? ? ? ? deep: true,

? ? ? ? ? ? handler (newValue) {

? ? ? ? ? ? ? // 需要将变化后的 newValue 存入本地 (转JSON)

? ? ? ? ? ? ? localStorage.setItem('list', JSON.stringify(newValue))

? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? }

? ? ? })

? ? </script>

? </body>

</html>

文章来源:https://blog.csdn.net/m0_59745705/article/details/134985397
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。