前端:Vue学习 - 购物车项目

坚持不懈的大白 2024-08-01 15:03:02 阅读 95

前端:Vue学习 - 购物车项目

1. json-server,生成后端接口2. 购物车项目 - 实现效果3. 参考代码 - Vuex

1. json-server,生成后端接口

全局安装json-server,json-server官网为:json-server

<code>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,代码如下:

<code>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>

<div id="app">code>

<ul>

<li v-for="item in books2" :key="item.id" class="sp">code>

<Cart :item="item"></Cart>code>

</li>

</ul>

<TotalPrice class="total-price-position"></TotalPrice>code>

</div>

</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>code>

#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>

<div class="sp-item">code>

<!-- <img :src="require('@/static/'+item.bookName+'.png')" alt=""> -->code>

<img src="@/static/水浒传.png" alt="">code>

<p class="sp-name">{ {item.bookName}}</p>code>

<p class="sp-price">¥{ {item.price}}</p>code>

<div class="sp-btn">code>

<button class="sp-l-btn" @click="btnClick(-1)">-</button>code>

<p class="sp-count">{ {item.count}}</p>code>

<button class="sp-r-btn" @click="btnClick(1)">+</button>code>

</div>

</div>

</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>code>

.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>

<div class="total-price-div">code>

<span class="z-span"></span>code>

共<span>{ {totalCount}}</span>本,总共<span class="total-price">{ {totalPrice}}</span>元code>

<button>结算</button>

</div>

</template>

<script>

import { mapGetters} from 'vuex';

export default {

name:"TotalPrice",

computed:{

...mapGetters('books',['totalCount','totalPrice'])

}

}

</script>

<style scoped lang="less">code>

.total-price-div{

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。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。