programing

Vuex 모듈에서 상속하는 방법

prostudy 2022. 8. 8. 15:18
반응형

Vuex 모듈에서 상속하는 방법

VueJ 및 Vuex를 사용하여 앱을 빌드하고 있는데 동일한 데이터 필드를 사용하는 모듈이 여러 개 있을 때 문제가 발생합니다.dat와 같은 API 설정에 관한 것입니다.

getUsers ({ state, commit }) {
    axios.get(urls.API_USER_URL).then( response => {
        let data = response.data;
        parseApi(state, data, 'user');

    }).catch( err => {
        console.log('getUser error: ', err);
    })
},

다른 모듈의 또 다른 기능은 다음과 같습니다.

getPosts ({ state, commit }) {
    axios.get(urls.API_POST_URL).then( response => {
        let data = response.data;
        parseApi(state, data, 'posts');

    }).catch( err => {
        console.log('getUser error: ', err);
    })
},

모듈을 상속하고 그 안에 데이터 필드/함수를 추가할 수 있는지 알고 싶습니다.

모든 모듈에는 메시지와 상태 필드가 있으며 API에 대한 응답으로 표시됩니다.

export default {
    state : {
        message : "",
        status : 0
    },
    parseApi: function(state, data, property) {
        if (data.hasOwnProperty('message')) {
            state.message = data.message;
        }
        if (data.hasOwnProperty('status')) {
            state.status = data.status;
        }
        if (data.hasOwnProperty(property)) {
            state[property] = data[property];
        }
    }
}

그런 것 같아요.

이 코드를 한 번 작성하여 Im이 사용하는 모든 모듈에 넣을 수 있는 방법이 있습니까?

편집:

이 apiParse 함수도 거기에 넣을 수 없기 때문에 그 필드에 대해 뮤트를 해야 합니다.하지만 그걸 계속 반복하는 건 무의미해조언 좀 해주시겠어요?

재사용 가능한 vuex 코드를 소규모 수업에 넣습니다.예.

crud.js

export default class {
    constructor ( endpoint ) {
       this.state = {
          endpoint: endpoint,
          meta:     {},
          status:   null,
          known:    [],
          currentId: null,
       };
       this.getters = {
          id: state => id => state.known.find( o => o.id === id )
       };
       this.actions = {
          async store( context, payload ) {
               *(call to API)*
          },
          async update( context, payload ) {
               *(call to API)*
          },
          *...etc*
      };
      this.mutations = {
         STORED(state, item) {
            state.known.push(item);
         },
         *...etc*
      };
   }
}

그러면 모든 모듈에서 사용할 수 있습니다.

user.module.js

import Crud from '/crud';
var crud = new Crud('/api/users');

const state = {
   ...crud.state,
};
const getters = {
   ...crud.getters,
};
const actions = {
   ...crud.actions,
};
const mutations = {
   ...crud.mutations,
};

export default {
   namespaced: true,
   state,
   getters,
   actions,
   mutations
};

Erin의 응답을 조금 더 발전시키면 다음과 같은 공통 기능을 가진 기본 클래스를 정의할 수 있습니다.

export default class BaseModule {
    protected state() {
        return {
            isLoading: false,
        };
    };
    protected getters() {
        return {
            isLoading(s) {
                return s.isLoading;
            },
        };
    };
    protected actions() {
        return {};
    };
    protected mutations() {
        return {
            [START_TRANSACTION]: (s) => {
                s.isLoading = true;
            },
            [END_TRANSACTION]: (s) => {
                s.isLoading = false;
            },
        };
    }
    protected modules() {
        return {};
    };

    public getModule = () => {
        return {
            namespaced: true,
            state: this.state(),
            getters: this.getters(),
            actions: this.actions(),
            mutations: this.mutations(),
            modules: this.modules(),
        };
    }
}

이제 파생 클래스에서 필요한 부품만 클래스 상속으로 확장/오버라이드할 수 있습니다. 예를 들어 모듈을 확장해야 하는 경우...:

import BaseModule from './BaseModule';
import rowDensity from '@/store/modules/reusable/rowDensity';

export default class ItemListModule extends BaseModule {  
  protected modules() {
    return {
      ...super.modules(),
      rowDensity,
    };
  };
}

마지막으로 스토어에서 모듈로 사용하기 위해 인스턴스화하고 호출할 수 있습니다..getModule():

import Vue from 'vue';
import Vuex from 'vuex';
import ItemListModule from './modules/ItemListModule';

Vue.use(Vuex);

const debug = process.env.NODE_ENV !== 'production';

export const MODULE_NAMESPACES = {
  List: 'list',
};

export default new Vuex.Store({
  modules: {
    [MODULE_NAMESPACES.List]: new ItemListModule().getModule(),
  },
  strict: debug,
});

주(州) 필드에 대한 상속을 알아냈어요

https://vuex.vuejs.org/en/modules.html#namespacing

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations,
    modules : {
        apiResponses
    }
}

nameslayed를 사용하여 모듈 사용자 뒤에 apiResponse 모듈을 내보낸 후 게시물에 대해 동일한 작업을 수행했습니다.

네임스페이스는 메시지/상태 상태 및 돌연변이를 상속받았고, 방금 사용자와 포스트 모듈에서 호출했습니다.지금 그들은 열심히 일하고 있다.

my message mutation form apiResponses:

[types.SET_MESSAGE] (state, message) {
    state.message = message;
},

사용자 모듈의 내부 작업을 수행합니다.

if (data.hasOwnProperty('message')) {
    commit(types.SET_MESSAGE, data.message);
}

그럼 내 지지자 안에서 그냥 전화할게

    computed: {
        ...mapGetters({
            user : 'user/user',
            userMessage : 'user/message',
            post: 'post/monitoring',
            postMessage : 'post/message',

        }),
    },

편집필

제 마지막 호는 그렇습니다.

apiResponse 모듈 내에서 액션을 받았습니다.

let actions = {
    getResponseParsed({commit}, payload) {
        console.log(payload)
        if (payload.data.hasOwnProperty('message')) {
            commit(types.SET_MESSAGE, payload.data.message);
        }
        if (payload.data.hasOwnProperty('status')) {
            commit(types.SET_STATUS, payload.data.status);
        }
        if (payload.data.hasOwnProperty(payload.property)) {
            commit(payload.mutation, payload.data[payload.property]);
        }
    }
}

그리고 사용자 및 다른 모듈에서 다음과 같이 불렀습니다.

getUser ({ state, commit, dispatch }) {
    axios.get(urls.API_GET_USER_URL).then( response => {
        let data = response.data;

        dispatch('getResponseParsed', {
            data : data,
            mutation : types.SET_USER,
            property : 'user'
        });

    });
},

마지막으로 이 새로운 모듈을 컴포넌트처럼 작성해야 한다는 문서에 따라 재사용할 수 있도록 해야 합니다.

export default {
    state() {
        return {
            message : '',
            status : 0,
        }
    },
    getters,
    mutations,
    actions
}

상태를 함수로 하여:)

다른 누군가가 같은 문제를 겪기를 바랍니다.d

제가 한 일은 다음과 같습니다.

우선, 저는 이 모든 것을mainApi.js그들의 의무는 아피스와 연결시키는 것이다.

mainApi.js

import axios from "@/plugins/axios";

export default {
    get(url ,id){
        return axios.get(`/${url}/${id}`);
    },
    getAll(url, filter) {
        return axios.get(`/${url}`, {params: {...filter}});
    },
    create(url ,teBeCreated){
        return axios.post(`/${url}`, teBeCreated);
    },
    update(url ,toBeUpdated){
        return axios.put(`/${url}/${toBeUpdated.oid}`, toBeUpdated);
    },
    delete(url ,id){
        return axios.delete(`/${url}/${id}`);
    },
}

두 번째: 데이터를 저장하기 위해 필요한 함수를 정의하는 기본 클래스를 작성했습니다.이 클래스는 다른 스토어 모듈에 상속될 수 있습니다.

gate.gate.displaces를 참조해 주세요.

import mainApi from '@/api/main'
import store from '@/store'

export default class {

  constructor() {

    this.state = {
        view: null,
        list: [],
    };

    this.getters = {
        view: (state) => state.view,
        list: (state) => state.list,
    }

    this.mutations = {
        SET_VIEW(state, payload) {
            state.view = payload;
        },
        SET_LIST(state, payload) {
            state.list = payload;
        },
        UN_SET_VIEW(state) {
            state.view = null;
        },
        UN_SET_LIST(state) {
            state.list = [];
        },
    }

    this.actions = {
        get({ commit }, { url, id }) {
            return new Promise((resolve, reject) => {
                mainApi.get(url, id)
                    .then(response => {
                        commit('SET_VIEW', response.data.data);
                        resolve(response)
                    })
                    .catch(error => {
                        console.log("error in get method in gate store: ", error);
                        commit('UN_SET_VIEW');
                        reject(error)
                    })
            });
        },
        getAll({ commit }, { url, filter }) {
            return new Promise((resolve, reject) => {
                mainApi.getAll(url, filter)
                    .then(response => {
                        commit('SET_LIST', response.data.data);
                        resolve(response)
                    })
                    .catch(error => {
                        console.log("error in getAll method in gate store: ", error);
                        commit('UN_SET_LIST');
                        reject(error)
                    })
            });
        },
        create({ commit }, { url, params }) {
            return new Promise((resolve, reject) => {
                mainApi.create(url, params)
                    .then(response => {
                        resolve(response)
                    })
                    .catch(error => {
                        console.log("error in create method in gate store: ", error);
                        reject(error)
                    });
            });
        },
        update({ commit }, { url, params }) {
            return new Promise((resolve, reject) => {
                mainApi.update(url, params)
                    .then(response => {
                        resolve(response)
                    })
                    .catch(error => {
                        console.log("error in update method in gate store: ", error);
                        reject(error)
                    })
            })
        },
        delete({ commit }, { url, id }) {
            return new Promise((resolve, reject) => {
                mainApi.delete(url, id)
                    .then(response => {
                        resolve(response);
                    })
                    .catch(error => {
                        console.log("error in delete method in gate store: ", error);
                        reject(error)
                    })
            });
        },
    }
}

셋째, 필요한 만큼 개별 스토어 모듈을 정의할 수 있습니다.아래에서 볼 수 있듯이 각 모듈에서 뷰에서 가져온 데이터를 mainApi로 전달하고(gate.js 기본 클래스의 함수와 메서드는 모두 모듈의 일부입니다) 수신된 데이터로 조작하면 됩니다.

someStore.js

import Gate from '@/store/modules/gate'

let gate = new Gate();
const url = 'customUrl'

const gateStates = { ...gate.state }
const gateGetters = { ...gate.getters }
const gateMutations = { ...gate.mutations }

const state = {
    ...gateStates,
};
const getters = {
    ...gateGetters,
};
const mutations = {
    ...gateMutations,
};

const actions = {
    get: ({ commit }, id) => gate.actions.get({ commit }, { url, id }),
    getAll: ({ commit }) => gate.actions.getAll({ commit }, {url, filter: {}}),
    create: ({ commit }, params) => gate.actions.create({ commit }, { url, params }),
    update: ({ commit }, params) => gate.actions.update({ commit }, { url, params }),
    delete: ({ commit }, id) => gate.actions.delete({ commit }, { url, id })
};

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations
};

마지막으로 모듈을 Import하여 "vuex store modules"로 정의하여 다음과 같이 합니다.

store/index.displaces

import Vue from 'vue'
import Vuex from 'vuex'
import someModule from './modules/someModule'

Vue.use(Vuex)

export default new Vuex.Store({

    state: {},

    mutations: {},

    actions: {},

    modules: {
        someModule
    },

    plugins: {}

})

에서는 다른 것을 했습니다.Promise내 뷰에 서버 응답이 직접 필요했기 때문입니다.스토어에서 응답만 사용하려는 경우 이러한 약속은 필요하지 않으며 다음과 같이 삭제해야 합니다.

gate.js을 고치다

get({ commit }, { url, id }) {
    return new Promise((resolve, reject) => {
        mainApi.get(url, id)
            .then(response => {
                commit('SET_VIEW', response.data.data);
                resolve(response)
            })
            .catch(error => {
                commit('UN_SET_VIEW');
                console.log("error in getOne method in gate store: ", error);
                reject(error)
            })
    });
},

여기에

get({ commit }, { url, id }) {
    mainApi.get(url, id)
        .then(response => {
            commit('SET_VIEW', response.data.data);
        })
        .catch(error => {
            commit('UN_SET_VIEW');
            console.log("error in getOne method in gate store: ", error);
        })
},

하면 '이렇게'가 됩니다.list ★★★★★★★★★★★★★★★★★」view뷰에서 할 수 .

보기표시하다

created() {
    store.dispatch('someModule/get', this.$route.params.id)
}

computed: {
    view() {
        return store.getters('someModule/view')
    }
}

개인적인 과제로서 이 요구를 표현할 수 있는 순수한 ES6 클래스를 만들고 싶었습니다(주석은 허용되지 않습니다). 해서 는는이 an 를 만들었습니다.AbstractModule높은 수준의 조작을 정의하는 클래스:

export default class AbstractModule {
    constructor(namespaced = true) {
        this.namespaced = namespaced;
    }

    _state () {
        return {}
    }

    _mutations () {
        return {}
    }

    _actions () {
        return {}
    }

    _getters () {
        return {}
    }

    static _exportMethodList (instance, methods) {
        let result = {};
        // Process methods when specified as array
        if (Array.isArray(methods)) {
            for (let method of methods) {
                if (typeof method === 'string') {
                    result[method] = instance[method].bind(instance);
                }

                if (typeof method === 'function') {
                    result[method.name] = method.bind(instance);
                }

                // else ignore
            }
        }

        // Process methods when specified as plain object
        if (typeof methods === "object") {
            for (const [name, method] of Object.entries(methods)) {
                if (typeof method === 'string') {
                    result[name] = instance[method].bind(instance);
                }

                if (typeof method === 'function') {
                    result[name] = method.bind(instance);
                }
            }
        }

        // Process methods when specified as single string
        if (typeof methods === 'string') {
            result[name] = instance[methods].bind(instance);
        }

        // Process methods when specified as single callback
        if (typeof methods === 'function') {
            result[name] = methods.bind(instance);
        }

        return result;
    }

    static module() {
        let instance = new this();
        console.log(instance);

        return {
            namespaced: instance.namespaced,
            state: instance._state(),
            mutations: AbstractModule._exportMethodList(instance, instance._mutations()),
            actions: AbstractModule._exportMethodList(instance, instance._actions()),
            getters: AbstractModule._exportMethodList(instance, instance._getters())
        }
    }
}

여기서부터 저는 제 클래스 모듈을 만들었습니다.parent:

export default class QuestionModule extends AbstractModule{
    constructor(question) {
        super();
        this.question = question;
    }

    selectLine (state, line) {
        this.question.selectLine(line);
    }

    unselectLine (state, line) {
        this.question.unselectLine(line);
    }

    submit ({ state, commit, rootState }) {
        /** API call */
    }

    _state () {
        return this.question;
    }

    _mutations () {
        return [this.selectLine, this.unselectLine, this.validate];
    }

    _actions () {
        return this.submit;
    }
}

스토어에 입니다('Vuex' ).module태틱틱 : : : 。

const store = new Vuex.Store({
  modules: {
      question: QuestionModule.module()
  },
  strict: process.env.NODE_ENV !== 'production'
});

언급URL : https://stackoverflow.com/questions/48327261/way-to-make-inheritance-in-vuex-modules

반응형