Используйте Vue.js, Firebase's Cloud Firestore и Vuefire для создания полнофункционального приложения.

Часть 1 (эта статья)

"Часть 2"

Это первая из 2 частей, посвященных созданию полнофункционального приложения с использованием Vue.js, Firebase's Cloud Firestore и Vuefire. Мы рассмотрим основные требования для приложения CRUD со списком задач (создание, чтение, обновление, удаление). К концу у вас будет приложение с постоянным хранилищем данных, а также лучшее понимание технологий Vue и Firebase.

Я не буду вдаваться в подробности об основах Vue в этой серии, поэтому, если вы новичок в этом, я рекомендую сначала проверить мою другую серию Учебников по Интернет-магазину!

Шаг 1. Настройка проекта

Мы будем использовать Vue CLI для запуска нашего проекта, для которого требуется Node.js версии 8.9 или выше (рекомендуется 8.11.0+). Убедитесь, что у вас есть Node, выполнив следующую команду в своем терминале:

node -v

Если вы получили что-то большее или равное v8.11.0, тогда все готово. В противном случае щелкните ссылку выше, чтобы загрузить и установить версию, подходящую для вашего компьютера.

Затем установите Vue CLI с помощью:

npm install vue-cli -g

Создайте новый проект с именем v-fire с простым шаблоном webpack, используя

vue init webpack-simple v-fire

Завершите шаги настройки проекта, задав имя проекта, описание, автора и параметры sass:

? Project name v-fire
? Project description A CRUD application using Vue and Firebase
? Author Nathan Magyar <[email protected]>
? License MIT
? Use sass? Y

Проект был успешно создан, если вы получили:

    vue-cli · Generated "v-fire".
    To get started:
        cd v-fire
        npm install
        npm run dev

cd в каталог v-fire и установите необходимые зависимости, которые Vue CLI автоматически объявляет для нас:

cd v-fire
npm install

Теперь в том же каталоге установим Firebase и VueFire через npm. Firebase будет служить базой данных для нашего проекта, а VueFire дает нам простой способ связи между этой базой данных и нашим приложением Vue:

npm install firebase vuefire

Запустите сервер разработки, чтобы убедиться, что ваш проект был успешно создан, затем посетите localhost: 8080 / в своем браузере:

npm run dev

В редакторе кода откройте App.vue, который находится в v-fire/src. Удалите все содержимое шаблона, кроме самого внешнего div.

<template>
  <div id="app">
  </div>
</template>
<script>
  export default {
    name: 'app',
    data () {
      return {
        msg: 'Welcome to Your Vue.js App'
      }
    }
  }
</script>
<style>
...
</style>

Шаг 1.2: настройте Firebase

В браузере зайдите в Firebase и войдите в свою учетную запись Google (при необходимости создайте учетную запись Google). Нажмите кнопку Перейти в консоль.

Нажмите «Добавить проект», введите имя проекта, примите условия и положения, затем нажмите «Создать проект». Когда ваш проект будет готов, нажмите «Продолжить», чтобы перейти на панель управления проектом.

Получите доступ к необходимым ключам проекта Firebase. Мы создаем веб-приложение, поэтому мы нажмем значок </> на странице панели инструментов проекта:

Скопируйте все внутри объекта, хранящегося в config:

apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
databaseURL: "YOUR_DATABASE_URL",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGE_SENDER_ID"

Мы используем приведенное выше содержимое для подключения нашего приложения к Firebase. Чтобы это произошло, создайте в src новый файл с именем firebase.js и добавьте следующий оператор импорта и константу:

// firebase.js
import { initializeApp } from 'firebase';
const app = initializeApp({
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  databaseURL: "YOUR_DATABASE_URL",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGE_SENDER_ID"
});

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

Чтобы облегчить себе доступ к нашей базе данных (db) и нашим задачам (todosCollection) в будущем, давайте добавим несколько экспортированных констант под функцией initializeApp:

export const db = app.firestore();
export const todosCollection = db.collection('todos');

В Firebase наши данные хранятся следующим образом. На верхнем уровне находятся «коллекции», для которых мы можем указать имена, например todos. Внутри каждой коллекции есть «документы», которые для нас являются отдельными задачами. Мы также можем назвать эти документы или позволить Firebase сгенерировать случайный id и установить его в качестве имени. Внутри каждого документа есть поля, которые мы указываем, например статус text или completed задачи. Интересный факт: не все документы в одной коллекции должны иметь одинаковые поля.

Затем убедитесь, что наше приложение Firebase инициализировано, импортировав указанный выше файл в main.js:

import './firebase'
import Vue from 'vue'
import App from './App.vue'
import VueFire from 'vuefire'
Vue.use(VueFire);
new Vue({
  el: '#app',
  render: h => h(App)
})

Выше мы также импортируем плагин VueFire и устанавливаем его методом Vue.use().

Шаг 2. Функциональность «Добавить новое задание»

В App.vue обновите шаблон, включив в него элемент form, который состоит из текстового поля input, заключенного в label:

Выше мы также использовали директиву v-model для подключения поля ввода к нашему компоненту и модификатор prevent в обработчике нажатия кнопки, чтобы остановить перезагрузку страницы, когда пользователь добавляет новую задачу. Вы также заметите addTodo() метод, который мы скоро напишем, чтобы обрабатывать добавление задачи в нашу базу данных.

Теперь напишите метод addTodo() в разделе methods в App.js:

Начнем с импорта нашей todosCollection экспортированной константы из firebase.js в верхней части раздела script. Внутри addTodo() мы используем метод add, чтобы добавить новый объект todo в эту коллекцию. Новое задание состоит из свойств text, completed и createdAt. Свойство text - это то место, где мы добавляем наше свойство данных newTodo. Все новые задачи по умолчанию будут неполными, поэтому для completed установлено значение false. Для createdAt мы используем новый экземпляр объекта Javascript Date для записи времени отправки задачи. Для начала обработки любых ошибок мы добавляем предложения then и catch. Если добавление прошло успешно, в консоли появится сообщение Document written with ID: blahBlah1234. Если нет, мы получим другое сообщение. Наконец, после всего этого сбросьте свойство данных newTodo на пустую строку, чтобы текст последнего задания не сохранялся после отправки.

Затем убедитесь, что у вас есть база данных, в которую можно писать и читать. Перейдите в панель управления базой данных проекта Firebase и нажмите «Создать новую базу данных», выберите «тестовый режим» для целей разработки (то есть нам пока не нужно иметь дело с аутентификацией) и нажмите «Создать».

Примечание. Тестовый режим следует использовать только в целях разработки. В производственных приложениях не должно быть таких гибких правил чтения и записи.

Теперь, если вы протестируете это в своем браузере, а затем перейдете к представлению базы данных в Firebase (возможно, вам придется обновить страницу), вы увидите новую коллекцию todos, новый документ с некоторым случайным ключом / именем, а затем наш новый контент в правом столбце. Милая!

Теперь давайте перейдем к отображению наших задач на странице. Чтобы запросить нашу базу данных Firestore, мы воспользуемся методом firestore(), который возвращает объект данных. Внутри этого объекта находится ключ, равный имени нашей коллекции, в данном случае todos. Он вернет константу todosCollection, которую мы импортировали в верхней части раздела script. Наши запросы будут упорядочены по последнему добавленному к самому старому с использованием метода orderBy, который получает строку createdAt и параметр desc (для «по убыванию»).

Затем мы должны добавить свойство данных todos в самом компоненте, которое Firestore заполнит данными. И, наконец, в метод addTodo() добавьте один новый ключ, id, чтобы помочь нам, когда мы будем перебирать задачи в будущем. Для каждого id на данный момент будет установлена ​​длина this.todos.

Чтобы отобразить todos, обновите шаблон, включив ul и li для каждого todo, который отображает text каждого todo:

Шаг 3. Отметьте элементы списка дел

Теперь давайте добавим функциональность, позволяющую пользователям отмечать какой-то элемент списка дел. Начните с обновления шаблона. Внутри li для каждого элемента добавьте элемент label, заключающий checkbox input и текст задачи:

...
<ul>
  <li v-for="todo in todos" :key="todo.id">
    <label>
    <input
      type="checkbox">
        {{todo.text}}
    </label>
  </li>
</ul>
...

На checkbox input добавьте еще два атрибута, v-model и @change. v-model будет связывать флажок с атрибутом completed данного элемента задачи, а @change будет запускать метод с именем updateTodo() всякий раз, когда пользователь проверяет или снимает отметку с элемента (при условии, что мы передаем todo в качестве аргумента):

...
<ul>
  <li v-for="todo in todos" :key="todo.id">
    <label>
    <input
      type="checkbox"
      v-model="todo.completed"
      @change="updateTodo(todo)">
        {{todo.text}}
    </label>
  </li>
</ul>
...

Теперь напишите метод updateTodo(). Он будет работать аналогично addTodo().

updateTodo(todo) {
  todosCollection.doc(todo.id).update({...todo})
  .then(function(docRef) {
    console.log("Updated document with ID: ", todo.id);
  })
  .catch(function(error) {
    console.error("Error updating document: ", error);
  });
}

Несмотря на то, что мы не добавляли / не создавали его явно, каждому todo документу Firestore присваивает id, к которому можно получить доступ, написав todo.id. Вот как мы сообщаем Firestore, какой документ обновлять. На todosCollection мы вызываем метод doc() и передаем этот идентификатор. Затем Firestore находит нужный нам документ и позволяет нам вызвать update(), метод, который мы используем для изменения части существующей записи. Хотя мы могли бы просто передать только ключ и значение для свойства todo completed, я использую оператор распространения (...) для передачи всего содержимого, потому что в будущем мы могли бы использовать этот же метод для обновления текста todo. Остальная часть метода делает то же самое с подтверждением успеха / сообщением об ошибке в консоли.

Теперь, когда вы проверяете checkbox input на экране, а затем обновляете страницу базы данных в Firebase, вы должны увидеть, что значение соответствующего todo элемента completed изменилось соответствующим образом.

Шаг 4. Сделайте это красивым

Наконец, добавьте несколько классов в элементы шаблона и соответствующие правила CSS, чтобы сделать страницу немного лучше:

Следующие шаги

Теперь мы можем создавать, читать и (вроде) обновлять задачи. Во второй части мы будем работать над обновлением текста и удалением задач. 👋