programing

동적으로 생성된 구성 요소의 vuex 저장소 분리

prostudy 2022. 5. 15. 23:42
반응형

동적으로 생성된 구성 요소의 vuex 저장소 분리

이 질문이 나를 잠시 꼼짝 못하게 했다.불행히도, 나는 여기서 답을 찾지 못했다.그래서 조사를 좀 하고 여기저기 물어본 결과 이 문제에 대한 해결책을 찾은 것 같다.

만약 여러분이 이미 답을 알고 있는 질문이 있다면, 그리고 다른 사람들(자신을 포함한)이 나중에 찾을 수 있도록 공공장소에서 그 지식을 문서화하기를 원할 것이다.

물론, 내 답변이 이상적인 답변은 아닐 수도 있고, 게다가 그것이 내가 그것을 향상시키기 위해 게시하는 핵심 요점이 아니라는 것도 알고 있다.

참고, 나는 예를 들어 액션을 사용하지 않는다.생각은 똑같다.

우선 그 문제를 다음과 같이 서술해 봅시다.

상상해보자App.vue로컬 구성 요소를 동적으로 생성하며Hello.

<template>
  <div id="app">
    <div>
      <hello v-for="i in jobs" :key="i" :id="i"></hello>
      <button @click="addJob">New</button>
    </div>
  </div>
</template>   

<script>
import Hello from './components/Hello'

export default {
  components: {
    Hello
  }...

store.js

export const store = new Vuex.Store({
  state: {
    jobs: []
  }
})

우리는 사용하고 있다.v-for배열을 반복하여 구성요소를 생성하도록 지시jobs. 우리의store현재로는 단지 로 구성되어 있다.state빈칸으로단추New다음 두 가지 작업을 수행하십시오.

1) 새 구성 요소 생성Hello, 다시 말하면 요소 추가jobs(숫자로 표시)로 할당될 경우key그리고id<hello>, 그리고 로 로컬 구성요소에 전달됨props.

2) 로컬 스토어 생성 - 모듈 생성 - 새로 생성된 구성 요소에 대한 데이터 범위 유지

Hello.vue

<template>
  <div>
    <input type="number" :value="count">
    <button @click="updateCountPlus">+1</button>
  </div>
</template>

export default {
  props: ['id']
}

단순 구성 요소 - 버튼이 1을 추가하는 입력

우리의 목표는 다음과 같은 것을 디자인하는 것이다.

의 첫 번째 작동에 대해NEW버튼 - 구성 요소 생성 - 추가mutation우리들의store.js

 mutations: {
    addJob (state) {
      state.jobs.push(state.jobs.length + 1)
...
}

둘째, 로컬 모듈 생성.여기서 우리는reusableModule모듈의 여러 인스턴스를 생성하십시오.그 모듈은 편의상 별도 파일로 보관한다.또한 모듈 상태를 선언하기 위한 기능의 사용을 기록해 두십시오.

const state = () => {
  return {
    count: 0
  }
}

const getters = {
  count: (state) => state.count
}

const mutations = {
  updateCountPlus (state) {
    state.count++
  }
}

export default {
  state,
  getters,
  mutations
}

사용 방법reusableModule우리는 그것을 수입하고 동적 모듈 등록을 적용한다.

store.js

import module from './reusableModule'

const {state: stateModule, getters, mutations} = module

export const store = new Vuex.Store({
  state: {
    jobs: []
  },
  mutations: {
    addJob (state) {
      state.jobs.push(state.jobs.length + 1)
      store.registerModule(`module${state.jobs.length}`, {
        state: stateModule,
        getters,
        mutations,
        namespaced: true // making our module reusable
      })
    }
  }
})

그리고 나서, 우리는 링크할 것이다.Hello.vue창고에 보관하여우리는 필요할지도 모른다.state,getters,mutations,actions로부터vuex스토리지에 액세스하려면 다음을 생성해야 함getters.도 마찬가지 입니다.mutations.

Home.vue

<script>

export default {
  props: ['id'],
  computed: {
     count () {
        return this.$store.getters[`module${this.id}/count`]
     }
  },
  methods: {
    updateCountPlus () {
        this.$store.commit(`module${this.id}/updateCountPlus`)
     } 
  }
}
</script>

우리가 많은 것을 가지고 있다고 상상해보라.getters,mutations그리고actions왜 사용하지 않는가?{mapGetters}또는{mapMutations}? 우리가 몇 개의 모듈을 가지고 있고 우리는 모듈로 가는 길을 알고 있을 때, 우리는 그것을 할 수 있다.불행히도 우리는 모듈 이름에 접근할 수 없다.

코드는 컴포넌트 생성 시점이 아니라 컴포넌트 모듈이 실행될 때(앱이 부팅될 때) 실행된다.그래서 이 도우미들은 모듈 이름을 미리 알고 있을 때만 사용할 수 있다.

여기는 도움이 거의 없다.우리는 분리할 수 있다.getters그리고mutations그리고 그것들을 물건으로 가져와 청결하게 유지한다.

<script>
import computed from '../store/moduleGetters'
import methods from '../store/moduleMutations'

export default {
  props: ['id'],
  computed,
  methods
}
</script>

로 돌아가기App구성 요소우리는 우리의 의무를 다해야 한다.mutation그리고 또 몇 가지를 만들어 봅시다.getter을 위해App모듈에 있는 데이터에 어떻게 액세스할 수 있는지 보여주기 위해서입니다.

store.js

export const store = new Vuex.Store({
  state: {
    jobs: []
  },
  getters: {
    jobs: state => state.jobs,
    sumAll (state, getters) {
      let s = 0
      for (let i = 1; i <= state.jobs.length; i++) {
        s += getters[`module${i}/count`]
      }
      return s
    }
  } 
...

종료 코드 입력App구성 요소

<script>
import Hello from './components/Hello'
import {mapMutations, mapGetters} from 'vuex'

    export default {
      components: {
        Hello
      },
      computed: {
        ...mapGetters([
          'jobs',
          'sumAll'
        ])
      },
      methods: {
        ...mapMutations([
          'addJob'
        ])
      }
    }
    </script>

안녕 그리고 너의 질문과 해결책을 게시해줘서 고마워.

나는 며칠 전부터 Vuex를 배우기 시작했고 비슷한 문제를 만났다.나는 너의 솔루션을 확인했고 새로운 모듈을 등록하지 않아도 되는 내 솔루션을 생각해냈어.나는 그것이 꽤 과잉 살상이고 솔직히 나는 왜 당신이 그것을 하는지 이해할 수 없다.내가 그 문제를 오해했을 가능성은 항상 있다.

나는 명확성과 증명 목적을 위해 몇 가지 차이점을 가진 당신의 마크업 사본을 만들었다.

내가 가지고 있는 그대로:

  1. JobList.vue - 기본 사용자 정의 구성 요소
  2. Job.vue - 작업 목록 하위 사용자 정의 구성 요소
  3. job.js - vuex 저장소 모듈 파일

JobList.vue(JobList.vue는 작업 목록 항목 마무리를 담당함)

<template>
    <div>
        <job v-for="(job, index) in jobs" :data="job" :key="job.id"></job>

        <h3>Create New Job</h3>
        <form @submit.prevent="addJob">
            <input type="text" v-model="newJobName" required>
            <button type="submit">Add Job</button>
        </form>
    </div>
</template>

<script>
    import store from '../store/index'
    import job from './job';

    export default {
        components: { job },
        data() {
            return {
                newJobName: ''
            };
        },
        computed: {
            jobs() {
                return store.state.jobs.jobs;
            }
        },
        methods: {
            addJob() {
                store.dispatch('newJob', this.newJobName);
            }
        }
    }
</script>

<template>
    <div>
        <h5>Id: {{ data.id }}</h5>
        <h4>{{ data.name }}</h4>
        <p>{{ data.active}}</p>
        <button type="button" @click="toggleJobState">Toggle</button>
        <hr>
    </div>
</template>

<script>

    import store from '../store/index'

    export default {
        props: ['data'],
        methods: {
            toggleJobState() {
                store.dispatch('toggleJobState', this.data.id);
            }
        }
    }

</script>

마지막으로 jobs.js Vuex 모듈 파일:

export default {
    state: {
        jobs: [
            {
                id: 1,
                name: 'light',
                active: false
            },
            {
                id: 2,
                name: 'medium',
                active: false
            },
            {
                id: 3,
                name: 'heavy',
                active: false
            }
        ]
    },

    actions: { //methods
        newJob(context, jobName) {
            context.state.jobs.push({
                id: context.getters.newJobId,
                name: jobName,
                active: false
            });
        },
        toggleJobState(context, id) {
            context.state.jobs.forEach((job) => {
                if(job.id === id) { job.active = !job.active; }
            })
        }
    },

    getters: { //computed properties
        newJobId(state) { return state.jobs.length + 1; }
    }
}

상점에 새로운 작업을 추가할 수 있으며 "활성" 속성이 시사하듯이, 새로운 사용자 지정 vuex 모듈 없이도 모든 개별 작업을 제어할 수 있다.

참조URL: https://stackoverflow.com/questions/44345704/separating-vuex-stores-for-dynamically-created-components

반응형