当使用vuex存储数据时,常常有这样的需求:输入框显示并动态修改state中的数据。
我们第一个反应就是使用v-model直接绑定state中的数据,虽然确实可以显示和修改,但是控制台会报错,所以不能采取这种方式。
案例如下:
在使用vant组件库实现底部标签栏时,此标签栏在各个页面中都需要显示,故放在App.vue中。
<template>
<div id="app">
<router-view></router-view>
<van-tabbar class="tab" v-model="activeTab" @change="changeActiveTab">
<van-tabbar-item icon="home-o" to="/home">首页</van-tabbar-item>
<van-tabbar-item icon="apps-o" to="/cate">分类</van-tabbar-item>
<van-tabbar-item icon="cart-o" to="/cart" :badge="badgeCount">购物车</van-tabbar-item>
<van-tabbar-item icon="user-circle-o" to="my">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState('m_user', ['activeTab']),
// ...
},
methods: {
...mapMutations('m_user', ['updateActiveTab']),
changeActiveTab (index) {
this.updateActiveTab(index)
}
}
}
</script>
activeTab:绑定选中标签的索引值,通过修改 v-model 即可切换选中的标签。
由于多个页面都可以切换标签,把activeTab作为公共变量存储到vuex中。updateActiveTab公共方法用于修改activeTab的值。
上面的代码可以切换标签,但是会报错:Computed property "activeTab" was assigned to but it has no setter.
解决办法:通过计算属性getter获取vuex中的值,通过setter来修改值。
这里新增一个计算属性active作为绑定值,利用getter和setter 来调用和修改公共变量activeTab。
<template>
<div id="app">
<router-view></router-view>
<van-tabbar class="tab" v-model="active">
<van-tabbar-item icon="home-o" to="/home">首页</van-tabbar-item>
<van-tabbar-item icon="apps-o" to="/cate">分类</van-tabbar-item>
<van-tabbar-item icon="cart-o" to="/cart" :badge="badgeCount">购物车</van-tabbar-item>
<van-tabbar-item icon="user-circle-o" to="my">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState('m_user', ['activeTab']),
// ...
active: {
get () { return this.activeTab },
set (val) { this.changeActiveTab(val) }
}
},
methods: {
...mapMutations('m_user', ['updateActiveTab']),
changeActiveTab (index) {
this.updateActiveTab(index)
}
}
}
</script>