Для каждого одностраничного приложения должно быть хранилище для оптимального обмена данными между компонентами. Для 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) }
Наконец, давайте еще раз повторим шаги
- Инициализировать хранилище с соответствующими геттерами, мутациями и состоянием
- При загрузке компонента вызовите API, в случае успеха сохраните данные в нашем хранилище vuex, передав данные в функцию мутации. Используйте mapMutations для вызова функции мутации из компонента.
- Где необходимо, используйте геттеры.
- Реализуйте то же самое для функций ДОБАВЛЕНИЯ и УДАЛЕНИЯ.
- Привяжите переменные хранилища к компонентам с помощью mapState.
Снимок экрана
Полный пример можно найти здесь
https://github.com/ubercooluk/vuex-example
просто клонируйте репо. Тогда все, что вам нужно сделать, это
yarn install yarn serve
Заключение
Мы рассмотрели хранилище vuex, вспомогательные функции в хранилище и, наконец, то, как взаимодействовать между хранилищем и компонентами и использовать единый управляемый источник данных для нашего приложения.