Frontend-sovellusten, erityisesti monimutkaisempien, on käsiteltävä paljon dataa. Ohjelmoijat ottavat käyttöön erilaisia suunnittelumalleja tehdäkseen projekteistaan luettavia ja ylläpidettäviä. Useimmissa yleisimmissä MVC-skenaarioissa haluamme erottaa datan sovelluksen visuaalisista osista.
Tästä syystä myymälä on tullut niin hyödylliseksi. Sinusta riippuu, käytätkö React + Reduxia vai Vue + Vuex - päätavoite on sama, nimittäin tietojen säilyttäminen jäsennellysti, helposti saatavilla ja turvallisesti samaan aikaan..
Tässä artikkelissa näytän sinulle muutamia esimerkkejä siitä, miten voit pitää Vuex-varastosi siistinä ja tehokkaana.
Ennen kuin aloitamme, oletetaan, että:
- sinulla on jonkin verran kokemusta nykyaikaisista JavaScript,
- tiedät periaatteessa, mikä Vue on ja miten sitä käytetään. rekvisiitta, laskettu, jne,
- tunnet Vuex:n (toimet, mutaatiot, jne.) ja haluat parantaa sovelluksiasi.
Vuex, kuten suurin osa Vue-hankkeeton melko hyvin dokumentoitu, ja löydät monia hyödyllisiä hakkereita virallisista dokumenteista. Olemme poimineet siitä joitakin olennaisia tietoja sinulle.
Perus Vuex-varaston toteutus näyttää seuraavalta:
// main.js
import Vue from 'vue'
import Vuex from 'vuex'
import App from "./App";
Vue.use(Vuex)
const store = new Vuex.Store(((
state: (
data: null;
),
actions: (
someAction: (( commit ), data) (
commit("SOME_MUTATION", data);
)
),
mutations: (
SOME_MUTATION (state, data) (
state.data = data;
)
))
));
uusi Vue((
el: "#app",
render: h => h(App),
store
));
Yleensä, kun sovelluksesi kasvaa, joudut käyttämään reititystä, joitakin globaaleja direktiivejä, lisäosia jne. Se tekee main.js
tiedosto on paljon pidempi ja vaikeampi lukea. On hyvä käytäntö säilyttää tallennus ulkoisessa tiedostossa, kuten tässä:
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = (
data: null;
);
const actions = (
someAction: (( commit ), data) (
commit("SOME_MUTATION", data);
)
);
const mutations = (
SOME_MUTATION (state, data) (
state.data = data;
)
);
export default new Vuex.Store((
state,
actions,
mutations
));
1. Moduulit
Mitä sinun pitäisi tehdä, kun store.js
tiedostosta tulee valtava ja vaikea työstää? Itse asiassa Vuex:ssä on todella hieno ominaisuus - moduulit. Ne on tarkoitettu jakamaan tietosi erillisiin tiedostoihin.
Kuvittele, että työskentelet jonkin yrityssovelluksen parissa, jossa on esimerkiksi muutamia tietosalueita:
- käyttäjä (hallinnoi kaikkia valtuutuksia ja käyttöoikeuksia),
- reittiparametrit (hallinnoi globaaleja parametreja ennen API-pyyntöjä),
- myynti (kuukausittain, neljännesvuosittain tai vuosittain näkyvää SalesMegaChart-komponenttia varten),
- tilaukset (näkyvät SalesMegaChart-palkin napsauttamisen jälkeen).
...ja ehkä muutama muukin. Nyt sinulla on vakavia syitä ottaa modulaarisuus käyttöön kaupassasi.
Siirrä ensin store.js
tiedostoon juuri luotuun store/
hakemistoon ja nimeä se uudelleen index.js
. Vaihtoehtoisesti, jos haluat pitää kaiken pakattuna moduuleihin, poista valtio, toimet ja mutaatiot päätiedostosta.
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store(((
modules: (
// moduulit tulevat tänne
)
));
Luo sitten `store/index.js`-tiedoston viereen ensimmäinen moduuli - `store/user.js`.
import ApiService from '../services/api.service';
const state = (
loggedIn: false,
loginError: null,
user: null
);
const actions = (
login: async (( commit ), data) (
try (
const response = await ApiService.post('/login', data);
const ( user ) = response.data;
COMMIT("SAVE_USER", user);
COMMIT("LOGIN_SUCCESS");
) catch (virhe) (
commit("LOGIN_ERROR", virhe);
)
)
);
const mutations = (
SAVE_USER (state, user) (
state.user = user;
),
LOGIN_SUCCESS (state) (
state.loggedIn = true;
),
LOGIN_ERROR (state, error) (
state.loginError = error;
state.loggedIn = false;
)
);
export const user (
state,
actions,
mutations
)
Lataa nyt valmis moduuli päätiedostoon `store/index.js`:
import Vue from 'vue'.
import Vuex from 'vuex'.
import ( user ) from './user';
Vue.use(Vuex);
export default new Vuex.Store((
modules: (
user
)
));
Onnittelut! Nyt sinulla on todella hienon näköinen myymälätoteutus. Voit myös käyttää tietoja komponentista (esim, UserProfile.vue
) näin:
<template>
<div class="user-profile">
<h2>(( user.name )))!</h2>
<!-- component template goes here -->
</div>
</template>
<script> import ( mapActions ) from 'Vuex';
export default (
name: 'UserProfile',
computed: mapState((
user: state => state.user
// user: 'user' <-- alternative syntax
))
)
</script>
2. Nimiavaruudet
Nyt kun tiedät, miten moduuleja käytetään, sinun on syytä tutustua myös Vuex:n ominaisuuksiin. namespacing. Edellisessä vaiheessa luotiin store/user.js
tiedosto, jossa on käyttäjä moduuli.
Tietorakenne, joka on määritelty user.js
tiedostoon pääsee käsiksi komponenteista, mutta voit huomata, että kaikki käyttäjä tiedot menevät suoraan globaaliin valtio
yhteydessä, kuten tässä:
laskettu: mapState((
user: state => state.user
// user: 'user' <-- vaihtoehtoinen tapa
))
Kun määrittelet useampia moduuleja, tulet luultavasti sekaisin siitä, mikä objekti on peräisin mistäkin moduulista. Silloin kannattaa käyttää nimitettyjä moduuleja ja määritellä ne tällä tavalla:
export const user (
namespaced: true, // <-- namespacing!
state,
actions,
mutations
)
Tästä lähtien kaikki käyttäjä data (valtio
muuttuja store/user.js
tiedosto) käsitellään state.user
viite:
laskettu: mapState((
user: state => state.user.user
// user: 'user/user' <-- vaihtoehtoinen tapa
))
Muutamaa askelta myöhemmin voit saavuttaa komponentille jotain tällaista:
Vuex';
export default (
name: 'Dashboard',
computed: mapState((
sales: 'sales/data',
orders: 'orders/data',
sortBy: 'orders/sortBy',
loggedIn: 'user/loggedIn'.
)),
methods: mapActions((
logout: 'user/logout',
loadSales: 'sales/load',
loadOrders: 'orders/load'.
)),
created() (
if (this.loggedIn) (
loadSales();
loadOrders();
)
)
)
Bravo! Niin raikasta, niin puhdasta... Mutta älä huoli, refaktorointi ei lopu koskaan. Oletko valmis seuraaviin vaiheisiin?
3. Moduulien välinen viestintä
Ensimmäisessä vaiheessa, näytin joitakin toimia vuonna käyttäjä moduuli:
const actions = (
login: async (( commit ), data) (
try (
const response = await ApiService.post('/login', data);
const ( user ) = response.data;
COMMIT("SAVE_USER", user);
COMMIT("LOGIN_SUCCESS");
) catch (virhe) (
commit("LOGIN_ERROR", virhe);
)
)
);
Epäonnistumisen varalta lisäämme kirjautumisvirheen myymäläämme - mitä seuraavaksi?
Tässä on muutamia vaihtoehtoja, ja valinta riippuu siitä, mikä vaihtoehto sopii tarpeisiisi paremmin. Yksinkertaisin tapa käyttää v-if
direktiivin avulla voidaan näyttää virheilmoitus, jos kaupassasi on virhe.
<template>
<div class="dashboard">
<!-- dashboard component template -->
<div
v-if="error"
class="error-message"
> (( error.message ))) </div>
</div>
</template>
<script> import ( mapActions ) from 'Vuex';
export default (
name: 'Dashboard',
computed: mapState((
error: "user/loginError"
))
)
</script>
Kuvittele taas, että sinulla on monta moduulia ja että jokainen try/catch
syntaksi tuottaa uuden virheen myymälässäsi. On selvää, että käytät DRY-sääntöä väärin tällä tavalla.
Miten voit tehdä virheenkäsittelyprosesseistasi yleisempiä?
Määritellään yhteinen moduuliin ja laittaa sinne logiikkaa, jota käytetään maailmanlaajuisesti.
// store/common.js
const state = (
errors: []
);
const actions = (
error: (
root: true,
handler(( commit ), error) (
commit("ERROR", virhe);
)
)
),
const mutations = (
ERROR (tila, virhe) (
/* näin saadaan uusin virhe listan kärkeen */
state.errors = [error, ...state.errors];
))
);
export const common (
namespaced: true,
state,
mutations
)
Nyt voimme mukauttaa käyttäjä moduulin (ja myös muiden moduulien):
yritä (
// some action
)catch (error) (
commit("common/ERROR", error, ( root: true ));
)
tai tyylikkäämmin käyttämällä globaalia toimintoamme:
try (
// some action
) catch (error) (
dispatch("virhe", virhe);
)
Tämä syntaksi commit
ja lähetä
puhelut vaikuttavat itsestään selviltä, mutta voit lukea lisää näistä nikseistä. täällä.
Kun sinulla on kaikki virheet yhdessä paikassa, voit helposti ladata ne omaan Kojelauta
komponentti:
laskettu: mapState((
errors: 'common/errors'
)),
watch: (
/* tätä kutsutaan jokaisen "common/ERROR"-mutaation jälkeen, jolloin lisäämme vain uusia virheitä varastoon yksi kerrallaan */
errors() (
this.showErrorMessage(this.errors[0]);
)
)
Edellinen esimerkki, jossa yhteinen moduulin virheiden käsittely on jo tehokas ratkaisu, mutta voit mennä vielä pidemmälle.
Kuten näet, seuraamme muutoksia, jotka tapahtuvat yhteiset/virheet
array myymälässä. Tällaisissa tapauksissa, kun sinun täytyy määrittää jokin tiettyyn mutaatioon kohdistuva toimenpide, voit käyttää komentoa Vuex-liitännäiset tai jopa Higher Order Components (HOC).
Käsittelen liitännäisiä ja HOC:eja seuraavassa artikkelissa. Sillä välin, kiitos, että luit tämän merkinnän, toivottavasti, nautit esimerkkejä olemme valmistelleet.
Pysy kuulolla ja jatka koodaamista!
Lue lisää:
– Miten parantaa Vue.js-sovelluksia? Joitakin käytännön vinkkejä
– GraphQL: tuotannossa opittua
– Shopify, Spree vai Solidus? Tarkista, miksi Ruby on Rails voi auttaa sinua kehittämään sähköistä kaupankäyntiäsi.