Основы работы с хранилищем Vuex

Основы работы с хранилищем Vuex
Комментарии: 0

Vuex является универсальным хранилищем данных для js фреймворка Vue. Использовать его стоит когда с одними данными должны работать разные компоненты. Чаще всего разработчик сам понимает когда это требуется.

Статья выполняет роль небольшой подсказки по функционалу Vuex. Для детального изучения рекомендуем обратиться к официальной документации. В примерах подразумевается что в проекте используется компонентный подход.

Схема vuex Страшная схема работы vuex

Установка может осуществляться несколькими способами:

npm install vuex --save // способ 1
yarn add vuex // способ 2

На практике часто ставят готовую сборку vue-cli с этим дополнением.

Далее в проекте создают каталог store с файлом index.js внутри. В нем можно создавать модель данных, но на практике в контейнере часто хранят данные разной направленности. Поэтому рекомедуется разбивать всё на модули. В этом случае index.js будет содержать примерно следующее:

import Vue from 'vue'
import Vuex from 'vuex'
import Auth from './modules/auth'
import Chat from './modules/chat'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    Auth,
    Chat
  }
})

То есть, в папке store создается вложенный каталог modules, а в нём уже файлы с данными. В примере это файл auth.js и chat.js, где .js при импорте опускается.

Пустое хранилище модуля chat.js будет выглядеть так:

export default {
    state: {

    },
    getters: {

    },
    actions: {

    },
    mutations: {

    }
}
  • State — содержит модель данных. Отличительно особенностью state в хранилище от data в комонентах является то, что их нельзя изменить напрямую. Для изменения обязательно нужно использовать функции из секции mutations.
  • Getters — функции, которые возвращают какие-то данные из хранилища. К state можно обратиться и напрямую, но если перед этим требуется обработать или отфильтровать данные, то применяют именно getters. Например, в state хранятся сообщения чата, но в компоненты должны попадать эти же сообщения, только с заменой матерных слов на звездочки. В этом случае создается функция getters, которая в цикле обходит все сообщения, заменяет мат и возвращает уже обработанный массив.
  • Mutations — синхронные функции для изменения состояния данных. Не могут быть асинхронными.
  • Actions — блок с функциями, которые могут быть асинхронными. Для примера представьте что в хранилище есть массив с сообщениями для чата. От компонента приходит запрос на добавление нового сообщения. В этом случае мы могли бы вызвать мутацию и добавить его в state, но в 99% случаев перед этим нам необходимо сначала это сообщение добавить в базу данных на сервере и только после этого обновить состояние хранилища. Поэтому в actions создают функцию, которая будет сначала отправлять данные на сервер, ждать ответа и только затем вызывать мутацию.

Пример использования:

export default {
    state: {
        msg: ['msg 1', 'msg 2', 'msg 3']
    },
    getters: {
        get_msg(state){
            return state.msg
        }
    },
    actions: {
        add_new_msg(context, data){
            
            // здесь можем добавлять новое сообщение в БД
            
            context.commit('add_msg', data)
        }
    },
    mutations: {
        add_msg(state, data){
            state.msg.push(data.msg)
        }
    }
}

Взаимодействие компонентов с vuex

В каждом примере будет рассмотрено 2 подхода к работе с vuex. Обычный и с привязкой через map.

State

Для получения данных из хранилища следует создавать вычисляемые данные. Это касается как state, так и getters.

export default {
  name: 'chat',
  computed: {
    get_msg() {
      return this.$store.state.Chat.msg
    }
  },
}

Chat — наименование модуля хранилища. Если модульный подход для Vuex не используется, то пишется просто this.$store.state.msg

Теперь в компоненте можем вывести все сообщения из контейнера:

<ul>
    <li v-for="(msg, key) in get_msg" :key="key">{{msg}}</li>
</ul>

Если в хранилище много полей, то использовать привязку данный из vuex к нашему компоненту так, будто это его собственные данные:

import { mapGetters } from 'vuex'

export default {
  name: 'chat',
  computed: {
    get_msg() {
      return this.$store.state.Chat.msg
    }
  },
}

Getters

Вместо обращения напрямую к данным контейнера часто используют getters, которые сначала обрабатывают данные и только потом отдают.

export default {
  name: 'chat',
  computed: {
    get_msg() {
      return this.$store.getters.get_msg
    }
  },
}

А вот так автоматически привязывают нужные getters, что позволяет сократить код.

import { mapGetters } from 'vuex'

export default {
  name: 'chat',
  computed: {
    ...mapGetters(['get_msg'])
  },
}

Mutations

Особенностью Vuex является невозможность изменения данных state напрямую. Для изменения обязательно нужно вызывать функции из секции mutations и вот как это делается:

export default {
  name: 'chat',
  methods: {
    add_msg_to_chat(){
      this.$store.commit('add_msg', {msg: 'Hello world'})
    }
  }
}

Здесь мы вызывали мутацию add_msg и передали ей дополнительный параметр, который представляет из себя объект.

Есть и ещё один подход к работе с Vuex. Он заключается в привязке хранилища к компоненту так, будто они принадлежат самому компоненту:

import {mapMutations} from 'vuex'
    
export default {
  name: 'chat',
  methods: {
    ...mapMutations(['add_msg']),
    add_msg_to_chat(){
      this.add_msg({ msg: 'Hello world'})
    }
  }
}

Actions

Вызов действий по синтаксису похож на мутации, но стоит помнить что они могут быть асинхронны, а мутации — нет.

export default {
  name: 'chat',
  methods: {
    add_msg_to_chat(){
      this.$store.dispatch('add_new_msg', {msg: 'Hello world'})
    }
  }
}

Все что изменилось, это commit поменялся на dispatch.

И второй подход:

import {mapActions, mapMutations} from 'vuex'
    
export default {
  name: 'chat',
  methods: {
    ...mapMutations(['add_msg']),
    ...mapActions(['add_new_msg']),
    add_msg_to_chat(){
      this.add_new_msg({ msg: 'Hello world'})
    }
  }
}

Если мутации не используются, то mapMutations можно удалить. В примере осталось для наглядности как использовать их совместно.

Темы:
JavaScript
Ещё интересное — 6
Комментарии —
    © REALADMIN.RU   2024 г.
    Страница сгенерирована: 0,1840 s | 4 mb.
    На каком уровне Вы играете в шахматы?
    OPROS