Vue购物车应用实现教程

文章目录

    • 1. 项目介绍
    • 2. 开发环境准备
    • 3. 设计购物车界面
    • 4. 创建Vue实例和数据模型
    • 5. 实现购物车功能
      • 5.1 从本地存储加载数据
      • 5.2 监听数据变化保存到本地存储
      • 5.3 实现全选/反选功能
      • 5.4 计算选中商品的总价和总数量
      • 5.5 实现修改商品数量功能
      • 5.6 实现删除商品功能
      • 5.7 实现结算功能
    • 6. 添加样式
    • 7. 完整代码
    • 8. Vue知识点解析
      • 8.1 数据渲染与绑定
      • 8.2 条件渲染与列表渲染
      • 8.3 类与样式绑定
      • 8.4 事件处理
      • 8.5 计算属性
      • 8.6 侦听器
      • 8.7 生命周期钩子
      • 8.8 属性绑定
    • 9. 功能扩展思路
    • 10. 总结

1. 项目介绍

本教程将带领初学者开发一个基于Vue.js的购物车应用,不需要使用脚手架,仅通过引入Vue.js库即可完成。通过这个项目,你将学习Vue的基础知识,包括:

  • 数据渲染与绑定
  • 事件处理
  • 计算属性
  • 侦听器
  • 条件渲染与列表渲染
  • 本地存储

完成后的购物车应用具有以下功能:

  • 商品列表渲染
  • 删除商品
  • 修改商品数量
  • 全选/反选功能
  • 统计选中商品的总价和总数量
  • 数据持久化到本地存储

2. 开发环境准备

对于初学者,我们采用最简单的方式搭建环境:通过CDN引入Vue.js。

创建一个基本的HTML文件结构:

DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue购物车title>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>
    
    <style>
        /* 样式稍后添加 */
    style>
head>
<body>
    <div id="app">
        
    div>

    <script>
        // Vue代码将写在这里
    script>
body>
html>

3. 设计购物车界面

我们设计一个简洁的购物车界面,包含以下部分:

  1. 标题
  2. 商品列表(每项包含复选框、图片、名称、单价、数量控制和删除按钮)
  3. 底部结算栏(全选按钮、总计和结算按钮)

更新HTML结构:

<div id="app">
    <div class="cart">
        <div class="cart-header">
            <h1>{{ title }}h1>
        div>
        
        
        <div class="empty-cart" v-if="cartItems.length === 0">
            <p>购物车空空如也,快去选购商品吧!p>
        div>
        
        
        <div class="cart-items" v-else>
            <div class="cart-item" v-for="(item, index) in cartItems" :key="item.id" :class="{'selected-item': item.checked}">
                <div class="item-check">
                    <input type="checkbox" v-model="item.checked">
                div>
                <div class="item-img">
                    <img :src="item.img" :alt="item.name">
                div>
                <div class="item-info">
                    <h3>{{ item.name }}h3>
                    <p class="item-price">¥{{ item.price.toFixed(2) }}p>
                div>
                <div class="item-quantity">
                    <button @click="decreaseQuantity(item.id)" :disabled="item.quantity <= 1">-button>
                    <input type="number" v-model.number="item.quantity" min="1">
                    <button @click="increaseQuantity(item.id)">+button>
                div>
                <div class="item-subtotal">
                    <p>¥{{ (item.price * item.quantity).toFixed(2) }}p>
                div>
                <div class="item-remove">
                    <button @click="removeItem(item.id)">删除button>
                div>
            div>
        div>
        
        
        <div class="cart-footer" v-if="cartItems.length > 0">
            <div class="select-all">
                <input type="checkbox" v-model="selectAll">
                <label>全选label>
            div>
            <div class="cart-total">
                <p>已选择 <span>{{ selectedCount }}span> 件商品p>
                <p>总计: <span>¥{{ totalPrice }}span>p>
            div>
            <div class="checkout">
                <button @click="checkout">结算button>
            div>
        div>
    div>
div>

4. 创建Vue实例和数据模型

在script标签中,我们创建Vue实例并定义数据模型:

new Vue({
    el: '#app',
    data: {
        title: 'Vue购物车',
        // 购物车商品数据
        cartItems: [
            {
                id: 1,
                name: '商品1',
                price: 199,
                quantity: 1,
                img: 'https://via.placeholder.com/80',
                checked: false
            },
            {
                id: 2,
                name: '商品2',
                price: 299,
                quantity: 2,
                img: 'https://via.placeholder.com/80',
                checked: false
            },
            {
                id: 3,
                name: '商品3',
                price: 399,
                quantity: 1,
                img: 'https://via.placeholder.com/80',
                checked: false
            }
        ]
    },
    // 计算属性将在后面定义
    computed: {
        // 计算属性将在这里实现
    },
    // 方法将在后面定义
    methods: {
        // 方法将在这里实现
    },
    // 监听器将在后面定义
    watch: {
        // 监听器将在这里实现
    },
    // 生命周期钩子函数将在后面定义
    created() {
        // 从本地存储加载购物车数据
    }
});

5. 实现购物车功能

5.1 从本地存储加载数据

首先,我们修改生命周期钩子函数,从本地存储加载购物车数据:

created() {
    // 从本地存储加载购物车数据
    const savedCart = localStorage.getItem('vue-cart');
    if (savedCart) {
        this.cartItems = JSON.parse(savedCart);
    }
}

5.2 监听数据变化保存到本地存储

添加侦听器,将购物车数据保存到本地存储:

watch: {
    // 深度监听购物车数据变化
    cartItems: {
        handler(newValue) {
            // 将购物车数据保存到本地存储
            localStorage.setItem('vue-cart', JSON.stringify(newValue));
        },
        deep: true // 深度监听对象内部的变化
    }
}

5.3 实现全选/反选功能

添加计算属性和相关方法来实现全选/反选功能:

computed: {
    // 计算全选状态
    selectAll: {
        // 获取全选状态
        get() {
            // 如果购物车为空,返回false
            if (this.cartItems.length === 0) return false;
            // 检查是否所有商品都被选中
            return this.cartItems.every(item => item.checked);
        },
        // 设置全选状态
        set(value) {
            // 将所有商品的选中状态设置为全选的状态
            this.cartItems.forEach(item => {
                item.checked = value;
            });
        }
    }
}

5.4 计算选中商品的总价和总数量

添加计算属性来统计选中商品的总价和总数量:

computed: {
    // 已定义的计算属性
    selectAll: {
        // ... 前面的代码
    },
    
    // 计算选中商品的总数量
    selectedCount() {
        return this.cartItems.reduce((total, item) => {
            return item.checked ? total + item.quantity : total;
        }, 0);
    },
    
    // 计算选中商品的总价
    totalPrice() {
        return this.cartItems.reduce((total, item) => {
            return item.checked ? total + (item.price * item.quantity) : total;
        }, 0).toFixed(2);
    }
}

5.5 实现修改商品数量功能

添加方法来增加和减少商品数量:

methods: {
    // 增加商品数量
    increaseQuantity(id) {
        const item = this.cartItems.find(item => item.id === id);
        if (item) {
            item.quantity++;
        }
    },
    
    // 减少商品数量
    decreaseQuantity(id) {
        const item = this.cartItems.find(item => item.id === id);
        if (item && item.quantity > 1) {
            item.quantity--;
        }
    }
}

5.6 实现删除商品功能

添加方法来删除购物车中的商品:

methods: {
    // 已定义的方法
    increaseQuantity(id) {
        // ... 前面的代码
    },
    
    decreaseQuantity(id) {
        // ... 前面的代码
    },
    
    // 删除商品
    removeItem(id) {
        if (confirm('确定要删除这个商品吗?')) {
            // 根据id查找商品索引
            const index = this.cartItems.findIndex(item => item.id === id);
            if (index !== -1) {
                // 从数组中删除商品
                this.cartItems.splice(index, 1);
            }
        }
    }
}

5.7 实现结算功能

添加一个简单的结算方法:

methods: {
    // 已定义的方法
    // ... 前面的代码
    
    // 结算方法
    checkout() {
        // 检查是否有选中的商品
        if (this.selectedCount === 0) {
            alert('请至少选择一件商品');
            return;
        }
        
        // 显示结算信息
        alert(`您已选择${this.selectedCount}件商品,总计:¥${this.totalPrice},感谢购买!`);
        
        // 实际应用中这里应该跳转到结算页面或发送请求到后端
        // 为了演示,我们仅移除已选中的商品
        this.cartItems = this.cartItems.filter(item => !item.checked);
    }
}

6. 添加样式

为了让购物车看起来更美观,我们添加一些CSS样式:

/* 将这些样式添加到