предисловие
При использовании vue для разработки проектов мы часто используем vuex для управления глобальным состоянием для достижения цели глобального обмена данными, но одним из недостатков использования vuex является то, что данные исчезают после обновления страницы, в результате чего на странице отображаются исключения или запросы. интерфейсы Например, после того, как пользователь успешно войдет в систему, мы получим токен пользователя или uid и другую информацию из фона, потому что большинство интерфейсов требуют передачи токена пользователя в фон для обработки аутентификации, потому что пользователь обновляет страница неуправляема. На данный момент нам нужно объединить локальное хранилище для обеспечения хранения данных.
1. Вручную используйте API локального хранилища HTML5
Первой реакцией на хранение данных является сохранение общих методов хранения, таких как localStorage, sessionStorage и файлы cookie, во внешней разработке. Метод конкретного использования заключается в выполнении соответствующих дополнений, удалений и изменений в хранилище при работе с состоянием данных. это должно быть сохранено в методе, определенном мутациями.Проверьте операцию.
const state = () => {
return {
token: ''
}
}
const actions = {
async login ({ commit }, param) {
// 在这里获取用户的登录信息,返回值包含token,uid等信息
const userInfo = await userService.login(param)
commit('setUser', userInfo)
return userInfo
}
}
const mutations = {
setUser (state, data) {
state.token = data.token
// 在这里获取用户token, 同步存储数据
localStorage.setItem('user-token', data.token)
}
}
Таким образом, состояние будет существовать вместе с хранилищем и синхронизироваться с vuex, чтобы гарантировать, что данные не исчезнут после обновления пользователя, что подходит только для хранения и кэширования простых данных.
2. Используйте плагин createPersistedState для реализации хранилища данных
Суть плагина createPersistedState заключается в использовании одних и тех же нескольких распространенных методов хранения в веб-разработке, его особенность в том, что он объединяет методы хранения, а унифицированная конфигурация на входе не требует каждый раз вручную прописывать метод хранения.
инструкции
- локальная установка
npm install --save vuex-persistedstate
Вы также можете напрямую ссылаться на упакованный файл js.
<script src="https://unpkg.com/vuex-persistedstate/dist/vuex-persistedstate.js"></script>
Затем вы можете использоватьwindow.createPersistedState
чтобы получить объект. Рекомендуется использовать npm install напрямую для загрузки для локального использования.
2. Введите и настройте соответствующим образом запись в магазине в файле inde.js.
import createPersistedState from "vuex-persistedstate";
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
});
Использование модулей Vuex
Новые экземпляры плагинов можно создавать в отдельных файлах, но их необходимо импортировать и добавлять в объект плагинов в основном файле Vuex.
/* module.js */
export const dataStore = {
state: {
data: []
}
}
/* store.js */
import { dataStore } from './module'
const dataState = createPersistedState({
paths: ['data']
})
export new Vuex.Store({
modules: {
dataStore
},
plugins: [dataState]
})
Подключаемый модуль createPersistedState по умолчанию использует хранилище storage:localStorage, ключ имени ключа хранилища по умолчанию — «vuex» и предоставляет параметры параметров для изменения конфигурации по умолчанию и персонализированного хранилища.
option Общие элементы конфигурации
параметр | описывать |
---|---|
key | Клавиши хранимые данные. (По умолчанию: vuex) |
paths | Массив частичных путей, которые могут частично сохранять состояние. Если путь не указан, будет сохранено полное состояние. Если задан пустой массив, состояние не сохраняется. Пути должны быть указаны с использованием записи через точку. При использовании модуля укажите имя модуля (по умолчанию: []) |
reducer | Функция, которая будет вызываться на основе заданного пути, чтобы уменьшить постоянство состояния. |
storage | Указывает, как хранятся данные. По умолчанию используется localStorage, вы также можете установить sessionStorage |
getState | Функция, используемая для пополнения предыдущего постоянного состояния, использование по умолчанию: хранилище определяет способ получения |
setState | Функция для хранения заданного состояния. Использование по умолчанию: метод установки значения, определяемый хранилищем |
filter | Функция, которая будет вызываться для фильтрации setState, которая в конечном итоге будет фильтроваться в хранилище. По умолчанию () => истина. |
Чтобы использовать хранилище для sessionStorage, вам нужно всего лишь изменить конфигурацию хранилища следующим образом:
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
Конфигурация, которая хочет использовать хранилище для файлов cookie, выглядит следующим образом:
Поскольку использование файлов cookie для управления данными отличается от использования методов getItem, setItem и removeItem для управления такими данными, как localStorage, нам необходимо настроить соответствующие методы следующим образом:
mport { Store } from "vuex"
import createPersistedState from "vuex-persistedstate"
import * as Cookies from "js-cookie"
// 使用js-cookie来简化cookie操作
const store = new Store({
// ...
plugins: [
createPersistedState({
storage: {
getItem: (key) => Cookies.get(key),
setItem: (key, value) =>
Cookies.set(key, value, { expires: 3, secure: true }),
removeItem: (key) => Cookies.remove(key)
}
})
]
})
Поскольку хранилище здесь переписано, если вам нужно использовать локальное хранилище, но при этом необходимо защитить содержимое данных, вы можете зашифровать его.
import { Store } from "vuex";
import createPersistedState from "vuex-persistedstate";
import SecureLS from "secure-ls";
var ls = new SecureLS({ isCompression: false });
// secure-ls 通过高级别的加密和数据压缩来保护localStorage数据 https://github.com/softvar/secure-ls
const store = new Store({
// ...
plugins: [
createPersistedState({
storage: {
getItem: (key) => ls.get(key),
setItem: (key, value) => ls.set(key, value),
removeItem: (key) => ls.remove(key)
}
})
]
})
Кэшировать состояние указанного модуля в нескольких модулях Vuex, что достигается путем изменения конфигурации пути.
/* user-module */
export const user = {
state: {
token: '',
role: ''
}
}
/* profile-module */
export const profile = {
state: {
name: '',
company: ''
}
}
/* modules目录下的index.js */
import user from './user'
import profile from './profile'
export default {
user,
profile
}
/* store.js */
import modules from './modules'
let store = new Vuex.Store({
modules,
plugins: [
createPersistedState({
key: 'zdao',
paths: ['user'] // 这里便只会缓存user下的state值
})
]
})
Кэшировать часть данных, указанных под состоянием, конфигурация следующая
const state = () => {
return {
token: '',
uid: ''
}
}
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的token,而不会缓存uid
token: val.token
}
}
})]
Если путь используется, а редуктор существует, мерцают пути к свойствам.
plugins: [createPersistedState({
storage: window.sessionStorage,
paths: ['user'],
reducer(val) {
console.log(val) // { user: {token: '123', uid: '456'}, profile: {name: 'zdao', company: '上海合合信息股份有限公司'}}
return {
company: val.profile.company
}
}
})]
Используйте свойство filter, чтобы отфильтровать различные отправки изменений, которые вызывают нежелательные обновления данных в кэше.
Мы используем setUserA и setUserB для одновременного изменения состояния токена, но наша модификация при срабатывании setUserB не должна влиять на сохраненное значение токена, мы можем установить фильтр для фильтрации мутации
/* user-module */
const mutations = {
setUserA (state, data) {
state.token = data.token
},
setUserB (state, data) {
state.token = data.token
}
}
/* store.js */
plugins: [
createPersistedState({
key: 'zdao',
paths: ['user'],
filter: (mutation) => {
console.log(mutation)
/* mutation
{
payload: { token: "5491CC8FBB36408C9R7167yY"}
type: "user/setUserA"
}
*/
// 这个时候触发setUserB则不会触发影响缓存的值
return mutation.type.indexOf('user/setUserA') !== -1
}
})
]