Для каждого одностраничного приложения должно быть хранилище для оптимального обмена данными между компонентами. Для Reactjs у нас есть redux / flux, а для Angular - ngrx. Для Vuejs у нас есть vuex.

Прежде чем продолжить, вы должны иметь базовое представление о Vuejs или, по крайней мере, концепцию Model – view – viewmodel (MVVM). У нас будут компоненты, представления и стили, как и у всех фреймворков SPA. Я буду охватывать vuex с нуля, так что никаких предварительных знаний не будет. в vuex не требуется.

Что такое магазин?

Магазин, как и каждое отдельное приложение страницы, представляет собой единую точку истины (просто данные). Он предоставляет API для изменения данных в магазине. Vuex - это шаблон управления состоянием и библиотека для приложений Vuejs. Он служит централизованным хранилищем всех компонентов приложения.

Установка vuex

Предполагая, что у вас есть базовое приложение vuejs, просто выполните эту команду в проекте.

npm установить vuex

Структура магазина Vuex

В корневой папке вашего приложения создайте этот файл и назовите его store.js.

import Vuex from ‘vuex’
import Vue from ‘vue’
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters:{
},
mutations: {
},
actions:{
}
})

И в этом файле main.js, где выполняется вся начальная загрузка, добавьте эту строку, где store - это файл store.js

import store from ‘./store’

и в разделе начальной загрузки

new Vue({
store, /** Add this line **/
render: h => h(App),
}).$mount(‘#app’)

Теперь мы успешно импортировали магазин в наше приложение. Давайте рассмотрим различные разделы в store.js.

состояние: он содержит все данные для нашего приложения. Мы даже можем установить начальное состояние данных здесь, например,

state: {
   userlist : [],
   showpopup :false,
   listdata : [],
},

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

getters:{
totalUsers : state => { return state.userlist.length },
}

мутации: здесь описаны функции для управления хранилищем. Мы вернемся к этому позже.

действия. Действия похожи на мутации, с той разницей, что:

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

Теперь перейдем к нашему приложению и к тому, чего мы пытаемся достичь. Наше приложение при начальной загрузке (точнее, при загрузке компонента) будет извлекать некоторые данные из API и сохранять их в хранилище vuex. Мы читаем те же данные из хранить и проделывать с ним все манипуляции.

Часть API

import axios from 'axios'
export default {
getUsers(){
return axios.get('/users')
.then(response => {
return response.data;
})
}
}

Назовите файл UserApi.js. Мы используем axios для вызовов API и не забываем добавить эту строку в main.js.

axios.defaults.baseURL = ‘https://jsonplaceholder.typicode.com'

поэтому URL-адрес будет https://jsonplaceholder.typicode.com / users

Составная часть

// Import the above API file in your component
import UserApi from ‘../services/UserApi’

Давайте вызовем этот API в ловушке жизненного цикла created vuejs.

created() { // this is a life cycle hook
UserApi.getUsers().then(users => {
this.addUser(users); //we will come to this function later
})
.catch()
.finally(() => {
})
}

Теперь нам нужно использовать вспомогательные функции vuex для получения и установки данных из хранилища.
В нашем компоненте мы должны импортировать это

import { mapMutations, mapState, mapGetters} from ‘vuex’

Эти помощники используются для сопоставления магазина с компонентами (мутации, состояние и геттеры).

Вернемся к нашему store.js и добавим наши мутации, геттеры и состояния

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
users:[] // we are displaying a list of users
},
getters:{
//getter for total number of users
totalUsers : state => {
return state.users.length 
},
//getter for getting the Max id from the user list ,The user list is a JSON and it has a field id.
maxId : state => {
return Math.max(...state.users.map(o => o.id), 0) + 1;
}
},
mutations: {
//Add user to the existing array
ADD_USER:(state,name) =>{
state.users.push(...name);
},
//Remove user from the user list
REMOVE_USER:(state,index) =>{
state.users.splice(index,1);
},
},
actions:{
//we dont have any actions for this example
}
})

Снова в нашем компоненте и в ловушке жизненного цикла вычислено добавьте это

computed: {
...mapState([
     'users' // this is the variable we are initializing in the state section of store
]),
...mapGetters([
      // The getter function names
      'maxId',
      'totalUsers'
])
},

Снова в нашем компоненте и в ловушке жизненного цикла методы добавьте это

methods: {
//The name of functions in the mutation section in the store.js
 …mapMutations([
   ‘ADD_USER’,
   ‘REMOVE_USER’,
]),
}

Теперь мы добавили весь код, связанный с store.js. Теперь пришло время вызвать и использовать их. Раньше у нас был UserApi, который вызывает API при загрузке страницы. Мы сохраняем ответ в нашем магазине.

created() {
UserApi.getUsers().then(users => {
this.addUser(users);//This function adds the API result to our store
}).catch()
.finally(() => {
})
},
methods() {
 addUser:function(data){
  // data is coming from API
 // ADD_USER is a mutation function.It is now available for calling   // because we have used mapMutations to bind that with component   this.ADD_USER(data)
 }
}

Связывание данных магазина с шаблоном

<div v-for=”(user,index) in users” class=”row” v-bind:key=user.id>
<div> {{ user.name }} </div>
<div> <a :href=’”mailto:”+user.email’>{{ user.email }}</a> </div>
<div> {{ user.phone }} </div>
<div> {{ user.website }} </div>
<span v-on:click=”removeUser(index)” class=”link”>delete</span>
</div>

Использование геттеров


<p>Total users in store : <strong>{{this.totalUsers}}</strong></p>

в нашем приложении были mapGetters. просто вызовите эту функцию-получатель.

Манипуляции с магазином

Удаление пользователя из магазина

removeUser(id){
this.REMOVE_USER(id)
},

Добавление пользователя в магазин

<button v-on:click="addUserInput">Add</button>
addUserInput(){
this.addUser([{
    “id”: this.maxId, // again a getter function
    “name”: this.username,
    “phone”:this.phone,
    “email”:this.email,
    “website”:this.website,
}])
this.username = ''
this.phone = ''
this.email = ''
this.website = ''
},
addUser:function(data){
  this.ADD_USER(data)
}

Наконец, давайте еще раз повторим шаги

  1. Инициализировать хранилище с соответствующими геттерами, мутациями и состоянием
  2. При загрузке компонента вызовите API, в случае успеха сохраните данные в нашем хранилище vuex, передав данные в функцию мутации. Используйте mapMutations для вызова функции мутации из компонента.
  3. Где необходимо, используйте геттеры.
  4. Реализуйте то же самое для функций ДОБАВЛЕНИЯ и УДАЛЕНИЯ.
  5. Привяжите переменные хранилища к компонентам с помощью mapState.

Снимок экрана

Полный пример можно найти здесь
https://github.com/ubercooluk/vuex-example

просто клонируйте репо. Тогда все, что вам нужно сделать, это

 yarn install
 yarn serve

Заключение
Мы рассмотрели хранилище vuex, вспомогательные функции в хранилище и, наконец, то, как взаимодействовать между хранилищем и компонентами и использовать единый управляемый источник данных для нашего приложения.