场景:

项目中使用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监听后再重新赋值绑定则不会报错。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐