JavaScript

Использование Vue.Observable в качестве State Store

Spread the love

Хотите легкую альтернативу Vuex для управления состоянием в веб-приложениях Vue.js?

Vue.Observable может использоваться как хранилище состояний state store вместо Vuex в простых приложениях.

В версии 2.6.0 Vue.js добавлен Vue.Observable. Эта функция, делает переданный ей объект реактивным. В Vue объекты не становятся реактивными автоматически. Это означает, что если мы хотим реагировать на изменение свойств объекта, нам нужно проделать дополнительную работу. Vue.Observable делает это супер легко. Подробнее о реактивности во Vue читайте здесь.

Non-Reactivity

const obj = {x: 0, y: 0};
export default { // Vue component
    data() { return {}; },
    method() {
        updateObj() {
            obj.x = 1;
            obj.y = 2;
        }
    }
}

В этом примере вызов updateObj не приведет к повторному вычислению значений и к повторному отображению их в шаблонах. К счастью, компоненты Vue имеют функцию data. Объект, возвращаемый data, является реактивным!

Reactivity через 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, и они обновится в шаблонах при необходимости.

Breakout State из Components

В обычных компонентах/приложениях все изменяемые данные помещаются в объект, возвращаемый функцией data. Но хранение всех данных приложения в функциях data в каждом компоненте не вариант. В частности, это становится проблемой, когда данные должны передаваться между одноуровневыми компонентами.

Передает ли компонент с данными его родительскому компоненту через события, а затем родительский компонент передает его дочернему компоненту через props? Даже в простых случаях это становится большой головной болью. Все эти данные сильно связывают компоненты, их становиться сложно тестировать, они становятся больше подвержены ошибкам и вся эта ситуация просто сбивает с толку.

Тут нам может помочь единое хранилище state stores.

State Management

Vuex — подключаемый модуль хранилища состояний для Vue.js. Вот как vuejs.org описывает Vuex:

Vuex — это шаблон управления состоянием + библиотека для приложений Vue.js. Он служит централизованным хранилищем для всех компонентов приложения с правилами, гарантирующими, что состояние может быть изменено только предсказуемым образом.

Это здорово, но Vuex не совсем тривиален в использовании. Во-первых, его нужно добавить как плагин к вашему приложению Vue. Во-вторых, это очень мощный инструмент, с которым сложно разобраться новичкам. Наконец, многие приложения достаточно просты, чтобы не нуждаться в Vuex и всех его функциях для управления состоянием.

Итак, какова альтернатива Vuex? Конечно, ответом является тема этого поста: Vue.Observable.

Vue.Observable как State Store

Рассмотрим пример использования 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, происходит важная часть. Геттеры (getters) и мутации (mutations) — это то, как мы получаем и обновляем состояние. К действиям (actions) относятся асинхронные вызовы, а именно запросы API. Действия совершают мутации, потенциально основанные на результатах запросов API.

И пример использования описанного выше хранилища в компоненте.

component.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 и использовать одно и то же состояние. Нет необходимости использовать props/events для передачи данных.

Бонусный совет для компонентов, которым не нужны геттеры, а нужны вычисляемые значения computed:

component.js

computed() {
    // ...getters <- instead of this, do this:
    radius() {
        return getters.radius;
    },
    diameter() {
        return getters.radius * 2;
    }
    // this component doesn't need color
}

Оригинальная статья Austin CooperUsing Vue Observable as a State Store

Была ли вам полезна эта статья?
[11 / 4.1]

Spread the love
Editorial Team

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

11 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

11 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago