Vuex - полезная нагрузка мутации в новом окне / вкладке - PullRequest
0 голосов
/ 22 ноября 2018

У меня простой VueJS SPA, обслуживаемый Express.Express также обрабатывает конечные точки API, вызываемые интерфейсом Vue.Express подключен к Postgres, а конечные точки API взаимодействуют с базой данных (выполняют базовые операции CRUD).

В моей базе данных у меня есть одна таблица "Patient" с столбцами "first_name", "last_name", ""date_of_birth "и" id ".

В хуке созданного () компонента PatientList.vue база данных запрашивается для всех пациентов, и эта информация сохраняется в данных компонента, отображаемых с помощью цикла v-for.

Мой код PatientList.vue:

<script>
import auth from '@/auth/authenticator';
import { mapMutations } from 'vuex';

export default {
    components: {
        name: 'PatientsList',
    },
    data() {
        return {
            patients: [],
        }
    },
    computed: {
        accessTokenGetter: {
            get: function () {
                return this.$store.getters.accessToken;
            },
        },
        patientEditStatusGetter: {
            get: function () {
                return this.$store.getters.g_patientEditStatusCheck;
            },
        },
    },
    methods: {
        ...mapMutations([
            'm_startPatientEditProcess',
            'm_endPatientEditProcess',
            'm_clearPatientEditState',
            'm_cachePatient'
        ]),
        cachePatientHandler(ptnt) {
            console.log('PatientList.vue method cachePatientHandler', ptnt);
            var patientObject = {
                'date_of_birth': ptnt.date_of_birth.split('T')[0],
                'first_name': ptnt.first_name,
                'last_name': ptnt.last_name,
                'patient': ptnt.patient,
                'uid': ptnt.uid
            }
            this.m_endPatientEditProcess(false);
            this.m_clearPatientEditState('');
            this.m_startPatientEditProcess(true);
            this.m_cachePatient(patientObject);
        },
        getPatients() {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', 'https://voyager.wrk.health/patients/index');
            xhr.setRequestHeader('Authorization', `Bearer ${this.accessTokenGetter}`);
            xhr.setRequestHeader('Cache-control', 'no-cache');
            xhr.onload = () => {
                var data = JSON.parse(xhr.response);
                for( var i=0, r = data.results; i<r.length; i++ ){
                    this.patients.push(r[i]);
                }
            };
            xhr.onerror = () => {
                console.log(xhr.statusText);
            };
            xhr.send();
        },
    },
    beforeCreate() {
    },
    created() {
        console.log('PatientList.vue created()');
        if(auth.isUserLogged()){
            this.getPatients();
        } else {
            router.go('/');
        }
    },
};
</script>

Чтобы отредактировать пациента, у меня есть роутер-ссылка для редактирования страницы.Ссылка на маршрутизатор имеет обработчик щелчка, передаваемый аргумент является итеративным из цикла v-for (т. Е. Один объект пациента).У меня есть 4 мутации, связанные с этим

const mutations = {
  m_startPatientEditProcess(state, trueStatus) {
   console.log('Vuex patient m_startPatientEditProcess');
   state.patientEditStatus = trueStatus;
  },
  m_endPatientEditProcess(state, falseStatus) {
   console.log('Vuex patient m_endPatientEditProcess');
   state.patientEditStatus = falseStatus;
  },
  m_clearPatientEditState(state, emptyString) {
   console.log('Vuex patient m_clearPatientEditState');
   state.patientDetails.date_of_birth = emptyString;
   state.patientDetails.first_name = emptyString;
   state.patientDetails.last_name = emptyString;
   state.patientDetails.patient = emptyString;
   state.patientDetails.uid = emptyString;
  },
  m_cachePatient(state, patientObj) {
   console.log('Vuex patient m_cachePatient, received: ', patientObj);
   state.patientDetails.date_of_birth = patientObj.date_of_birth;
   state.patientDetails.first_name = patientObj.first_name;
   state.patientDetails.last_name = patientObj.last_name;
   state.patientDetails.patient = patientObj.patient;
   state.patientDetails.uid = patientObj.uid;
  },

Кроме того, мой код PatientEdit.vue:

<script>
import { mapMutations } from 'vuex';

export default {
  components: {
    name: 'PatientEdit',
  },
  data() {
    return {
      patientToEdit: {
        first_name: '',
        last_name: '',
        date_of_birth: '',
        patient: '',
        uid: '',
      },
      patientDetailsLoaded: false,
    }
  },
  computed: {
    patientToEditDetailsGetter: {
      get: function() {
        return this.$store.getters.g_patientToEditDetails;
      }
    },
    accessTokenGetter: {
      get: function() {
        return this.$store.getters.accessToken;
      }
    }
  },
  methods: {
    ...mapMutations([
      'm_endPatientEditProcess',
      'm_clearPatientEditState',
    ]),
    populatePatientEditState() {
      const pDeets = this.patientToEditDetailsGetter;
      this.patientToEdit.first_name = pDeets.first_name;
      this.patientToEdit.last_name = pDeets.last_name;
      this.patientToEdit.date_of_birth = pDeets.date_of_birth;
      this.patientToEdit.patient = pDeets.patient;
      this.patientToEdit.uid = pDeets.uid;
      this.patientDetailsLoaded = true;
    },
    submitUpdatedPatientDetails() {
      const payload = Object.assign({}, this.patientToEdit);
      const xhr = new XMLHttpRequest();
      xhr.open('PUT', `https://voyager.wrk.health/patients/update/${payload.uid}`)
      xhr.setRequestHeader('Content-type', 'application/json');
      xhr.setRequestHeader('Authorization', `Bearer ${this.accessTokenGetter}`);
      xhr.onload = async () => {
        try {
          await console.log(xhr.response);
          await console.log('Sent patient data to update endpoint \n Ready to be redirected.');
          await Promise.all([this.m_endPatientEditProcess(false), this.m_clearPatientEditState('')]);
          await this.$router.push('/patients/index');
        } catch (e) {
          throw new Error(e);
        }
      }
      xhr.send(JSON.stringify(payload));
    }
  },
  created() {
    this.populatePatientEditState();
  },
};
</script>

Я решил избежать ненужного запроса к базе данных.

Все работает как задумано.У меня есть store.subscription, настроенный для сохранения состояния Vuex в localStorage (для сохранения сеанса при обновлении этого приложения).Сохраняйте состояние журналов подписки и изменения, все в норме, например:

Вывод первого хранилища

Если я открою новую вкладку или окно (файлы cookie остались нетронутыми) и попробуйтечтобы выполнить те же самые операции обновления, моя подписка магазина выходит из строя, и я не могу автоматически заполнить свою страницу PatientEdit информацией о пациенте из Vuex.

В соответствии с выводом, внезапно мутация совершает вещи, которые я никогда не определял, например, так:

Сохранение вывода 2

Почему это происходит?

Спасибо за чтение.

Примечание: если я пропустил информациюнеобходимо выяснить это поведение, пожалуйста, дайте мне знать.

Edit 1:

Vuex store:

import Vue from 'vue';
import Vuex from 'vuex';

import session from './modules/session';
import patient from './modules/patient';

Vue.use(Vuex);

const store = new Vuex.Store({
    modules: {
        session,
        patient,
    },
    mutations: {
        initStore(state) {
            console.log('Vuex root state checking for local snapshot');
            if (localStorage.getItem('store')) {
                console.log('Snapshot found, hydrating...');
                this.replaceState(Object.assign(store, JSON.parse(localStorage.getItem('store'))));
            }
        },
    },
});

store.commit('initStore');

store.subscribe((mutation, state) => {
    console.warn('Subscription detected');
    console.log('mutation: ', mutation);
    console.log('state: ', state);
    localStorage.setItem('store', JSON.stringify(state));
});

export default store;

1 Ответ

0 голосов
/ 22 ноября 2018

В результате вы получаете сообщение об ошибке «невозможно преобразовать JSON в строку», потому что вы превращаете состояние, а также получатели, мутации и действия в строку.Они содержат ссылки на объект, который вы пытаетесь структурировать, что приводит к бесконечному циклу.

Это не проблема в вашем первом запуске, потому что ваш localStorage все еще пуст.Вы правильно структурируете свое состояние, но при перезагрузке запускается следующая строка:

this.replaceState(Object.assign(store, JSON.parse(localStorage.getItem('store'))));

Эта строка заменяет ваше состояние на store , расширенное тем, что имеется в localStorage.Если вы замените store на state, все должно работать намного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...