目前,我们学习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的知识了呢?路漫漫其修远兮,吾将上下而求索,一起加油吧!