programing

계산된 속성에서 반환된 어레이의 개체 편집 중

lastcode 2023. 6. 21. 22:37
반응형

계산된 속성에서 반환된 어레이의 개체 편집 중

Vuex 스토어에서는 Firebase/Firestore API 호출을 통해 다음과 같은 일련의 룸을 받습니다.[{label:'Kitchen', decription:'...'}, ...]그리고 Vuex getter 기능을 통해 앱에서 사용할 수 있도록 합니다.당연히 내 구성요소에서 이 배열을 계산된 속성으로 받습니다.하지만 CRUD 구성 요소에서 저는 실제로 이 "원래" 배열을 다른 계산된 속성을 통해 라우팅하여 배열의 각 개체에 여러 임시 속성을 연결할 수 있습니다.workable: () => this.rooms.map(val => { return ...val, editing: false, loading: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>

제가 만들어 봤습니다.workable(null이 아닌) 데이터 속성을 사용한 다음 메서드를 사용합니다.setWorkable()) 각 배열에 추가 속성을 추가한 다음 호출합니다.setWorkable()mounted()그것은 성공적으로 분리됩니다.workable부터rooms하지만 이 접근법의 문제는 제가 계속해서 전화를 해야 한다는 것입니다.setWorkable()소스로 계속 전파하고 싶은 배열의 개체 중 하나를 변경할 때.

이것이 제가 하려는 일을 할 수 있는 유일한 방법일 수도 있다는 것을 알고 있지만, 매번 변경할 때마다 수동으로 렌더링하지 않도록 계산된 속성만 사용하는 더 나은 방법이 있기를 바랍니다.

제가 다른 정보를 포함해야 한다면 저에게 알려주세요.

액션을 추가하여 전체 논리를 스토어에 배치하는 접근 방식을 변경할 것을 제안합니다.edit 버튼을 클릭하여 룸을 할 때 .index상태를 하는 중: " " " "

// 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,
};

룸 크루드.가치관

<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>

언급URL : https://stackoverflow.com/questions/57741241/editing-object-in-array-returned-from-computed-property

반응형