最近做一个商城的项目,商品的详情页和购物车列表都需要用到上面数量增减的功能,其实这个是一个很普通的功能,但是购物车的列表是放到vuex里面的,这里记录使用的差别:
首先封装number-box组件:
<template>
<div class="numBox">
<button class="btn" @click="jian">-1</button>
<input type="text" @change="handleChange" style="width:50px;" :value="value" />
<button class="btn" @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'demoPage',
props: {
value: {
type: Number,
default: 1
}
},
data () {
return {
}
},
methods: {
add () {
this.$emit('input', this.value + 1)
},
jian () {
if (this.value <= 1) return
this.$emit('input', this.value - 1)
},
handleChange (e) {
const num = +e.target.value
if (isNaN(num) || num < 1) {
e.target.value = this.value
} else {
this.$emit('input', num)
}
}
}
}
</script>
在列表页去引用,并使用v-vmode传递数据:
<ul>
<li v-for="(item,index) in list" :key="index">
<div>{{item.name}}</div>
<NumberBox v-model="item.num"></NumberBox>
</li>
</ul>
data () {
return {
num: 10,
list: [
{ id: 1, name: '商品1', num: 1 },
{ id: 2, name: '商品2', num: 2 },
{ id: 3, name: '商品3', num: 3 }
]
}
},
如果数据是直接在data下面,直接循环绑定num,触发增减按钮,list的数据能整成增减。但是这里有个特殊的情况,如果list的数据是在vuex里面的,利用上面的绑定,是不能实现list里面num的增减的,需要更改绑定的方式:
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">
<div>{{item.name}}</div>
<NumberBox :value="item.num" @input="changNum(item.id,$event)"></NumberBox>
</li>
</ul>
</div>
</template>
<script>
import NumberBox from '../components/NumberBox.vue'
import { mapState } from 'vuex'
export default {
name: 'demoPage',
components: {
NumberBox
},
data () {
return {
num: 10
}
},
methods: {
changNum (id, val) {
this.$store.commit('demo/changeNum', { id, val })
}
},
computed: {
...mapState('demo', ['list'])
}
}
</script>
vuex部分的代码:
export default {
namespaced: true,
state () {
return {
list: [
{ id: 1, name: '商品1', num: 1 },
{ id: 2, name: '商品2', num: 2 },
{ id: 3, name: '商品3', num: 3 }
]
}
},
mutations: {
changeNum (state, obj) {
const good = state.list.find(item => item.id === obj.id)
good.num = obj.val
}
}
}
这样也能实现绑定的效果: