• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[VUE] Zmiana view component, po przez store.

Object Storage Arubacloud
0 głosów
236 wizyt
pytanie zadane 29 kwietnia 2019 w JavaScript przez ShiroUmizake Nałogowiec (46,300 p.)
edycja 30 kwietnia 2019 przez ShiroUmizake

Mam sobie oto taki wrapik:

<template>
  <div>
    <component :is="currentView"></component>
  </div>
</template>
<script>
import AddForm from './partials/add.vue';
import Preview from './partials/preview.vue';
import { mapState } from 'vuex';

export default {
  name: 'app',
  data() {
    return {
      message: 'Hello, Vue!!!!',
      currentView: 'AddForm'
    };
  },
  computed: {
    changeView() {
      return 'AddForm';
    },
    ...mapState({changeView: 'section.post.changeView'})
  },
  watch: {
    changeView(newValue, oldValue) {
    }
  },
  components: {
    AddForm,
    Preview
  }
};
</script>

Oraz taki stan na storze. 

  section: {
    post: {
      changeView: false
    }
  }

Który się mutuje tu:

    offerService.set(state.offer).then(response => state.sendResult = response);
    window.setTimeout(() => state.section.post.changeView = true, 3000);

Stan się zmienił co nie? więc i watch powinen zaregować. No właśnie nie zaregował.

Co chce osiągnać, gdy pewna częśc użytkownik wypełni formularz, i bedzie sukces, to chce mu zmienić po określonym czasie widok, jeśli flaga będzie na true. Ale  tu nic takowego się nie dzieje. Pomóżcie :3

 

Rozwiązanie problemu
<template>
  <div>
    <component :is="$store.state.section.post.view"></component>
  </div>
</template>
<script>
import AddForm from './partials/add.vue';
import Preview from './partials/preview.vue';
export default {
  name: 'postSection',
  data() {
    return {};
  },
  components: {
    AddForm,
    Preview
  }
};
</script>
metoda na storze.
  SEND_OFFER(state, payload) {
    offerService.set(state.offer).then(response => state.sendResult = response);
    window.setTimeout(() => state.section.post.view = 'preview', 3000);
  }

 

komentarz 29 kwietnia 2019 przez niezalogowany
Dlaczego masz 2x w computed `changeView`?
komentarz 29 kwietnia 2019 przez ShiroUmizake Nałogowiec (46,300 p.)
bez powodu po prostu próbowałem jakoś zrobić.

1 odpowiedź

0 głosów
odpowiedź 30 kwietnia 2019 przez andrew80 Użytkownik (900 p.)

Problem prawdopodobnie jest zagnieżdzenie (nested), bez pełnego kodu nie ciężko stwierdzić.

Z definicji w vuex należy używać mutacji/setterów do zmiany stanów. 

https://vuex.vuejs.org/guide/mutations.html

komentarz 30 kwietnia 2019 przez ShiroUmizake Nałogowiec (46,300 p.)

Proszę cały store.

import Vuex from 'vuex';
import Vue from 'vue';
import OfferService from '../../commons/Services/OfferService';
import LocationService from '../../commons/Services/LocationService';
import SubjectService from '../../commons/Services/SubjectService';
import { Offer } from '../../commons/Models/common/Offer';

Vue.use(Vuex);
const offerService = new OfferService();
const locationService = new LocationService();
const subjectService = new SubjectService();

const state = {
  config: {},
  searchResult: '',
  sendResult: {
    'error': '',
    'message': 'test'
  },
  changeView: true,
  finishSearchSubject: false,
  activeSubjectLevel: [],
  whereCorepetitions: [],
  subjectLevel: [],
  foundedSubjects:[],
  offer: Offer,
  section: {
    post: {
      changeView: false
    }
  }
}

const getters = {
  offers() {
    return offerService.get();
  },
  config() {
    return this.state.config;
  },
  searchResult() {
    return state.searchResult;
  },
  subjects() {
    return subjectService.get();
  },
  sendResult() {
    return state.sendResult;
  },
}

const mutations = {
  SET_OFFER(state, payload) {
    offerService.set(payload);
  },
  SET_CONFIG(state, payload) {
    state.config = payload;
  },
  SET_DICTIONARY(state, payload) {
    subjectService.set(payload.subjects);
    state.subjectLevel = payload.subjectLevel;
    state.whereCorepetitions = payload.whereCorepetitions;
  },
  START_LOCATION_SERVICE(state, payload) {
    locationService.init(payload);
  },
  FIND_BY_LOCATION(state, payload) {
    locationService.setTypes(['(cities)'])
    locationService.findBy(payload).then(value=> {
      state.searchResult = value;
    });
  },

  FIND_BY_SUBJECT(state, payload) {
    if (payload.value.length >= 3) {
      state.searchResult = subjectService.find(payload.value);
    } else {
      state.searchResult = [];
    }
  },

  FIND_BY_STREET(state, payload) {
    state.offer.street = payload;
  },

  PICK_SUBJECT(state, payload) {
    let foundedSubject =  subjectService.find(payload);
    state.activeSubjectLevel = state.subjectLevel[foundedSubject[0].type_id];
    state.offer.subjects_id = foundedSubject[0].id;
  },

  PICK_LEVEL_SUBJECT(state, payload) {
    state.offer.subject_level = state.activeSubjectLevel.findIndex(element => element === payload); 
  },

  PICK_WHERE_COREPETITIONS(state, payload) {
    state.offer.where_id = payload;
  },

  PICK_DESCRIPTION(state, payload) {
    state.changeView = false;
    state.offer.description = payload;
  },

  PICK_PRICE_MIN(state, payload) {
    state.offer.price_min = payload;
  },

  PICK_PRICE_MAX(state, payload) {
    state.offer.price_max = payload
  },

  RESET_SEARCH_RESULT(state, payload) {
    state.searchResult = [];
  },

  PICK_CITY(state, payload) {
    state.offer.city = payload;
  },

  PICK_STREET(state, payload) {
    state.offer.street = payload;
  },

  PICK_STREET_NUMBER(state, payload) {
    state.offer.number_house = payload;
  },

  PICK_NUMBER_FLOAT(state, payload) {
    state.offer.number_float = payload;
  },

  SEND_OFFER(state, payload) {
    offerService.set(state.offer).then(response => state.sendResult = response);
    window.setTimeout(() => state.section.post.changeView = true, 3000);
  }
}

const actions = {
  setOffer(context, payload) {
    context.commit('SET_OFFER', payload);
  },
  setConfig(context, payload) {
    context.commit('SET_CONFIG', payload);
  },
  setDictionary(context, payload) {
    context.commit('SET_DICTIONARY', payload);
  },
  initServices(context, payload) {
    context.commit('START_LOCATION_SERVICE', payload);
  },
  pickSubject(context, payload) {
    context.commit('PICK_SUBJECT', payload);
  },
  pickSubjectLevel(context, payload) {
    context.commit('PICK_LEVEL_SUBJECT', payload);
  },
  pickWhereCorepetitions(context, payload) {
    context.commit('PICK_WHERE_COREPETITIONS', payload);
  },
  pickDescription(context, payload) {
    context.commit('PICK_DESCRIPTION', payload);
  },
  pickPriceMin(context, payload) {
    context.commit('PICK_PRICE_MIN', payload);
  },
  pickPriceMax(context, payload) {
    context.commit('PICK_PRICE_MAX', payload);
  },
  pickCity(context, payload) {
    context.commit('PICK_CITY', payload);
  },
  pickStreet(context, payload) {
    context.commit('PICK_STREET', payload);
  },
  pickStreetNumber(context, payload) {
    context.commit('PICK_STREET_NUMBER', payload);
  },
  pickNumberFloat(context, payload) {
    context.commit('PICK_NUMBER_FLOAT', payload)
  },
  find(context, payload) {
    switch(payload.field) {
      case 'miejscowosc': context.commit('FIND_BY_LOCATION', payload); break;
      case 'przedmiot': context.commit('FIND_BY_SUBJECT', payload); break;
      case 'ulica': context.commit('FIND_BY_STREET', payload); break;
      default: context.commit('FIND_BY_LOCATION', payload); break;
    }
  },
  clearSearchResult(context, payload) {
    context.commit('RESET_SEARCH_RESULT', payload);
  },
  sendOffer(context, payload) {
    context.commit('SEND_OFFER', payload);
  }
}

export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions
})

Jeśli nie zagniedże to jest ok, z zagniedżonym stanem ma problem zmapować.

1
komentarz 30 kwietnia 2019 przez andrew80 Użytkownik (900 p.)

Musisz napisać po prostu getter, zamiast odpytywać zagnieżdżoną strukturę.

Możesz też obesorwować state przed watch, ale wtedy dodaj deep: true.

Dla mnie ten kod jest niepotrzebnie tak złożony. Możesz jeszcze prościej
 

<div id="app">
    <component :is="$store.state.section.post.view"></component>
</div>
const component1 = Vue.component('c1', {
  template: '<div>1111</div>',
});
const component2 = Vue.component('c2', {
  template: '<div>2222</div>',
});

Vue.use(Vuex);
const store = new Vuex.Store({
  state: {
     section: {
        post: {
            view: component1                                                                                                                                                                                                                                  
        }   
    }   
  }
});

new Vue({
    el: '#app',
    store,
    mounted() {
        window.setTimeout(() => this.$store.state.section.post.view = component2, 2000);
    }   
});

jeśli ten watch i złożona struktura ma jakiś ważny powód - rozpisz dokładnie czego i dlaczego potrzebujesz

komentarz 30 kwietnia 2019 przez ShiroUmizake Nałogowiec (46,300 p.)
Po prostu coś kombinowałem :), i tak mabyć takim wraperem :). Spróbuje z storem na getter :).

Podobne pytania

0 głosów
0 odpowiedzi 108 wizyt
pytanie zadane 7 grudnia 2020 w JavaScript przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
1 odpowiedź 205 wizyt
pytanie zadane 3 października 2018 w JavaScript przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
0 odpowiedzi 132 wizyt
pytanie zadane 27 grudnia 2017 w JavaScript przez ShiroUmizake Nałogowiec (46,300 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...