Frontendové aplikace, zejména ty složitější, musí zpracovávat velké množství dat. Programátoři zavádějí různé návrhové vzory, aby jejich projekty byly čitelné a udržovatelné. Ve většině běžných scénářů práce s MVC chceme oddělit data od vizuálních částí aplikace.
To je důvod, proč ukládat se stala tak užitečnou. Záleží jen na vás, zda budete používat React + Redux nebo Vue + Vuex - hlavní cíl je stejný, a to udržovat data strukturovaná, dostupná a zároveň bezpečná..
V tomto článku vám ukážu několik příkladů, jak udržet sklad Vuex čistý a efektivní.
Než začneme, předpokládejme, že:
- máte nějaké zkušenosti s moderními JavaScript,
- v podstatě víte, co je Vue a jak se používá rekvizity, vypočtené, atd.,
- jste obeznámeni s Vuex (akce, mutace, atd.) a chcete své aplikace vylepšit.
Vuex, stejně jako většina základních Projekty Vue, je poměrně dobře zdokumentován a v oficiálních dokumentech najdete mnoho užitečných hacků. Vybrali jsme z ní pro vás několik podstatných informací.
Základní implementace úložiště Vuex vypadá takto:
// main.js
import Vue z '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);
)
),
mutace: (
SOME_MUTATION (stav, data) (
state.data = data;
)
))
));
nový Vue((
el: "#app",
render: h => h(App),
store
));
Když se aplikace zvětší, musíte obvykle použít směrování, některé globální směrnice, zásuvné moduly atd. To způsobuje, že main.js soubor mnohem delší a hůře čitelný. Je dobré uchovávat úložiště v externím souboru, jako například zde:
// store.js
import Vue z '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,
mutace
));
1. Moduly
Co byste měli dělat, když store.js soubor je obrovský a obtížně se s ním pracuje? Ve skutečnosti existuje opravdu skvělá funkce Vuex - moduly. Jsou určeny k rozdělení dat do samostatných souborů.
Představte si, že pracujete na nějaké podnikové aplikaci, ve které máte například několik domén dat:
- uživatele (spravovat všechna oprávnění a oprávnění),
- parametry trasy (správa globálních parametrů před požadavky na rozhraní API),
- prodeje (pro komponentu SalesMegaChart viditelnou v měsíčním/čtvrtletním/ročním kontextu),
- objednávky (viditelné po kliknutí na lištu SalesMegaChart).
...a možná ještě několik dalších. Nyní máte vážný důvod zavést ve svém obchodě modulárnost.
Nejprve přesuňte store.js do nově vytvořeného souboru ukládat/ a přejmenujte jej na index.js. Pokud chcete zachovat vše zabalené do modulů, můžete případně odstranit stát, akce a mutace z hlavního souboru.
// store/index.js
import Vue z 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store((
modules: (
// moduly se umístí sem
)
));
Pak vedle souboru `store/index.js` vytvořte první modul - `store/user.js`.
import ApiService z '../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 (error) (
commit("LOGIN_ERROR", chyba);
)
)
);
const mutations = (
SAVE_USER (state, user) (
state.user = user;
),
LOGIN_SUCCESS (state) (
state.loggedIn = true;
),
LOGIN_ERROR (stav, chyba) (
state.loginError = error;
state.loggedIn = false;
)
);
export const user (
state,
actions,
mutations
)
A nyní načtěte připravený modul do hlavního souboru `store/index.js`:
vue': import Vue from 'vue'
import Vuex z 'vuex'
import ( user ) z './user';
Vue.use(Vuex);
export default new Vuex.Store((
modules: (
user
)
));
Gratulujeme! Nyní máte opravdu pěkně vypadající implementaci obchodu. K datům můžete přistupovat i z komponenty (např, UserProfile.vue) takto:
<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. Prostory názvů
Nyní, když víte, jak používat moduly, měli byste se také seznámit s funkcemi Vuex. jmenný prostor. V předchozím kroku jsme vytvořili store/user.js soubor s uživatel modul.
Datová struktura definovaná v user.js je přístupný z komponent, ale můžete si všimnout, že všechny uživatel data přechází přímo do globálního stát kontext, jako například zde:
vypočteno: mapState((
user: state => state.user
// user: 'user' <-- alternativní způsob
))
Při definování více modulů budete mít pravděpodobně zmatek v tom, který objekt pochází z kterého modulu. Pak byste měli používat moduly se jmenným prostorem a definovat je tímto způsobem:
export const user (
namespaced: true, // <-- namespacing!
state,
actions,
mutations
)
Od této chvíle budou všechny vaše uživatel data (stát proměnná z store/user.js ) se zpracovává v rámci state.user odkaz:
vypočteno: mapState((
user: state => state.user.user
// user: 'user/user' <-- alternativní způsob
))
O několik kroků později můžete pro komponentu dosáhnout něčeho takového:
import ( mapActions ) z 'Vuex';
exportovat výchozí (
name: "Dashboard",
vypočítáno: 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! Tak svěží, tak čistý... Ale nebojte se, refaktoring nikdy nekončí. Jste připraveni na další kroky?
3. Komunikace mezi moduly
V prvním kroku jsem vám ukázal nějakou akci v aplikaci uživatel modul:
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 (error) (
commit("LOGIN_ERROR", chyba);
)
)
);
V případě neúspěchu přidáváme do našeho obchodu chybu přihlášení - co bude dál?
Zde máme několik možností a výběr závisí na tom, která z nich lépe vyhovuje vašim potřebám. Nejjednodušší způsob používá v-if díky které se může zobrazit chybová zpráva, pokud se v úložišti vyskytne chyba.
<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>
Opět si představte, že máte mnoho modulů a každý z nich try/catch syntaxe vygeneruje novou chybu ve vašem obchodě. Je zřejmé, že tímto způsobem zneužijete pravidlo DRY.
Jak můžete své procesy zpracování chyb zobecnit?
Definujme společné a vložit do něj nějakou logiku, která by se používala globálně.
// store/common.js
const state = (
errors: []
);
const actions = (
error: (
root: true,
handler(( commit ), error) (
commit("ERROR", error);
)
)
),
const mutations = (
ERROR (stav, chyba) (
/* tímto způsobem budeme mít nejnovější chybu na začátku seznamu */
state.errors = [error, ...state.errors];
))
);
export const common (
namespaced: true,
state,
mutations
)
Nyní můžeme přizpůsobit uživatel (a také další moduly):
zkuste (
// nějaká akce
)catch (error) (
commit("common/ERROR", error, ( root: true ));
)
nebo elegantnějším způsobem pomocí naší globální akce:
try (
// nějaká akce
) catch (error) (
dispatch("error", error);
)
Tato syntaxe odevzdat a odeslání volání se zdá být samozřejmé, ale o těchto tricích si můžete přečíst více. zde.
Když máte všechny chyby na jednom místě, můžete je snadno načíst do svého počítače. Přístrojová deska součást:
vypočteno: mapState((
chyby: 'common/errors'
)),
watch: (
/* tato funkce bude vyvolána po každé mutaci "common/ERROR", kdy budeme do úložiště přidávat pouze nové chyby, jednu po druhé */
errors() (
this.showErrorMessage(this.errors[0]);
)
)
Předchozí příklad s společné Modul pro zpracování chyb je již efektivním řešením, ale můžete jít ještě dál.
Jak vidíte, sledujeme změny v oblasti společné/chybné pole v obchodě. V takových případech, kdy potřebujete určit nějakou akci na konkrétní mutaci, můžete použít funkci Zásuvné moduly Vuex nebo dokonce komponenty vyššího řádu (HOC).
Zásuvným modulům a HOC se budu věnovat v dalším článku. Zatím vám děkuji za přečtení tohoto příspěvku a doufám, že se vám připravené příklady líbily.
Zůstaňte naladěni a pokračujte v kódování!
Přečtěte si více:
– Jak vylepšit aplikace Vue.js? Několik praktických tipů
– GraphQL: zkušenosti z výroby
– Shopify, Spree nebo Solidus? Podívejte se, proč vám Ruby on Rails může pomoci s vývojem vašeho elektronického obchodu.