@AleksMerk

Как управлять состоянием множества диалоговых окон (Vue, Vuex, Element UI)?

Сейчас реализован вызов одного окна, при помощи изменения его состояния видимости в Store.

В сторе есть объект modals. А dialogSignUp и dialogSignIn это два окна:

state: {
    modals: {
      dialogSignUp: false,
      dialogSignIn: false
    }
  },
  mutations: {
    DIALOG_SHOW(state, value) {
      state.modals.dialogSignUp = value;
    }
  },
  actions: {
    dialogShow({ commit }, value) {
      commit("DIALOG_SHOW", value);
    }
  },
  getters: {
    dialogSignUp: state => {
      return state.modals.dialogSignUp;
    }
  }

Сейчас через компонент диалогового окна я взаимодействую со стором так:

computed: {
    modal: {
      get() {
        return this.$store.getters.dialogSignUp;
      },
      set(value) {
        this.$store.dispatch("dialogShow", value);
      }
    }
  },

Само окно и его вызов:

<el-button plain type="default" size="small" @click="modal = !modal">Popup</el-button>
  <el-dialog :title="title" :visible="modal" @close="modal = false">
    <slot></slot>
    <span slot="footer" class="dialog-footer">
      <el-button @click="modal = false">Отмена</el-button>
      <el-button type="primary" @click="popupAction">Ок</el-button>
    </span>
  </el-dialog>

Но сейчас это работает для одного окна dialogSignUp, а как реализовать открытие окон, когда их несколько? Каким образом к ним можно обратиться через кнопку вызова окна, чтобы не писать новый modal:{get(), set()}, и что можно сделать в сторе, чтобы не писать для каждого окна свои action и mutation?
  • Вопрос задан
  • 1131 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Передавайте в мутацию вместо просто состояния диалога объект вида { имя_диалога: состояние }. Тогда при обновлении состояния диалогов не будет необходимости обращаться к ним поимённо:

mutations: {
  dialogShow: (state, payload) => Object.assign(state.modals, payload),
},

В компоненте, вместо вычисляемого свойства modal, отвечающего за работу с одним диалогом, будет свойство modals, обеспечивающее получение состояния всех диалогов. А чтобы изменение состояния диалога по-прежнему выглядело как присваивание, воспользуемся Proxy, где будем перехватывать установку значений и вызывать мутацию:

modals() {
  return new Proxy(this.$store.state.modals, {
    set: (target, prop, value) => {
      this.$store.commit('dialogShow', { [prop]: value });
      return true;
    },
  });
},

Соответственно, в шаблоне заменяем установку значения просто свойства на установку значения свойства объекта:

<el-button @click="modals.dialogSignIn = true">sign in</el-button>

<el-dialog :visible="modals.dialogSignIn" @close="modals.dialogSignIn = false">
  <span slot="footer" class="dialog-footer">
    <el-button @click="modals.dialogSignIn = false">Закрыть</el-button>
  </span>
</el-dialog>

Посмотреть живьём.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы