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
'programing' 카테고리의 다른 글
Arrays.asList() vs Collections.singletonList() (0) | 2022.08.15 |
---|---|
vue.select 2 다중 선택 (0) | 2022.08.08 |
Vue 및 Vuex가 html에서 적절한 값을 취득하지 않음 (0) | 2022.08.08 |
Spring @Autowired 필드가 null인 이유는 무엇입니까? (0) | 2022.08.08 |
vuejs 필터에 인수를 전달하는 방법 (0) | 2022.08.08 |