场景:
项目中使用vuex进行状态管理,控制对话框的弹出与隐藏,在实际应用过程中,出现Computed property "xxx" was assigned to but it has no setter.错误警告,经过几番测试发现原因在于:直接将mapState中的数据绑定到了组件上, 而没有经过watch监听属性的变化重新赋值给data中的一个变量再绑定。代码如下:
Vuex store>modules>vuexA.js:
const state = () => ({
show: false, // 控制显示与隐藏dialog
})
const getters = {
}
const mutations = {
SHOWDIALOG(state, value) {
state.show = value;
},
}
const actions = {
showDialog(context, value) {
context.commit('SHOWDIALOG', value);
},
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
使用到Vuex中action的子组件Table.vue:
<template>
<div class="my-table">
<el-table :data="data" @cell-click="cellHandleclick">
...
</el-table>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'MyTable',
data() {
return {
}
},
methods: {
...mapActions('vuexA', ['showDialog']),
cellHandleclick(row, column, cell, event) {
if(column.label === 'XX') {
this.showDialog(true);
}
});
},
}
</script>
<style scoped>
</style>
使用到Vuex中state的子组件Table.vue的父组件Father,Father中List组件为包含dialog的子组件,Father中使用watch监听vuex中show的变化:
<template>
<div>
<!-- Table组件-->
<Table />
<!-- List组件 -->
<List v-show="showList"/>
</div>
</template>
<script>
const Table = resolve => (require(['@/views/pages/Table'], resolve));
const List = resolve => (require(['@/views/pages/List'], resolve));
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'Father',
components: {
Table,
List
},
data() {
return {
showList: this.show,
}
},
computed: {
...mapState('vuexA', ['show']),
},
watch: {
show(val) {
this.showList= val;
}
},
}
</script>
<style scoped>
</style>
使用到Vuex中state的子组件List.vue,:visible.sync绑定的showList同样来源于watch监听的vuex中的state的show值,在点击关闭按钮时触发close事件,close事件触发vuex中的showDialog:
<template>
<!-- List组件 -->
<div class="listDialog">
<el-dialog :visible.sync="showList" width="90%" @close="close">
...
</el-dialog>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'List',
data() {
return {
showList: this.show,
}
},
computed: {
...mapState('vuexA', ['show']),
},
watch: {
show(val) {
console.log(val);
this.showPoorUserList = val;
}
},
methods:{
...mapActions('vuexA', ['showDialog']),
close() {
this.showDialog(false);
},
},
}
</script>
<style scoped>
</style>
总结:组件中的v-show和:visible.sync直接绑定vuexA中的show会在点击close按钮的时候报出警告,按照上面代码中的方式使用watch监听后再重新赋值绑定则不会报错。