前端Vue学习之购物车项目实践记录实用指南
平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“前端Vue学习之购物车项目实践记录”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
1. json-server,生成后端接口
在这个场景下,全局安装json-server,json-server官网为:json-server
npm install json-server -g
// 全局安装
在这个场景下,安装之后启动可能存在json-server与node版本不兼容导致的问题,为此,建议指定一个json-sever版本。
在这个场景下,需准备一个json文件,然后在json文件中写入json数据,借助json-server,就能够完成增删改查功能。
{
"books":[
{"id":1,"bookName":"三国演义","price":23},
{"id":2,"bookName":"西游记","price":43},
{"id":3,"bookName":"水浒传","price":33}
]
}
在这个json文件的目录下执行下述命令,
2. 购物车项目 - 实现效果
从实现思路看,就是更改对应书本的购买数量,下面显示共计多少本书,以及需多少钱实时更新。界面上构建了两个组件,分别为单个书本组件和下面总计组件。状态控制采用vuex.store来进行管理。
3. 参考代码 - Vuex
在这个场景下,采用模块化对这个界面需用到store进行封装,命名为books.js,代码如下所示:
import axios from 'axios'
const state = {
books2:[]
};
const mutations = {
updateBooks(state,newBooks){
state.books2 = newBooks;
},
updateCount(state,obj){
const book = state.books2.find(item => item.id == obj.id);
book.count = obj.newCount;
}
};
const actions = {
async getBooks(context){
const res = await axios.get('http://localhost:3000/books');
context.commit('updateBooks',res.data);
},
async updateBooks(context,obj){
await axios.patch(`http://localhost:3000/books/${obj.id}`,{
count:obj.newCount
})
// 后台修改数据
context.commit('updateCount',{
id:obj.id,
newCount:obj.newCount
});
// 前端页面显示
}
};
const getters = {
totalCount(state) {
return state.books2.reduce((sum, item) => sum + item.count,0);
},
totalPrice(state) {
return state.books2.reduce((sum, item) => sum + item.count * item.price,0);
}
};
export default {
namespaced:true,
state,
mutations,
actions,
getters
}
在store目录下index.js文件引入这个模块即可。
import books from './modules/books'
export default new Vuex.Store({
...,
modules:{
books
}
})
App.vue代码如下所示:
<template>
<p id="app">
<ul>
<li v-for="item in books2" :key="item.id" class="sp">
<Cart :item="item"></Cart>
</li>
</ul>
<TotalPrice class="total-price-position"></TotalPrice>
</p>
</template>
<script>
import {mapState} from 'vuex'
import Cart from './components/Cart.vue';
import TotalPrice from './components/TotalPrice.vue';
export default {
name: 'App',
components: {
Cart,TotalPrice
},
async created(){
this.$store.dispatch('books/getBooks');
},
computed:{
...mapState('books',['books2'])
}
}
</script>
<style lang="less" scoped>
#app{
position: relative;
width: 100%;
height: 700px;
.total-price-position{
position: absolute;
bottom: 0;
left: 0;
}
}
.sp{
height: 100px;
margin-top: 5px;
border-bottom: 1px solid yellow;
}
</style>
当个书本组件代码如下所示:Cart.vue
<template>
<p class="sp-item">
<!-- <img :src="require('@/static/'+item.bookName+'.png')" alt=""> -->
<img src="@/static/水浒传.png" alt="">
<p class="sp-name">{{item.bookName}}</p>
<p class="sp-price">¥{{item.price}}</p>
<p class="sp-btn">
<button class="sp-l-btn" @click="btnClick(-1)">-</button>
<p class="sp-count">{{item.count}}</p>
<button class="sp-r-btn" @click="btnClick(1)">+</button>
</p>
</p>
</template>
<script>
export default {
name:'Cart',
props:{
item:Object
},
methods:{
btnClick(step){
const newCount = this.item.count + step;
const id = this.item.id;
if(newCount < 1)
return
this.$store.dispatch('books/updateBooks',{
id,
newCount
})
}
}
}
</script>
<style lang="less" scoped>
.sp-item{
width: 100%;
height: 100%;
position: relative;
>*{
position: absolute;
}
img{
width: 100px;
top: 50%;
left: 0;
transform: translateY(-50%);
}
.sp-name{
top: 6px;
left: 104px;
font-size: 18px;
}
.sp-price{
bottom: 4px;
left: 104px;
color: red;
font-weight: 600;
}
.sp-btn{
bottom: 4px;
right: 2px;
>*{
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
}
}
}
</style>
总计组件代码如下所示:TotalPrice.vue
<template>
<p class="total-price-p">
<span class="z-span"></span>
共<span>{{totalCount}}</span>本,总共<span class="total-price">{{totalPrice}}</span>元
<button>结算</button>
</p>
</template>
<script>
import {mapGetters} from 'vuex';
export default {
name:"TotalPrice",
computed:{
...mapGetters('books',['totalCount','totalPrice'])
}
}
</script>
<style scoped lang="less">
.total-price-p{
height: 60px;
width: 100%;
line-height: 60px;
padding: 2px;
background-color: #e1dcdc;
}
.total-price{
color: red;
}
.z-span{
width: 146px;
display: inline-block;
}
button{
color: white;
background-color: green;
border-radius: 6px;
width: 60px;
height: 40px;
line-height: 40px;
}
</style>
项目中需用到axios、less、vuex。
总结
最后轻松收个尾:前端vue购物车逻辑这类实现要先理清数据流、状态变化和边界情况。把核心流程跑稳,再补齐异常处理和体验细节,后续维护会轻松很多。
游戏推荐
推荐专题
热门阅读
推荐下载
-
-
下载
- |
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- |
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏