学习Vue之商城案例(代码+详解)

 目前,我们学习Vue的一些基础的知识,那么就让我们做一个像下图这样简单的商城案例吧。


目录

通过脚手架创建项目

安装axios和bootstrap组件

安装axios和bootstrap

在保存的时候不进行格式化校验

初步定义App.vue文件

初步渲染组件页面

根据接口渲染商品

根据结构数据渲染商品具体信息

对商品数量组件进行渲染与操作

实现数量组件的增加与减少

实现全选选项

实现价格合计

实现结算后数量的变化


通过脚手架创建项目

本篇通过@vue/cli脚手架来创建形目,具体的如何导入vue、如何创建就不过多赘述啦~

安装axios和bootstrap组件

npm i axios
npm i bootstrap

安装axios和bootstrap

在main.js中配置axios和bootstrap

配置axios

import axios from 'axios'

引入bootstrap

import 'bootstrap/dist/css/bootstrap.min.css'import 'bootstrap/dist/js/bootstrap.min.js'

把axios放到vue对象的属性上

Vue.prototype.axios = axios

在保存的时候不进行格式化校验

在vue.config.js中输入,防止系统因格式太多报错

lintOnSave: false

初步定义App.vue文件

在script中引入所有组件

import (组件名) from '(组件路径)';

本文件中引入:

 import shopHeader from './components/shopHeader.vue';import good from './components/good.vue';import shopFoot from './components/shopFoot.vue';import count from './components/count.vue';

注册组件

在export default中注册

components:{``(组件名称)``}

本文件中引入:

 components:{shopHeader,good,shopFoot,count}

利用组件标签初步渲染页面

在template中使用自定义组件标签

 <div><shop-Header></shop-Header><div style="margin-top: 40px;"></div><good></good><shopFoot></shopFoot></div>

初步渲染组件页面

在这里,我们将初步的格式给到大家~

shopHeader.vue

 <template><div class="my-header">购物车案例</div></template>​<script>export default {​}</script>​<style lang="less" scoped>.my-header {height: 45px;line-height: 45px;text-align: center;background-color: #1d7bff;color: #fff;position: fixed;top: 0;left: 0;width: 100%;z-index: 2;}</style>

goods.vue

 <template><div class="my-goods-item"><div class="left"><div class="custom-control custom-checkbox"><input type="checkbox" class="custom-control-input" id="input"><label class="custom-control-label" for="input"><img src="http://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" alt=""></label></div></div><div class="right"><div class="top">商品名字</div><div class="bottom"><span class="price">¥ 100</span><span>数量组件</span></div></div></div></template>​<script>export default {​}​</script>​<style lang="less" scoped>.my-goods-item {display: flex;padding: 10px;border-bottom: 1px solid #ccc;.left {img {width: 120px;height: 120px;margin-right: 8px;border-radius: 10px;}.custom-control-label::before,.custom-control-label::after {top: 50px;}}.right {flex: 1;display: flex;flex-direction: column;justify-content: space-between;.top{font-size: 14px;font-weight: 700;}.bottom {display: flex;justify-content: space-between;padding: 5px 0;align-items: center;.price {color: red;font-weight: bold;}}}}</style>

Count.vue

<template><div class="my-counter"><button type="button" class="btn btn-light" >-</button><input type="number" class="form-control inp" ><button type="button" class="btn btn-light">+</button></div></template>​<script>export default {​}</script>​<style lang="less" scoped>.my-counter {display: flex;.inp {width: 45px;text-align: center;margin: 0 10px;}.btn, .inp{transform: scale(0.9);}}</style>

shopFooter.vue

<template><!-- 底部 --><div class="my-footer"><!-- 全选 --><div class="custom-control custom-checkbox"><input type="checkbox" class="custom-control-input" id="footerCheck"><label class="custom-control-label" for="footerCheck">全选</label></div><!-- 合计 --><div><span>合计:</span><span class="price">¥ 0</span></div><!-- 按钮 --><button type="button" class="footer-btn btn btn-primary">结算 ( 0 )</button></div></template>​<script>export default {​}</script>​<style lang="less" scoped>.my-footer {position: fixed;z-index: 2;bottom: 0;width: 100%;height: 50px;border-top: 1px solid #ccc;display: flex;justify-content: space-between;align-items: center;padding: 0 10px;background: #fff;.price {color: red;font-weight: bold;font-size: 15px;}.footer-btn {min-width: 80px;height: 30px;line-height: 30px;border-radius: 25px;padding: 0;}}</style>

根据接口渲染商品

调用created钩子函数

created是一个生命周期钩子函数,用于在Vue实例被创建后立即被调用。

 created(){this.loadData()},

用数据定义一个空的 goods 数组,用于存储商品数据

data(){return {goods:[]}
}

给上述自定义组件标签设定一个循环输出属性

是一个循环,它遍历 goods 数组,并为每个数组项渲染一个 <good> 组件

在goods数组中循环item数据,标识item.id是唯一标识,并把item传递给good组件

<good v-for="item in goods" :key="item.id" :good="item" ></good>

设计loadData函数来获取接口数据

方法使用 axios 库发送一个 GET 请求到 h ttps://applet-base-api-t.itheima.net/api/goods 来获取商品数据

this.axios.get('https://applet-base-api-t.itheima.net/api/goods').then(res=>{}

了解接口数据属性

数据中有goods_name(商品名称),goods_price(商品价格),id(商品id),inputValue(商品购买数量),inputVisible(商品是否被勾选属性)为我们能用到的

判断有没有存入成功

如果请求成功,它将更新 goods 数组,并为每个商品设置一个初始的 inputValue

// 请求成功
if (res.data.status === 0){this.goods = res.data.data;
}

若未请求成功还要做出未反馈响应

else{alert('网络出小差了~')
}

根据结构数据渲染商品具体信息

在good.vue中进行修改

接收父组件传递的信息

props:['good']

利用插值表达式修改商品名称与价格

{{good.goods_name}} 
{{good.goods_price}}

对商品数量组件进行渲染与操作

对商品数量组件基本渲染

在good.vue中引入count组件并注册

import count from '@/components/count.vue';
components:{count},

用count组件自定义标签替换span标签中的数量组件文字

:good="good"用来接收good数据

<count :good="good"></count>

将数量组件设置默认为1

在上述请求数据的if语句中直接设定默认值

利用三元运算符来输入,item.inputValue在输入时就为空,所以当请求到的值为空时,默认输入为1,否则,把item.inputValue的数据取整

this.goods.forEach(item=>{item.inputValue = item.inputValue === "" ? 1 : parseInt(item.inputValue);
})

在count组件中渲染此数据

props:['good'],

将count组件中的input标签加上用来渲染

v-model="good.inputValue"

实现数量组件的增加与减少

首先,要在count上给“+”“-”按钮添加点击事件

@click="sub"
@click="add"

因为在组件内不能单独的进行运算,所以我们要把点击事件传递到父元素上去,在本实例中,我们要传递到父元素的父元素上

methods:{add(){this.$emit('add',this.good.id)},sub(){this.$emit('sub',this.good.id)}
}

在count中父元素为good组件,所以我们还要从good组件传递到app.vue中,

在good组件中,引用的count标签内接收一下

@add="add" @sub="sub"

并再次传递到App.vue上

methods:{add(id){this.$emit('add',id)},sub(id){this.$emit('sub',id)}
}

在App.vue的good标签中也接收一下

@add="add" @sub="sub"

并在定义增加与减少的语法

增加语法:方法用于增加商品的数量,它遍历 goods 数组,找到对应 id 的商品,并将其 inputValue 加一

add(id){this.goods.forEach(item=>{if (item.id === id){item.inputValue++;}})}

减少语法:方法用于减少商品的数量,它遍历 goods 数组,找到对应 id 的商品,并将其 inputValue 减一。如果 inputValue 已经为一,它将从 goods 数组中移除该商品

sub(id){this.goods.forEach(item=>{if (item.id === id){if(item.inputValue > 1){item.inputValue--;}else{this.goods.splice(item,1);} }})}

实现全选选项

找到shopFoot.vue组件

首先引入商品组件,根据依赖的数据(即 goods 数组)自动更新

props:['goods']

在App.vue的shopFoot标签中也要引入goods

:goods="goods"

在全选input框中添加checkAll自定义计算属性

v-model="checkAll"

checkAll计算属性方法

get:every 方法会遍历数组中的每个元素,并对每个元素执行一个回调函数。如果所有商品的 inputVisible 属性都为 true,则 every 方法返回 true,表示所有商品都被选中;否则,every方法返回 false,表示至少有一个商品没有被选中

set:接收一个参数 val,这个参数表示复选框的选中状态(true 或 false)。然后,它遍历 goods 数组中的每个商品,并将每个商品的 inputVisible属性设置为 val。这样,所有商品的选中状态就会被更新为与复选框的选中状态一致。

checkAll:{get:function(){return this.goods.every(item=>item.inputVisible === true)},set:function(val){this.goods.forEach(item=>{item.inputVisible = val;})}}

在good.vue中将复选框的 v-model 绑定到 good.inputVisible 属性,用于控制复选框的选中状态。

v-model="good.inputVisible"

实现价格合计

在上述引入good组件的基础下

定义一个totalPrice计算属性并用插值表达式替代0

{{totalPrice}}

totalPrice计算属性语法:

声明一个局部变量 total,初始值为 0,用于累加商品的总价。

this.goods.forEach(item=>{...}):使用 forEach 方法遍goods 数组中的每个商品。

if(item.inputVisible ===true){...}:检查当前商品的inputVisibl属性是否为true,即该商品是否被选中。

total += item.goods_price * item.inputValue;:如果商品被选中,将其价格(goods_pric)乘以数量(inputValu),并累加到 total变量中。

return total;:方法结束时返回 total 变量的值,即购物车中已选中商品的总价。

totalPrice(){let total = 0;this.goods.forEach(item=>{if(item.inputVisible ===true){total += item.goods_price * item.inputValue;}})return total;},

实现结算后数量的变化

在上述引入good组件的基础下

定义一个totalnum计算属性并用插值表达式替代0

{{ totalnum }}

totalnum计算属性语法:定义了一个名为 totalnum 的计算属性,它用于计算购物车中已选中商品的数量。这个方法通过遍历 goods数组,检查每个商品的 inputVisible属性是否为 true,如果是,则将计数器 num 加一。最终,方法返回计数器的值,即购物车中已选中商品的数量

 totalnum(){let num = 0;this.goods.forEach(item=>{if(item.inputVisible ===true){num++}})return num;}

到这里,商城的Vue案例就结束了,大家是否成功的跟上并且完成了呢,是否根据这个小案例更深入学习到了Vue的知识了呢?路漫漫其修远兮,吾将上下而求索,一起加油吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/466488.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【测试】【Debug】vscode中同一个测试用例出现重复

这种是正常的情况 当下面又出现一个 类似python_test->文件夹名->test_good ->test_pad 同一个测试用例出现两次&#xff0c;名称都相同&#xff0c;显然是重复了。那么如何解决&#xff1f; 这种情况是因为在终端利用“pip install pytest”安装 之后&#xff0c;又…

基于C++的决策树C4.5机器学习算法(不调包)

目前玩机器学习的小伙伴&#xff0c;上来就是使用现有的sklearn机器学习包&#xff0c;写两行代码&#xff0c;调调参数就能跑起来&#xff0c;看似方便&#xff0c;实则有时不利于个人能力发展&#xff0c;要知道现在公司需要的算法工程师&#xff0c;不仅仅只是会调参&#x…

Mac解决 zsh: command not found: ll

Mac解决 zsh: command not found: ll 文章目录 Mac解决 zsh: command not found: ll解决方法 解决方法 1.打开bash_profile 配置文件vim ~/.bash_profile2.在文件中添加配置&#xff1a;alias llls -alF键盘按下 I 键进入编辑模式3. alias llls -alF添加完配置后&#xff0c;按…

VBA10-处理Excel的动态数据区域

end获取数据边界 1、基本语法 1-1、示例&#xff1a; 2、配合row和column使用 2-1、示例1 2-2、示例2 此时&#xff0c;不管这个有数值的区域&#xff0c;怎么增加边界&#xff0c;对应的统计数据也会跟着变的&#xff01;

无人车之路径规划篇

无人车的路径规划是指在一定的环境模型基础上&#xff0c;给定无人车起始点和目标点后&#xff0c;按照性能指标规划出一条无碰撞、能安全到达目标点的有效路径。 一、路径规划的重要性 路径规划对于无人车的安全、高效运行至关重要。它不仅能够提高交通效率&#xff0c;减少交…

【前端基础】CSS基础

目标&#xff1a;掌握 CSS 属性基本写法&#xff0c;能够使用文字相关属性美化文章页。 01-CSS初体验 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#…

一种高度集成的数字化管理平台:城市管理综合执法系统(源码)

什么是城市管理综合执法系统&#xff1f; 城市管理综合执法系统是一种高度集成的数字化管理平台&#xff0c;它旨在通过整合信息技术资源&#xff0c;实现对城市环境、秩序、设施等多方面的综合管理和高效执法。 城市管理综合执法系统通常包含以下几个核心要素和功能&#xff…

【Python】强大的正则表达式工具:re模块详解与应用

强大的正则表达式工具&#xff1a;re模块详解与应用 在编程和数据处理中&#xff0c;字符串的处理是不可避免的一项任务。无论是从文本中提取信息、验证数据格式&#xff0c;还是进行复杂的替换操作&#xff0c;正则表达式&#xff08;Regular Expression&#xff0c;简称Rege…

计算机毕业设计Python+图神经网络手机推荐系统 手机价格预测 手机可视化 手机数据分析 手机爬虫 Django Flask Spark 知识图谱

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

03.DDD六边形架构

学习视频来源&#xff1a;DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 什么是依赖DDD四层架构六边形架构代码实现 想要详细了解六边形架构&#xff0c;可以看我之前的一篇文章。是对六边形架构原文的翻…

前端开发实现自定义勾选/自定义样式,可复选,可取消勾选

基于后端返回数组实现多选、复选 以下代码基于vue2&#xff0c;如果有需要React/Vue3或者其他框架代码的&#xff0c;可以通过国内直连GPT4o进行代码转换&#xff0c;转换正确率99% 前端代码如下(直接拷贝到你的vue代码即可)&#xff1a; <!-- CustomCheckboxList.vue --&g…

新型智慧城市顶层设计方案(118页word)

文档介绍&#xff1a; 新型智慧城市顶层设计方案是一种全局性、前瞻性的规划&#xff0c;旨在通过整合城市各类资源&#xff0c;运用新一代信息技术&#xff0c;推动城市治理、民生服务、产业发展等领域的全面升级&#xff0c;以实现城市的可持续发展和居民生活质量的提升。该…

nginx-proxy-manager实现反向代理+自动化证书(实战)

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 cnginx-proxy-manager实现反向代理自动化证书 nginx-proxy-manager是什么搭建nginx-proxy-manage…

定时器入门:Air780E定时器基础与进阶

今天我们学习的是Air780E定时器基础与进阶&#xff0c;让大家更深入的了解定时器。 一、定时器(timer)的概述 在Air780E模组搭载的LuatOS系统中&#xff0c;定时器&#xff08;timer&#xff09;是一项基础且关键的服务。它允许开发者在特定的时间点或周期性地执行代码段&…

C语言复习第7章 自定义类型(结构体+位段+枚举+联合体)

目录 一、结构体1.1 内置类型和自定义类型1.2 结构体的概念1.3 结构体基本的声明1.4 区分两种创建结构体变量的方式1.5 结构体变量的定义和初始化1.6 区分一下typdef和变量列表1.7 匿名结构体类型1.8 访问结构体成员1.9 修改字符数组成员变量的时候 要用strcpy1.10 结构体的传参…

Twitter(X)2024最新注册教程

Twitter 现名为X&#xff0c;因为图标是一只小鸟的形象&#xff0c;大家也叫它小蓝鸟&#xff08;埃隆马斯克于 2023 年对该平台进行了品牌重塑&#xff09;&#xff0c;目前仍然是全球最受欢迎的社交媒体和微博平台之一&#xff0c;全球活跃用户量大概在4.5亿。尤其是欧美国家…

[单例模式]

[设计模式] 设计模式是软件工程中的一种常见做法, 它可以理解为"模板", 是针对一些常见的特定场景, 给出的一些比较好的固定的解决方案. 不同语言适用的设计模式是不一样的. 这里我们接下来要谈到的是java中典型的设计模式. 而且由于设计模式比较适合有一定编程经…

[mysql]DDL,DML综合案例,

综合案例 题目如下 目录 综合案例 ​编辑 ​编辑 # 1、创#1建数据库test01_library # 2、创建表 books&#xff0c;表结构如下&#xff1a; # 3、向books表中插入记录库存 # 4、将小说类型(novel)的书的价格都增加5。 # 5、将名称为EmmaT的书的价格改为40&#xff0c;并将…

day-81 打家劫舍 II

思路 与LCR 089. 打家劫舍相比&#xff0c;本题所有房屋围成了一圈&#xff0c;那么第一间房子和最后一间房子不能同时打劫&#xff0c;那么就可以分为两种情况&#xff1a;1.选第一间房打劫&#xff1b;2.选最后一间房打劫 解题过程 然后依次计算出以上两种情况的最大金额&am…

秃姐学AI系列之:GRU——门控循环单元 | LSTM——长短期记忆网络

RNN存在的问题 因为RNN模型的BPTT反向传导的链式求导&#xff0c;导致需要反复乘以一个也就是说会出现指数级别的问题&#xff1a; 梯度爆炸&#xff1a;如果的话&#xff0c;那么连乘的结果可能会快速增长&#xff0c;导致梯度爆炸梯度消失&#xff1a;如果的话&#xff0c;…