Цель этого руководства - познакомить вас с vue.js ❤.
Этот контент изначально был написан для воркшопа для DAMDigital London.
Vue.js - это прогрессивный фреймворк для создания пользовательских интерфейсов (UI).
В этом руководстве предполагается, что у вас уже есть некоторые промежуточные знания о HTML, CSS и Javascript. Если у вас нет никаких знаний в этих областях, посетите freeCodeCamp, у них есть отличные ресурсы для изучения этих тем 😉.
Вот темы, которые будут рассмотрены в этом руководстве:
- директива v-bind
- Привязки классов и стилей
- Обработка событий
- Связывание данных в атрибутах
- Отображение списка
- Интерполяции - Усы
- Привязки ввода формы - флажок
- v-модель
- Методы
- Условный рендеринг
- v-if
- v-еще
- Введение в PWA
Мы собираемся создать приложение для задач с возможностью иметь несколько списков задач.
Начиная
Клонируйте стартовые материалы с гитхаба. Он включает в себя базовый HTML, CSS и JS.
Вы можете найти окончательный код этого руководства на github, а демо - по этой ссылке.
Vue CDN уже включен в наш index.html, а также в наш CSS и content / js / app.js 😃.
Переключить навигацию на мобильном телефоне
Во-первых, боковая навигация на мобильном устройстве (‹850px) должна отображаться и скрываться.
Когда мы нажимаем Меню, мы хотим, чтобы <nav>
переключал класс .is-open
.
В vue.js v-bind
позволяет нам связывать данные внутри атрибута html. Например. v-bind:id=""
, v-bind:style=""
, v-bind:data-target=""
и т. Д. Сокращение для v-bind
- :
.
В index.html
мы будем динамически передавать .is-open
, используя v-bind:class
. Если isNavOpen
истинно, то мы добавим наш класс.
<nav v-bind:class="{'is-open': isNavOpen}">
<!-- ... -->
</nav>
В content/js/app.js
нам нужно isNavOpen
в наших данных. Если вы измените значение последнего на true, появится навигационная система.
Свойство data в vue.js - это место, где мы храним данные нашего приложения, а также состояние нашего пользовательского интерфейса. Например, для isNavOpen
по умолчанию установлено значение false, но, изменив его значение на true, мы можем привязать класс is-open к DOM.
В нашем app.js нам нужно добавить isNavOpen: false
.
var app = new Vue({
el: "#app",
data: {
isNavOpen: false
}
});
Теперь мы хотим изменить значение isNavOpen
, когда мы нажимаем кнопку Меню.
Мы собираемся использовать обработчик событий «по клику». В vue.js мы можем использовать v-on:
или @
(сокращенно) для прослушивания событий DOM. В нашем случае мы хотим прослушивать событие щелчка. Затем мы будем использовать _22 _ / _ 23_.
<button v-on:click="isNavOpen = !isNavOpen" class="menu">Menu</button>
Как видите, мы можем передать встроенный оператор javascript, мы также можем использовать метод (функцию), мы увидим позже в этом руководстве, как использовать этот последний.
Ссылки на документацию
Привяжите наши списки дел к боковой навигации
В content/js/app.js
давайте добавим несколько фиктивных списков, чтобы мы могли начать интегрировать нашу боковую навигацию.
var app = new Vue({
el: "#app",
data: {
isNavOpen: false,
todoLists: [
{
title: "✈️ Trip to japan",
keyword: "japan",
items: [
{ name: "Eat ramen", isCompleted: true },
{ name: "Visit mt Fuji", isCompleted: false },
{ name: "Learn japanese", isCompleted: false }
]
},
{
title: "🏂 Ski trip to the Alps",
keyword: "Alps",
items: [
{ name: "Find a chalet", isCompleted: true },
{ name: "Learn how to ski", isCompleted: false }
]
},
{
title: "🍉 Groceries",
keyword: "Food",
items: [
{ name: "Apples", isCompleted: false },
{ name: "Banana", isCompleted: true },
{ name: "Tomatoes", isCompleted: false },
{ name: "Bread", isCompleted: true }
]
}
]
}
});
Чтобы отображать наши списки в боковой навигации, нам нужно использовать директиву v-for
.
<nav v-bind:class="{'is-open': isNavOpen}">
<ul>
<li v-for="todoList in todoLists">
<button>
{{todoList.title}}
<span>
{{todoList.items.length}}
</span>
</button>
</li>
<li>
<button class="is-add">Create a new list</button>
</li>
</ul>
</nav>
todoLists
- исходные данные, а todoList
- псевдоним, используемый для итерации в нашем массиве.
Мы используем синтаксис «усы» {{}}
для привязки нашего текста к представлению. Тег усов заменяется целевым значением в todoLists
.
Ссылки на документацию
Основной раздел
Заголовок
Мы хотим видеть наши задачи в основном разделе. Пока мы будем отображать только первый список todoLists
(индекс 0).
В content/js/app.js
= ›data
добавьте currentListIndex: 0
.
var app = new Vue({
el: "#app",
data: {
isNavOpen: false,
currentListIndex: 0,
todoLists: [
//...
]
}
});
Свяжите заголовок списка, используя синтаксис усов в заголовке.
<h1>{{todoLists[currentListIndex].title}}</h1>
В заголовке есть фоновое изображение. Мы используем Unsplash Source для получения случайного изображения. Мы можем указать ключевое слово, чтобы получить релевантное изображение для нашего заголовка.
https://source.unsplash.com/featured/?{KEYWORD},{KEYWORD}
Когда мы связываем наше ключевое слово внутри атрибута, мы используем v-bind
:
<header v-bind:style="'background-image: url(https://source.unsplash.com/featured/?' + todoLists[currentListIndex].keyword + ')'">
<!-- ... -->
</header>
Todos
Чтобы отобразить наши задачи в основном разделе, нам нужно будет использовать v-for
. Поскольку нам нужен индивидуальный идентификатор и имена для каждого ввода, мы передаем индекс в наш цикл for v-for="(value, index) in object"
.
Мы используем v-bind
, чтобы проверять / отмечать входные данные наших задач, если они уже отмечены.
Мы используем v-model
для обновления значения isCompleted
из наших задач, когда мы устанавливаем флажок. Когда наш флажок установлен, isCompleted получит значение true, а родительский li
автоматически получит класс .is-completed
, поскольку isCompleted равен true
.
Директива v-model
создает двустороннюю привязку данных, то есть при обновлении значения обновляется и пользовательский интерфейс.
<ul>
<li v-for="(todo, index) in todoLists[currentListIndex].items" v-bind:class="{'is-completed': todo.isCompleted}">
<label v-bind:for="'todo' + index">
<input
type="checkbox"
v-bind:name="'todo' + index"
v-bind:id="'todo' + index"
v-bind:checked="todo.isCompleted"
v-model="todo.isCompleted">
{{todo.name}}
</label>
<button class="is-danger">Edit todo</button>
</li>
<li>
<button class="is-add">New Todo</button>
</li>
</ul>
Ссылки на документацию
Изменить текущий список
Мы хотим иметь возможность изменять текущий отображаемый список. Этот параметр установлен currentListIndex
в данных нашего приложения. Когда мы щелкаем по одному из элементов списка, мы хотим изменить currentListIndex
на индекс этого элемента и закрыть боковую навигацию, если она открыта.
Нам также нужно, чтобы показать пользователю текущий отображаемый список, для этого мы добавляем класс .is-active
, если currentListIndex === index
.
<li v-for="(todoList, index) in todoLists" v-bind:class="{'is-active' : currentListIndex === index}">
<button v-on:click="currentListIndex = index; isNavOpen = false">
{{todoList.title}}
<span>
{{todoList.items.length}}
</span>
</button>
</li>
Создать новый список
Переключить боковую панель
При нажатии на Создать новый список отображается .sidebar
. Для этого мы хотим добавить к этому класс .is-open
, а затем закрыть панель навигации, если она открыта на мобильном устройстве. Это очень похоже на то, что мы сделали с навигацией на мобильных устройствах.
В наши данные мы сначала добавим новую запись isSidebarOpen: false
:
var app = new Vue({
el: "#app",
data: {
isNavOpen: false,
isSidebarOpen: false,
currentListIndex: 0
//...
}
});
Теперь давайте свяжем наш класс .is-open
с нашим .sidebar
:
<div class="sidebar" v-bind:class="{'is-open' : isSidebarOpen}">
<!-- ... -->
</div>
Нам нужно добавить обработчик событий при нажатии на Создать новый список, который откроет боковую панель и закроет навигацию на мобильном устройстве:
<button class="is-add" v-on:click="isSidebarOpen = true; isNavOpen = false;">Create a new list</button>
Отлично, теперь мы можем открыть нашу боковую панель 🎉.
Теперь закроем боковую панель, когда нажмем отменить:
<button type="button" class="is-danger" v-on:click="isSidebarOpen = false">Cancel</button>
Добавить новый список
Чтобы создать новый список, нам нужны значения полей ввода title и keyword. Когда пользователь нажимает Создать список, мы помещаем наши новые значения в todoLists
в наших данных. Если один из наших входных данных пуст, мы покажем значение по умолчанию.
В наш app.js добавьте массив tempNewList
, он будет хранить значения наших входных данных.
var app = new Vue({
el: "#app",
data: {
isNavOpen: false,
isSidebarOpen: false,
currentListIndex: 0,
tempNewList: [
{
title: null,
keyword: null
}
]
//...
}
});
Теперь мы свяжем наши входы с помощью v-model
.
<form>
<h3>Create a new list</h3>
<label for="listTitle">Title:</label>
<input id="listTitle" name="listTitle" type="text" placeholder="My amazing next trip to south america" v-model="tempNewList.title">
<label for="listKeyword">Keyword:</label>
<input id="listKeyword" name="listKeyword" type="text" placeholder="Colombia" v-model="tempNewList.keyword">
<div class="buttons">
<button type="button" class="is-danger" v-on:click="isSidebarOpen = false">Cancel</button>
<button type="button" class="is-confirm">Create List</button>
</div>
</form>
Хорошо, теперь давайте переместим наши новые tempNewList
значения на todoLists
.
Создайте метод с именем addNewList
. Метод - это функция, хранящаяся как свойство объекта. Здесь объект - это экземпляр vue. В vue наш метод будет храниться в объекте methods
.
addNewList
будет следовать этому сценарию:
- Если title пуст, используйте строку по умолчанию
"🕵️ List with no name"
- Если ключевое слово пусто, используйте строку по умолчанию
"earth"
- Переместите наши ценности на
todoLists
- Измените наш текущий список на наш новый список
- Закройте боковую панель
- Сбросьте значения наших входов
var app = new Vue({
el: "#app",
data: {
//...
},
methods: {
addNewList: function() {
var listTitle = this.tempNewList.title;
var listKeyword = this.tempNewList.keyword;
if (listTitle == null) {
listTitle = "🕵️ List with no name";
}
if (listKeyword == null) {
listKeyword = "earth";
}
this.todoLists.push({
title: listTitle,
keyword: listKeyword,
items: []
});
this.currentListIndex = this.todoLists.length - 1;
this.isSidebarOpen = false;
this.tempNewList.title = null;
this.tempNewList.keyword = null;
}
}
});
Наконец, мы собираемся привязать наш метод к нашей кнопке Создать список.
<button type="button" class="is-confirm" v-on:click="addNewList">Create List</button>
Ссылки на документацию
Редактировать список
Хорошо, теперь, когда мы можем создать новый список, нам нужна возможность редактировать существующие. Мы сможем редактировать заголовок, ключевое слово и удалить список.
Переключить содержимое боковой панели
Создайте новый метод openSidebar
. Этот будет:
- Откройте боковую панель
- Покажем форму, которую мы хотим использовать
- Закройте навигацию, если она открыта
В данных давайте добавим sidebarContentToShow: null
. Это позволит нам узнать, какая форма должна отображаться.
var app = new Vue({
el: "#app",
data: {
isNavOpen: false,
isSidebarOpen: false,
sidebarContentToShow: null,
currentListIndex: 0
//...
},
methods: {
//...
}
});
У нас есть 4 формы на боковой панели, которые мы будем переключать:
"createNewList"
"editList"
"createNewTodo"
"editTodo"
В нашем HTML мы будем условно отображать наши формы в зависимости от значения sidebarContentToShow
. Для этого мы используем директиву v-if
. Это позволит нам отобразить наш блок, если условие истинно. Нам нужно раскомментировать наши формы и добавить директиву v-if
.
<div class="sidebar" v-bind:class="{'is-open' : isSidebarOpen}">
<div class="sidebar-content">
<form v-if="sidebarContentToShow === 'createNewList'">
<h3>Create a new list</h3>
<!-- ... -->
</form>
<form v-if="sidebarContentToShow === 'editList'">
<h3>Edit list</h3>
<!-- ... -->
</form>
<form v-if="sidebarContentToShow === 'createNewTodo'">
<h3>Create a new todo</h3>
<!-- ... -->
</form>
<form v-if="sidebarContentToShow === 'editTodo'">
<h3>Edit todo</h3>
<!-- ... -->
</form>
</div>
</div>
Теперь, когда мы нажимаем на Создать новый список, появляется боковая панель и мы видим… Ничего 😱. Это нормально, помните, sidebarContentToShow
имеет значение null 😉.
Чтобы изменить значение sidebarContentToShow
, мы собираемся создать openSidebar
метод, который откроет боковую панель и изменит форму, которую мы хотим показать.
var app = new Vue({
el: "#app",
data: {
//...
},
methods: {
openSidebar: function(contentToShow) {
this.isSidebarOpen = true;
this.isNavOpen = false;
this.sidebarContentToShow = contentToShow;
}
//...
}
});
Теперь мы можем изменить Создать новый список, чтобы использовать openSidebar
<button class="is-add" v-on:click="openSidebar('createNewList')">Create a new list</button>
И, та-да, мы сейчас визуализируем форму создания нового списка. Как вы, возможно, уже догадались, мы повторно воспользуемся нашим методом с кнопкой Изменить список.
<button class="is-primary" v-on:click="openSidebar('editList')">Edit list</button>
Удалить список
Начнем с кнопки удалить список. Создайте новый метод с именем deleteList
. Он удалит текущий отображаемый список и покажет первый.
//... deleteList: function() { this.todoLists.splice(this.currentListIndex, 1); this.currentListIndex = 0; this.isSidebarOpen = false; } //...
<button type="button" class="is-danger" v-on:click="deleteList">Delete list</button>
Теперь мы можем удалять списки, но если мы попытаемся удалить все списки, мы получим ошибку, и наше приложение перестанет работать.
[Vue warn]: Error in render: "TypeError: todoLists[currentListIndex] is undefined"
Как вы, возможно, догадались, у нас есть эта ошибка, потому что наш todoLists
пуст, и мы все еще пытаемся визуализировать некоторую часть нашего приложения, которая полагается на значения todoLists
. Мы будем использовать условный рендеринг v-if
и v-else
, чтобы исправить эту проблему, мы будем рендерить наш основной контент, только если todoLists.length > 0
. Более того, мы хотим, чтобы пользователь мог создать новый список, мы будем использовать v-else
, чтобы показать альтернативный основной контент, который поможет пользователю создать новый список.
<main v-if="todoLists.length > 0">
<!-- ... -->
</main>
<main v-else>
<header style="background-image: url(https://source.unsplash.com/featured/?cat">
<div class="header-content">
<h1>Please create a new list</h1>
<button class="is-add" v-on:click="openSidebar('createNewList')">Create a new list</button>
</div>
</header>
</main>
Измените заголовок и значение ключевого слова
Вернемся к нашей форме editList. Мы хотим:
- Свяжите наши входы с правым элементом
todoLists
, используяv-model
. - Когда мы нажимаем готово, мы хотим закрыть ползунок.
- Отображать эту форму нужно только в том случае, если
todoLists.length > 0
<form v-if="sidebarContentToShow === 'editList' && todoLists.length > 0">
<h3>Edit list</h3>
<label for="listTitle">Title:</label>
<input id="listTitle" name="listTitle" type="text" placeholder="My amazing next trip to south america" v-model="todoLists[currentListIndex].title">
<label for="listKeyword">Keyword:</label>
<input id="listKeyword" name="listKeyword" type="text" placeholder="Colombia" v-model="todoLists[currentListIndex].keyword">
<div class="buttons">
<button type="button" class="is-danger" v-on:click="deleteList">Delete list</button>
<button type="button" class="is-confirm" v-on:click="isSidebarOpen = false">Done</button>
</div>
</form>
Ссылки на документацию
Создать и отредактировать задачу
Пользовательский интерфейс нашего приложения почти готов, нам еще нужно:
- Создать новую задачу в списке
- Редактировать и удалять существующее задание
Звучит похоже на то, что мы сделали со списками, верно? Это будут почти те же шаги.
Создать задачу
В наших данных создайте новый элемент tempNewList
:
tempNewTodo: [
{
name: null,
isCompleted: false
}
],
Нам нужен новый метод, поэтому мы можем добавить нашу новую задачу в список в todoLists
addNewTodo: function() {
var todoName= this.tempNewTodo.name;
var todoCompleted = this.tempNewTodo.isCompleted;
if (todoName == null) {
todoName = "🕵️ unnamed todo";
}
this.todoLists[this.currentListIndex].items.push({
name: todoName,
isCompleted: todoCompleted
});
this.isSidebarOpen = false;
this.tempNewTodo.name = null;
this.tempNewTodo.isCompleted = false;
}
Теперь давайте углубимся в наш HTML.
Нам нужно открыть боковую панель с формой createNewTodo.
<button class="is-add" v-on:click="openSidebar('createNewTodo')">New Todo</button>
Как и раньше, мы свяжем наши входные данные с помощью v-model
и будем использовать метод addNewTodo
для передачи наших новых значений.
<form v-if="sidebarContentToShow === 'createNewTodo'">
<h3>Create a new todo</h3>
<label for="todoName">Name:</label>
<input id="todoName" name="todoName" type="text" placeholder="Do things..." v-model="tempNewTodo.name">
<label for="todoCompleted"><input name="todoCompleted" id="todoCompleted" type="checkbox" v-bind:checked="tempNewTodo.isCompleted" v-model="tempNewTodo.isCompleted"> Is completed</label>
<div class="buttons">
<button type="button" class="is-danger" v-on:click="isSidebarOpen = false">Cancel</button>
<button type="button" class="is-confirm" v-on:click="addNewTodo">Create todo</button>
</div>
</form>
Поскольку сейчас мы привязываем данные для isCompleted
в наших задачах, мы будем показывать в нашей навигации количество выполненных задач.
В нашем app.js создайте totalTodosCompleted
метод, передающий индекс текущего todoList.
totalTodosCompleted: function(i){
var total = 0;
for (var j = 0; j < this.todoLists[i].items.length; j++) {
if(this.todoLists[i].items[j].isCompleted){
total++;
}
}
return total;
}
А теперь в нашем navigation
мы собираемся использовать наш новый метод для возврата общего количества выполненных задач.
<li v-for="(todoList, index) in todoLists" v-bind:class="{'is-active' : currentListIndex === index}">
<button v-on:click="currentListIndex = index; isNavOpen = false">
{{todoList.title}}
<span>
{{totalTodosCompleted(index)}} / {{todoList.items.length}}
</span>
</button>
</li>
Редактировать задачу
Чтобы отредактировать задачу, во-первых, нам нужно знать индекс задачи, которая будет редактироваться, в наших данных create currentTodoIndex
.
currentTodoIndex: 0,
Нам понадобится deleteTodo
метод, который удалит текущее задание.
deleteTodo: function() {
this.todoLists[this.currentListIndex].items.splice(this.currentTodoIndex, 1);
this.isSidebarOpen = false;
this.currentTodoIndex = 0;
}
Теперь давайте посмотрим на наш HTML.
Во-первых, мы хотим открыть наш ползунок и изменить значение currentTodoIndex
.
<button class="is-primary" v-on:click="openSidebar('editTodo'); currentTodoIndex = index">Edit todo</button>
В нашей форме editTodo мы:
- Показывать нашу форму, только если
todoLists[currentListIndex].items.length > 0
- Свяжите имя задачи и, если завершено, используйте
v-model
- Когда мы нажимаем Удалить задачу, запускаем метод
deleteTodo
- Когда мы нажимаем Готово, закрываем боковую панель.
<form v-if="sidebarContentToShow === 'editTodo' && todoLists[currentListIndex].items.length > 0">
<h3>Edit todo</h3>
<label for="todoName">Todo:</label>
<input id="todoName" name="todoName" type="text" placeholder="Do things..." v-model="todoLists[currentListIndex].items[currentTodoIndex].name">
<label for="todoCompleted"><input name="todoCompleted" id="todoCompleted" type="checkbox" v-bind:checked="todoLists[currentListIndex].items[currentTodoIndex].isCompleted" v-model="todoLists[currentListIndex].items[currentTodoIndex].isCompleted"> Is completed</label>
<div class="buttons">
<button type="button" class="is-danger" v-on:click="deleteTodo">Delete todo</button>
<button type="button" class="is-confirm" v-on:click="isSidebarOpen = false">Done</button>
</div>
</form>
🎉🎉🎉🎉🎉 Пользовательский интерфейс нашего списка задач готов!
LocalStorage
Когда мы перезагружаем страницу, она возвращается к нашим фиктивным значениям. Насколько было бы здорово, если бы мы могли хранить наши списки и задачи локально?
Мы собираемся использовать window.localStorage. Это часть API веб-хранилища.
localStorage позволяет нам хранить данные без срока действия.
В нашем app.js создайте новый метод updateTodoLocalStorage
//...
updateTodoLocalStorage: function () {
localStorage.setItem('todoLocalStorage', JSON.stringify(this.todoLists));
}
//...
Мы используем метод setItem()
из API веб-хранилища. Передаем следующие параметры:
setItem(keyName, keyValue);
keyName
: имя ключа, который мы хотим создать / обновить ('todoLocalStorage'
).keyValue
: значение, которое мы хотим дать ключу, который вы создаете / обновляете (JSON.stringify(this.todoLists)
).
Теперь мы хотим использовать этот метод каждый раз, когда обновляем значения наших задач или списков. Vue позволяет нам реагировать на изменения данных с помощью опции watch
. Каждый раз, когда мы вносим изменения в наш todoLists
, мы будем вызывать наш updateTodoLocalStorage
метод. Поскольку у нашего объекта есть вложенные значения, мы хотим обнаруживать изменения внутри этих значений. Для этого мы можем передать deep: true
.
var app = new Vue({
el: "#app",
data: {
//...
},
watch: {
todoLists: {
handler() {
this.updateTodoLocalStorage();
},
deep: true
}
},
methods: {
//...
updateTodoLocalStorage: function() {
localStorage.setItem("todoLocalStorage", JSON.stringify(this.todoLists));
}
}
});
Теперь давайте проверим наше приложение и заглянем в Локальное хранилище. Если мы создадим / обновим список или задачу, мы увидим, что наше todoLocalStorage
хранилище обновляется.
Теперь, когда мы загружаем нашу страницу, нам нужно установить наш todoLists
как наш todoLocalStorage
. Vue поставляется с крючками жизненного цикла. Мы будем использовать created: function()
, чтобы установить наши значения. Мы также собираемся удалить наши фиктивные значения.
var app = new Vue({
el: "#app",
data: {
//...
todoLists: []
},
created: function() {
this.todoLists = JSON.parse(
localStorage.getItem("todoLocalStorage") || "[]"
);
},
watch: {
//...
},
methods: {
//...
}
});
Теперь, если мы перезагрузим, закроем и снова откроем наше приложение, все наши задачи и список будут сохранены 🤟.
Ссылки на документацию
- Наблюдатели
- "Созданный"
Бонус - автономное прогрессивное веб-приложение (PWA)
В этой бонусной части этого руководства мы настроим прогрессивное веб-приложение (PWA) и сервис-воркеров, чтобы мы могли использовать это веб-приложение в автономном режиме на смартфоне.
Настроить PWA
PWA - это:
Прогрессивные веб-приложения - это веб-приложения, которые представляют собой обычные веб-страницы или веб-сайты, но могут выглядеть для пользователя как традиционные или собственные мобильные приложения. Тип приложения пытается объединить функции, предлагаемые большинством современных браузеров, с преимуществами мобильного взаимодействия. википедия
По сути, это веб-приложение, которое использует преимущества новейших технологий для работы и ощущается как нативное приложение.
Чтобы настроить наш PWA, нам нужно будет создать manifest.json
файл и настроить наших сервис-воркеров.
PWA должен обслуживаться из безопасного источника (HTTPS).
Создание ресурсов значков
Во-первых, включите в наш проект все ресурсы значков. Иконки уже были созданы с использованием https://realfavicongenerator.net/. Они включены в content/img/
.
В заголовок нашего HTML мы хотим включить:
<link rel="apple-touch-icon" sizes="180x180" href="content/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="content/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="content/img/favicon-16x16.png">
<link rel="mask-icon" href="content/img/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="content/img/favicon.ico">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-config" content="content/img/browserconfig.xml">
<meta name="theme-color" content="#77c4d3">
Манифест веб-приложения
Манифест веб-приложения (manifest.json) - это файл, который предоставляет информацию о нашем веб-приложении, такую как значки, имя нашего приложения и т. Д. Он является частью технологий, используемых для PWA. Дополнительную информацию о манифесте веб-приложения можно найти в Веб-документации MDN.
Создайте этот файл в корне нашего проекта.
{
"name": "todo",
"short_name": "todo",
"author": "Vincent Humeau",
"lang": "en-GB",
"icons": [
{
"src": "content/img/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "content/img/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#77c4d3",
"background_color": "#77c4d3",
"display": "standalone",
"orientation": "portrait",
"scope": "/todo/",
"start_url": "/todo/"
}
Мы хотим включить его в наш HTML-файл.
<link rel="manifest" href="manifest.json">
Сервисные работники
Что такое сервис-работники?
Сервис-воркеры - это новая функция браузера, которая предоставляет сценарии, управляемые событиями, которые выполняются независимо от веб-страниц. В отличие от других воркеров, сервис-воркеры могут быть отключены в конце событий, обратите внимание на отсутствие сохраненных ссылок из документов, и у них есть доступ к общедоменным событиям, таким как выборка из сети. У сервис-воркеров также есть кеш-память с поддержкой сценариев. Наряду с возможностью отвечать на сетевые запросы с определенных веб-страниц с помощью сценария, это позволяет приложениям переходить в автономный режим. w3c / ServiceWorker - Github
Это руководство не ставит своей целью углубленное изучение обслуживающего персонала, вы можете найти отличное руководство и ресурсы в Интернете:
- Как настроить базового сервис-воркера (с кешированием) - bitsofcode (видео)
- Сервис-воркеры: введение
- Pwabuilder - работники сферы обслуживания
- Pwabuilder - работники сферы обслуживания
- "Маяк"
- Как заставить простой сайт работать в автономном режиме с помощью ServiceWorker
- Начало работы с обслуживающим персоналом
Для наших сервисных работников мы используем эту суть от Omranic.
Создайте файл sw.js
в корне нашего проекта.
В нашем index.html:
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('sw.js');
});
}
</script>
Затем в нашем sw.js мы кэшируем все наши ресурсы, которые позволят нашему приложению работать в автономном режиме:
var shellCacheName = "pwa-todo-v1";
var filesToCache = [
"./",
"./index.html",
"./content/css/screen.min.css",
"./content/js/app.js",
"https://cdn.jsdelivr.net/npm/vue",
"https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css"
];
Теперь нам нужно только следовать этой сути и добавить части Слушать установочное событие, Обновить кэш активов и Обслуживать оболочку приложения в автономном режиме из кеша.
Это руководство, наконец, готово. Теперь наш todo vue.js PWA доступен здесь https://vinceumo.github.io/todo