Хотите облегченную альтернативу Vuex для управления состоянием в веб-приложениях Vue.js?
Vue.Observable
можно использовать в качестве хранилища состояний вместо Vuex в простых приложениях. Вот простой способ начать:
Версия 2.6.0 Vue.js добавила Vue.Observable
. Это функция, которая возвращает реактивный экземпляр данного объекта. В Vue объекты не являются автоматически реактивными. Это означает, что если мы хотим реагировать на изменение свойств объекта, нам нужно проделать дополнительную работу. Vue.Observable
делает это очень просто. Подробнее о реактивности читайте здесь.
Нереактивность
const obj = {x: 0, y: 0};
export default { // Vue component
data() { return {}; },
method() {
updateObj() {
obj.x = 1;
obj.y = 2;
}
}
}
В этом примере вызов updateObj
не приведет к повторному вычислению вычисленных значений и повторной визуализации представления. К счастью, компоненты Vue имеют функцию data
. Объект, возвращаемый data
, является реактивным!
Реактивность через данные()
export default { // Vue component
data() {
return {
obj: {x: 0, y: 0}
};
},
method() {
updateObj() {
this.obj.x = 1;
this.obj.y = 2;
}
}
}
Поскольку результат data
становится реактивным, вызов updateObj
приведет к пересчету вычисляемых значений, зависящих от obj
, и обновлению представления при необходимости.
Состояние выхода из компонентов
В базовых компонентах/приложениях все изменяемые данные помещаются в объект, возвращаемый функцией data
. Хранение всех данных приложения в data
функциях каждого компонента быстро разваливается. В частности, это становится проблемой, когда данные должны передаваться между одноуровневыми компонентами.
Компонент с данными передает их родительскому компоненту через события, а затем родительский компонент передает их родственному компоненту через реквизит? Даже в простых случаях это сразу запах кода, а не отличный опыт разработки. Он объединяет компоненты, его сложно тестировать, он подвержен ошибкам, неудобен в сопровождении и просто сбивает с толку.
Здесь на помощь приходят государственные магазины.
Государственное управление
Vuex — это подключаемый модуль хранилища состояний для Vue.js. Вот как vuejs.org описывает Vuex:
Vuex — это шаблон управления состоянием + библиотека для приложений Vue.js. Он служит централизованным хранилищем для всех компонентов приложения с правилами, гарантирующими, что состояние может быть изменено только предсказуемым образом.
Это здорово, но Vuex не совсем тривиален в использовании. Во-первых, его нужно добавить в качестве плагина к вашему приложению Vue. Во-вторых, он очень мощный, поэтому начать с него сложно. Наконец, многие приложения достаточно просты, чтобы не нуждаться в Vuex и всех его функциях для управления состоянием.
Итак, какова альтернатива Vuex? Разумеется, ответ в тему этого поста: Vue.Observable
.
Vue.Observable как хранилище состояний
Наконец, когда вся предыстория установлена, вот как использовать Vue.Observable
в качестве хранилища состояний.
store.js
import Vue from 'vue';
import axios from 'axios';
const state = Vue.Observable({ // this is the magic
radius: 0,
color: 'red'
});
export const getters {
radius: () => state.radius,
color: () => state.color
}
export const mutations {
setRadius: (val) => state.radius = val,
setColor: (val) => state.color = val
}
export const actions {
fetchRadiusFromApi() {
return axios
.get('http://localhost:5001/api/radius')
.then((res) => {
mutations.setRadius(res.data);
});
},
fetchColorFromApi() {
return axios
.get('http://localhost:5001/api/color')
.then((res) => {
mutations.setColor(res.data);
});
}
}
В строке 4, где мы объявляем state
, происходит важная часть. Геттеры и мутации — это то, как мы читаем и обновляем состояние. Действия — это то, куда идут асинхронные вызовы, а именно запросы API. Действия совершают изменения, потенциально основанные на результатах запросов API.
компонент.vue
<template>
<div>
<div>Radius: {{ radius }}</div>
<div>Color: {{ color }}</div>
<button @:click="setRadius(0)">Reset radius</button>
<button @:click="fetchColorFromApi">Fetch color</button>
</div>
</template>
<script>
import { getters, mutations, actions } from 'store.js';
export default {
data() { return {}; },
computed() {
...getters // radius(), color()
},
created() {
this.fetchRadiusFromApi(); // fetching data right away
this.fetchColorFromApi().then(() => {
console.log('You can chain then after actions, if you return the request');
});
}
methods() {
...mutations, // setRadius(val), setColor(val)
...actions // fetchRadiusFromApi(), fetchColorFromApi()
}
}
</script>
Подведение итогов
Вот и все! Любые компоненты могут просто импортировать store.js
и использовать одно и то же состояние. Нет необходимости использовать реквизит/события для передачи данных.
Дополнительный совет для компонентов, которым не нужны все геттеры или вычисляемое значение:
компонент.js
computed() {
// ...getters <- instead of this, do this:
radius() {
return getters.radius;
},
diameter() {
return getters.radius * 2;
}
// this component doesn't need color
}
Первоначально опубликовано на https://austincooper.dev 9 августа 2019 г.