Offline функциональность становится критически важной для современных веб-приложений. Возможность работы приложения без подключения к интернету повышает удобство использования и надежность, особенно для пользователей мобильных устройств или нестабильного соединения. Vue.js предоставляет гибкие инструменты для реализации offline-first приложений, включая Service Worker, кеширование данных и локальное хранилище.
Service Worker — это скрипт, который браузер выполняет в фоновом режиме отдельно от веб-страницы. Он позволяет перехватывать сетевые запросы, кешировать ресурсы и синхронизировать данные в фоновом режиме.
Для интеграции Service Worker во Vue.js используется Vue CLI PWA Plugin. Установка и настройка:
vue add @vue/pwa
После установки создается файл service-worker.js,
который можно настроить под конкретные нужды приложения. Основные
возможности Service Worker:
Пример кеширования ресурсов:
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('my-app-cache').then((cache) => {
return cache.addAll([
'/',
'/index.html',
'/css/app.css',
'/js/app.js',
'/images/logo.png'
]);
})
);
});
При запросе ресурсов Service Worker может отдавать их из кеша:
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
Для хранения данных в офлайн-режиме удобно использовать IndexedDB или LocalStorage.
Пример работы с LocalStorage во Vue-компоненте:
export default {
data() {
return {
tasks: []
};
},
created() {
const savedTasks = localStorage.getItem('tasks');
if (savedTasks) {
this.tasks = JSON.parse(savedTasks);
}
},
methods: {
addTask(task) {
this.tasks.push(task);
localStorage.setItem('tasks', JSON.stringify(this.tasks));
}
}
};
Для IndexedDB можно использовать библиотеку idb, упрощающую работу с асинхронными операциями:
import { openDB } from 'idb';
const dbPromise = openDB('tasks-db', 1, {
upgrade(db) {
db.createObjectStore('tasks', { keyPath: 'id', autoIncrement: true });
}
});
async function saveTask(task) {
const db = await dbPromise;
await db.add('tasks', task);
}
async function getTasks() {
const db = await dbPromise;
return await db.getAll('tasks');
}
Для офлайн-приложений важно сохранять ответы с сервера. Реализуется это через Service Worker или клиентские хранилища.
Пример с Service Worker:
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
event.respondWith(
caches.open('api-cache').then((cache) =>
fetch(event.request)
.then((response) => {
cache.put(event.request, response.clone());
return response;
})
.catch(() => caches.match(event.request))
)
);
}
});
Такой подход позволяет приложению работать с последними доступными данными даже без подключения к интернету.
Для управления состоянием Vue-приложения в офлайн важно предусмотреть:
Пример очереди синхронизации:
const offlineQueue = [];
function addToQueue(request) {
offlineQueue.push(request);
localStorage.setItem('offlineQueue', JSON.stringify(offlineQueue));
}
window.addEventListener('online', () => {
const queue = JSON.parse(localStorage.getItem('offlineQueue')) || [];
queue.forEach(async (req) => {
await fetch(req.url, req.options);
});
localStorage.removeItem('offlineQueue');
});
При использовании Vuex для управления состоянием офлайн-функциональность расширяется. Состояние можно сохранять в LocalStorage или IndexedDB при каждом изменении:
import createPersistedState from 'vuex-persistedstate';
export default new Vuex.Store({
state: {
tasks: []
},
mutations: {
addTask(state, task) {
state.tasks.push(task);
}
},
plugins: [createPersistedState({
storage: window.localStorage
})]
});
Это обеспечивает сохранение состояния приложения при перезагрузке или отсутствии сети.
Offline функциональность во Vue.js строится на трех ключевых принципах: кеширование ресурсов и данных, работа с локальными хранилищами и синхронизация состояния при восстановлении сети. Комбинирование Service Worker, IndexedDB и Vuex позволяет создавать приложения, которые остаются полностью функциональными без постоянного подключения к интернету.