json-server使用
在目录下新建db文件夹=>里面新建index.json
index.json
{
"cart": [
{
"id": 100001,
"name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维",
"price": 128,
"count": 6,
"thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
},
{
"id": 100002,
"name": "网易味央黑猪猪肘330g*1袋",
"price": 39,
"count": 15,
"thumb": "https://yanxuan-item.nosdn.127.net/d0a56474a8443cf6abd5afc539aa2476.jpg"
},
{
"id": 100003,
"name": "KENROLL男女简洁多彩一片式室外拖",
"price": 128,
"count": 3,
"thumb": "https://yanxuan-item.nosdn.127.net/eb1556fcc59e2fd98d9b0bc201dd4409.jpg"
},
{
"id": 100004,
"name": "云音乐定制IN系列intar民谣木吉他",
"price": 589,
"count": 1,
"thumb": "https://yanxuan-item.nosdn.127.net/4d825431a3587edb63cb165166f8fc76.jpg"
}
],
"friends": [
{
"id": 1,
"name": "zs",
"age": 18
},
{
"id": 2,
"name": "ls",
"age": 19
},
{
"id": 3,
"name": "ww",
"age": 20
}
],
"arr": [
{
"id": 1,
"name": "zhansan"
}
]
}
在 cmd 终端定位到 db 文件夹目录下
json-server.cmd --watch index.json
开启服务模拟服务端接口数据
store/index.js
// 导入vue
import Vue from 'vue'
// 导入vuex
import Vuex from 'vuex'
import cart from './module/cart'
Vue.use(Vuex)
// 创建仓库store
const store = new Vuex.Store({
strict: true,
modules: {
cart
}
})
// 导出仓库
export default store
store/modules/cart.js
封装cart
模块
import request from '@/utils/request'
export default {
namespaced: true,
state: {
// 购物车数据[{},{}]
list: []
},
getters: {
total (state) {
return state.list.reduce((sum, item) => sum + item.count, 0)
},
totalPrice (state) {
return state.list.reduce((sum, item) => sum + item.count * item.price, 0)
}
},
mutations: {
updateList (state, newList) {
state.list = newList
},
// 修改数量
updateCount (state, payload) {
// 根据id找到要更新的数据
const goods = state.list.find(item => item.id === payload.id)
// 更新数量
goods.count = payload.count
}
},
actions: {
async getList (context) {
const res = await request.get('/cart')
console.log(res)
context.commit('updateList', res)
},
// 修改数量
/*
请求方式:patch
请求地址:http://localhost:3000/cart/:id
请求参数
{
count:值,
price:值
}
*/
async updateCountAsync (ctx, payload) {
// 修改后端的数据
await request.patch('/cart/' + payload.id, {
count: payload.count
})
// 更新vuex的数据
ctx.commit('updateCount', payload)
}
}
}
App.vue
注册并使用子组件,并渲染商品item
<template>
<div id="app">
<CartHeader></CartHeader>
<CartItem v-for="item in list" :key="item.id" :item="item"></CartItem>
<CartFooter></CartFooter>
</div>
</template>
<script>
import CartHeader from '@/components/cart-header.vue'
import CartItem from '@/components/cart-item.vue'
import CartFooter from '@/components/cart-footer.vue'
import { mapState } from 'vuex'
export default {
components: {
CartHeader, CartItem, CartFooter
},
created () {
this.$store.dispatch('cart/getList')
},
computed: {
...mapState('cart', ['list'])
}
}
</script>
<style lang="less" scoped>
#app{
padding: 50px 0;
}
</style>
cart-header.vue
封装头部
<template>
<div class="header-container">购物车案例</div>
</template>
<script>
export default {
name: 'CartHeader'
}
</script>
<style lang="less" scoped>
.header-container {
height: 50px;
line-height: 50px;
font-size: 16px;
background-color: #42b983;
text-align: center;
color: white;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
}
</style>
cart-item.vue
封装商品item
<template>
<div class="cart-item">
<img :src="item.thumb" alt="" height="100px">
<div class="wrapper">
<p class="tit">{{ item.name }}</p>
<div class="box">
<button @click="changeCount(-1)">-1</button>
<div class="count">{{ item.count }}</div>
<button @click="changeCount(1)">+1</button>
</div>
<div class="price">¥{{ item.price }}</div>
</div>
</div>
</template>
<script>
export default {
props: {
item: {
type: Object
}
},
methods: {
changeCount(step) {
console.log(this.item)
const id = this.item.id
const newCount = this.item.count + step
this.$store.dispatch('cart/updateCountAsync', { id, count: newCount })
}
}
}
</script>
<style scoped >
.cart-item {
height: 140px;
display: flex;
align-items: center;
}
.wrapper {
margin-left: 10px;
}
.box {
display: flex;
width: 80px;
justify-content: space-between;
align-items: center;
}
.box button {
width: 30px;
height: 20px;
border-radius: 3px;
border: 0;
background-color: orange;
}
.tit,
.box {
margin-bottom: 5px;
}
</style>
cart-footer.vue
封装底部
<template>
<div>
<p>商品总数:{{ totalCount }} | 总价:{{ totalSum }}</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('cart', ['totalCount', 'totalSum'])
}
}
</script>
<style scoped></style>