Javascript 编辑从计算属性返回的数组中的对象

Javascript 编辑从计算属性返回的数组中的对象,javascript,vue.js,vuejs2,vuex,computed-properties,Javascript,Vue.js,Vuejs2,Vuex,Computed Properties,在我的Vuex应用商店中,我从Firebase/Firestore API调用中获得一个房间数组,如下所示:[{label:'Kitchen',description:'…},…],我通过Vuex getter函数将其提供给我的应用程序。自然地,在我的组件中,我将这个数组作为计算属性接收。但是在我的CRUD组件中,我实际上通过另一个计算属性路由这个“原始”数组,这样我就可以将几个临时属性附加到数组中的每个对象上-可行:()=>this.rooms.map(val=>{return…val,edi

在我的Vuex应用商店中,我从Firebase/Firestore API调用中获得一个房间数组,如下所示:
[{label:'Kitchen',description:'…},…]
,我通过Vuex getter函数将其提供给我的应用程序。自然地,在我的组件中,我将这个数组作为计算属性接收。但是在我的CRUD组件中,我实际上通过另一个计算属性路由这个“原始”数组,这样我就可以将几个临时属性附加到数组中的每个对象上-
可行:()=>this.rooms.map(val=>{return…val,editing:false,load:false,…})
。这些附加属性是CRUD组件唯一需要的,因此保留在原始阵列、数据源或应用程序中的任何其他位置都没有意义

我现在遇到的问题是,我显然需要能够更新CRUD数组中的这些临时属性,但我不能,因为(AFAIU)我的计算属性需要设置器来更新vuex存储中的原始数组,在我的情况下,必须更新数据源才能完成循环。(请注意,我并不完全理解我在这一段中所说的大部分内容,因此请随意更正任何错误的假设。)

所以我的问题是如何更新数组对象中的临时属性,而不将这些更改(和属性)一直传播回数据源?

下面是我的代码的简化版本,可以帮助您可视化当前的工作方式:

// store.js (Vuex)
const actions = {
  load: ({ commit, getters }) => {
    const query = firebase.roomCollection.where('user', '==', getters.user.id);
    const unsub = query.onSnapshot(snap => {

      const rooms = snap.docs.map(val => {
        return {
          id: val.id,
          ...val.data(),
          timestamp: val.data().timestamp.toDate(),
        };
      });

      commit('setRooms', rooms);
    });
  },
};

const mutations = {
  setRooms: (state, payload) => state.rooms = payload,
};

const state = {
  rooms: [],
};

const getters = {
  rooms: state => state.rooms,
};

// RoomCrud.vue
<template>
  <ul>
    <li v-for="room in workable" :key="`room-${i}`">
      {{ room.label }}
      <button @click="room.editing = !room.editing">Edit</button>
      <br />
      room: {{ room }} <!-- room.editing doesn't change when the Edit button gets clicked -->
    </li>
  </ul>
</template>

<script>
  import { mapGetters } from 'vuex';

  export default {
    computed: {
      ...mapGetters(['rooms']),
      workable() {
        return this.rooms.map(val => {
          return {
            ...val,
            editing: false,
            loading: false
          };
        });
      }
    }
  }
</script>
//store.js(Vuex)
常量动作={
加载:({commit,getters})=>{
const query=firebase.roomCollection.where('user','=',getters.user.id);
const unsub=query.onSnapshot(snap=>{
const rooms=snap.docs.map(val=>{
返回{
id:val.id,
…val.data(),
时间戳:val.data().timestamp.toDate(),
};
});
提交(“会议室”,会议室);
});
},
};
常数突变={
设置室:(状态,有效载荷)=>state.rooms=有效载荷,
};
常量状态={
房间:[],
};
常量getters={
房间:state=>state.rooms,
};
//RoomCrud.vue
  • {{room.label} 编辑
    房间:{{room}
从“vuex”导入{mapGetters}; 导出默认值{ 计算:{ …映射器(['rooms']), 可行的{ 返回此.rooms.map(val=>{ 返回{ …瓦尔, 编辑:错, 加载:错误 }; }); } } }
我尝试将
设置为可操作的
数据属性(最初为空),然后使用方法(
setWorkable()
)将附加属性添加到每个数组中,然后在
mounted()
上调用
setWorkable()
,从而成功地将
可操作的
房间中删除,但是这种方法的问题是,当我对数组中的一个对象进行更改时,我必须一直调用
setWorkable()
,我确实希望这些对象一直传播回源

我意识到这可能是我尝试做的唯一方法,但我希望有一种更好的方法,只使用计算属性,这样我就不必在每次更改时手动重新渲染


如果需要包含任何其他信息,请告诉我。

我建议更改将整个逻辑放入存储的方法,方法是添加操作
编辑
,通过传递房间
索引并更改行状态,单击该按钮时将触发该操作:

// store.js (Vuex)
const actions = {
 edit:({commit,state},index)=>{
     commit('editRoom', index);
  },
  load: ({ commit, getters }) => {
    const query = firebase.roomCollection.where('user', '==', getters.user.id);
    const unsub = query.onSnapshot(snap => {

      const rooms = snap.docs.map(val => {
        return {
          id: val.id,
          ...val.data(),
            editing: false,
            loading: false,
          timestamp: val.data().timestamp.toDate(),
        };
      });

      commit('setRooms', rooms);
    });
  },
};

const mutations = {
  setRooms: (state, payload) => state.rooms = payload,
   editRoom:(state,index)=> {
          state.rooms[index].editing=!state.rooms[index].editing;
           Vue.set(state.rooms,index,state.rooms);


       }
};

const state = {
  rooms: [],
};

const getters = {
  rooms: state => state.rooms,
};
RoomCrud.vue

<template>
  <ul>
    <li v-for="(room,i) in rooms" :key="`room-${i}`">
      {{ room.label }}
      <button @click="edit({index:i})">Edit</button>
      <br />
      room: {{ room }}
    </li>
  </ul>
</template>

<script>
  import { mapGetters,mapActions } from 'vuex';

  export default {
    methods:{
            ...mapActions(["edit"]),
        } ,
    computed: {
      ...mapGetters(['rooms']),

    }
  }
</script>

  • {{room.label} 编辑
    房间:{{room}
从“vuex”导入{MapGetter,mapActions}; 导出默认值{ 方法:{ …映射操作([“编辑”]), } , 计算:{ …映射器(['rooms']), } }