Самоучитель №4 от JL

Серия [Истории самообучения JL]

[Net Ninja] JS Regular Expressions
[Net Ninja] Vue JS2 (Part1, Part2, Part3(current))
[Net Ninja] Vuex
[Net Ninja] Python3 (Part1, Part2, Part3)
[Net Ninja] Django (Part1, Part2, Part3)
[Net Ninja] Sass (Part1, Part2)
[Sean Larkin] Webpack4 (Part1)

🌲 Это последняя часть моего резюме Учебника Vue JS от Net Ninja на YouTube.

31) HTTP Requests
32) GET Requests
33) Custom Directives
34) Filters
35) Custom Search Filter
36) Registering Things Locally
37) Mixins
38) Setting Up Routing
39) Routing : Hash vs History
40) Adding Router Links
41) Route Parameters
42) Posting to Firebase
43) Retrieving Posts from Firebase

Если вы не настроили сервер разработки для Vue, обратитесь к главе 16) Vue CLI в предыдущем сообщении, чтобы получить подробную информацию о запуске сервера разработки с использованием Vue CLI3.

Если вы уже это сделали, просто введите npm run dev в терминале Mac OS и командной строке Windows, чтобы запустить сервер разработки.

31) HTTP-запросы (YouTube)

Чтобы хранить данные в базе данных, нам нужно сделатьHypertext Transfer Protocol (HTTP) запросов.

  1. v-if='!submitted' используется для скрытия формы после нажатия кнопки «Добавить блог».
  2. Используя v-if='submitted', отобразите «Спасибо за добавление сообщения!» сообщение.
  3. title: '', content: '' позволяет нам отображать заголовок и контент, вводимый пользователем.
[index.html]
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>vuejs-playist</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="/dist/build.js"></script>
  </body>
</html>
-----------------------------------
[src > main.js]
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
Vue.prototype.$http = axios;
new Vue({
  el: '#app',
  render: h => h(App)
});
-----------------------------------
[src > App.vue]
<template>
  <div>
    <add-blog></add-blog>
  </div>
</template>

<script>
import addBlog from './components/addBlog.vue';
export default{
  components{
    'add-blog': addBlog
  }
}
</script> 
-----------------------------------
[src > components > addBlog.vue]
<template>
  <div id='add-blog'>
    <h2>Add a New Blog Post</h2>
    <form v-if='!submitted'>
      <label>Blog Title: </label>
      <input type='text' v-model.lazy='blog.title' required />
      <label>Blog Content: </label>
      <textarea v-model.lazy='blog.content'></textarea>

      <div id='checkboxes'>
        <label>Ninjas</label>
        <input type='checkbox' value='ninjas' v-model='blog.categories'/>
        <label>Wizards</label>
        <input type='checkbox' value='wizards' v-model='blog.categories'/>
        <label>Mario</label>
        <input type='checkbox' value='mario' v-model='blog.categories'/>
        <label>Cheese</label>
        <input type='checkbox' value='cheese' v-model='blog.categories'/>
      </div>
      
      <label>Author: </label>
      <select v-model='blog.author'>
        <option v-for='author in authors' :key='author.id'>{{ author }}</option>
      </select>
      <button @click.prevent='post'>Add Blog</button>
    </form>
    <div v-if='submitted'>
      <h3>Thanks for adding your post</h3>
    </div>
<div id='preview'>
      <p>Blog Title: {{ blog.title }}</p>
      <p>Blog Content: </p>
      <p>{{ blog.content }}</p>
      <p>Blog Categories</p>
      <ul>
        <li v-for='category in blog.categories' :key='category.id'>{{ category }}</li>
      </ul>
      <p>Author: {{ blog.author }}</p>
    </div>
  </div>
</template>

<script>
export default{
  data(){
    return{
      blog:{
        title: '',
        content: '',
        categories: [],
        author: ''
      },
      authors: ['The Net Ninja', 'The Angular Avenger', 'The Vue Vindicator'],
      submitted: false
    }
  },
  methods:{
    post: function() {
      const axios = require('axios');
      axios.post('https://jsonplaceholder.typicode.com/posts', {
        title: this.blog.title,
        body: this.blog.content,
        userID: 1
      }).then(response => {
        console.log(response);
        this.submitted = true;
      });
    }
  }
}
</script>

В версии 2.2.0+ при использовании v-for с компонентом теперь требуется key (Официальный веб-сайт).

Если ключ не указан, появляется следующее сообщение об ошибке:

[eslint-plugin-vue] [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.

Доступно для просмотра полного кода с подсветкой синтаксиса на GitHubGist .

  • Net Ninja использовал JSON: Placeholder, поддельный онлайн-REST API для тестирования и создания прототипов.

RESTful API - это интерфейс прикладных программ (API), который использует запросы HTTP для данных GET, PUT, POST и DELETE. RESTful API, также называемый веб-сервисом RESTful, основан на технологии REpresentational State Transfer (REST), архитектурном стиле и подходе к коммуникациям, часто используемом при разработке веб-сервисов. (Маргарет Роуз)

3 ноября 2016 года Even You, создатель Vue.js, написал статью Прекращение использования vue-ресурса. В статье говорится: Как пользователи Vue, многие из вас, возможно, использовали « vue-resource для обработки запросов ajax в своих приложениях Vue. Долгое время она считалась официальной библиотекой ajax для Vue, но сегодня мы убираем ее из статуса официальной рекомендации »( блог ).

Итак, я решил использовать axios вместо vue-resource. Axios - это HTTP-клиент на основе обещаний для браузера и node.js (GitHub)

Поскольку Net Ninja использовал vue-resource в своем VueJS2 учебнике, я внес несколько изменений.

  1. Используйте import axios from ‘axios’ вместо import VueResource from 'vue-resource’ в файле main.js.
  2. Введите Vue.prototype.$http = axios вместо Vue.use(VueResource).
  3. Внутри post: function() включите const axios = require(‘axios').
  4. Введите axios.post вместо this.$http.post.
  5. response вместо data в then() method: объяснит причину в следующей главе.
  6. Используйте => вместо function().

Метод then() возвращает _29 _. (MDN)

32) GET запросы (YouTube)

Мы используем GET-запросы для получения данных. Пример объектов-примеров в JSON: Placeholder:

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

[src > app.vue]
<template>
  <div>
    <show-blogs></show-blogs>
  </div>
</template>

<script>
import showBlogs from './components/showBlogs.vue';

export default{
  components{
    'show-blogs': showBlogs
  }
}
</script>
-----------------------------------
[src > components > showBlogs.vue]
<template>
  <div id='show-blogs'>
    <h1>All Blog Articles</h1>
    <div v-for='blog in blogs' class='single-blog'>
      <h2>{{ blog.title }}</h2>
      <article>{{ blog.body }}</article>
    </div>
  </div>
</template>

<script>
export default{
  data(){
    blogs: []
  },
  created(){
    const axios = require('axios');
    
    axios.get('https://jsonplaceholder.typicode.com/posts')
    .then(response => {
      console.log(response);
      this.blogs = response.data.slice(0,10);
    });
  }
}
</script>

<style scoped>
#show-blogs{
  max-width: 800px;
  margin: 0 auto;
}
.single-blog{
  padding: 20px;
  margin: 20px 0;
  box-sizing: border-box;
  background: #eee;
}
</style>

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

Как я объяснил в предыдущей главе, я внес несколько изменений, потому что использовал axios вместо vue-resource. Причина пятого различия (использование response вместо data в then() method) заключается в следующем:

[Код Net Ninja]

.then(function(data) {
  console.log(data);
  this.blogs = data.body.slice(0,10);

[Мой код]

.then(response => {
  console.log(response);
  this.blogs = response.data.slice(0,10);

›Чтобы получить доступ к примерам объектов, предоставляемых JSON Placeholder , мне нужно было использовать data вместо body. Итак, чтобы не путать с этим, я передал response вместо data.

33) Пользовательские директивы (YouTube)

  • Создал специальную директиву под названием «v-rainbow». Он генерирует случайный цвет для каждого заголовка.
  • Создана еще одна настраиваемая директива под названием «v-theme» для предоставления параметров: узкий и широкий.
  • Прикрепил аргумент под названием «столбец» к настраиваемой директиве v-theme, чтобы связать параметр фона
[src > components > showBlogs.vue]
<template>
  <div v-theme:column="'narrow'" id='show-blogs'>
    <h1>All Blog Articles</h1>
    <div v-for='blog in blogs' class='single-blog'>
      <h2 v-rainbow>{{ blog.title }}</h2>
      <article>{{ blog.body }}</article>
    </div>
  </div>
</template>

<script>
  // same as above
</script>

<style scoped>
/* same as above */
</style>
-----------------------------------
[src > main.js]
// same as above
Vue.directive('rainbow', {
  bind(el, binding, vnode){
    el.style.color = '#' + Math.random().toString().slice(2,8);
  }
});

Vue.directive('theme', {
  bind(el, binding, vnode){
    if(binding.value == 'wide'){
      el.style.maxWidth = '1200px';
    } else if(binding.value == 'narrow'){
      el.style.maxWidth = '600px';
    }
    
    if(binding.arg == 'column'){
      el.style.background = '#ddd';
      el.style.padding = '20px';
    }
  }
});
new Vue({
  // same as above
});

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

  1. В v-theme:column используются одинарные кавычки, чтобы заключить «узкий» в двойные кавычки. Без одинарных кавычек в консоли появляется следующее сообщение об ошибке: Свойство или метод «узкий» не определен в экземпляре, но на него ссылаются во время рендеринга. «Узкий» - это не свойство или метод. Это просто ценность. Чтобы указать, что это строка, нам нужно заключить слово в одинарные кавычки.
  2. Добавлен '#' перед функцией Math.random(), поскольку шестнадцатеричный цвет начинается с символа «#» (например, # 00fefe).
  3. Функция Math.random() возвращает псевдослучайное число с плавающей запятой в диапазоне 0–1 (включая 0, но не 1) с приблизительно равномерным распределением в этом диапазоне, которое затем можно масштабировать до желаемого диапазона (MDN ). Результатом console.log(Math.random()) будет 0.XXXXX… Следовательно, первое число в функции slice() - 2.

34) Фильтры (YouTube)

Vue.js позволяет определять фильтры, которые можно использовать для применения обычного форматирования текста (« официальный сайт )».

  • Заглавные буквы сделаны в верхнем регистре
  • Вырежьте тела, чтобы показать максимум 100 символов.
[src > components > showBlogs.vue]
<template>
  <div id='show-blogs'>
    <h1>All Blog Articles</h1>
    <div v-for='blog in blogs' class='single-blog'>
      <h2>{{ blog.title | to-uppercase }}</h2>
      <article>{{ blog.body | snippet }}</article>
    </div>
  </div>
</template>
<script>
  // same as above
</script>

<style scoped>
/* same as above */
</style>
-----------------------------------
[src > main.js]
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'

Vue.prototype.$http = axios;
Vue.filter('to-uppercase', function(value){
  return value.toUpperCase()
});
Vue.filter('snippet', function(value){
  return value.slice(0,100) + '...'
});

new Vue({
  el: '#app',
  render: h => h(App)
});

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

  1. | <name of a filter> в showBlogs.vue: добавляется в конец выражения JavaScript, обозначается символом «вертикальная черта».
  2. Vue.filter('<name of a filter>', function(){}) в main.js: глобально определите фильтр перед созданием Vue экземпляра.

35) Фильтр пользовательского поиска (YouTube)

Когда пользователь вводит слово (слова) в строке поиска, на экране остаются только блоги, содержащие это слово (слова).

[src > components > showBlogs.vue]
<template>
  <div id='show-blogs'>
    <h1>All Blog Articles</h1>
    <div v-for='blog in filteredBlogs' class='single-blog'>
      <h2>{{ blog.title | to-uppercase }}</h2>
      <article>{{ blog.body | snippet }}</article>
    </div>
  </div>
</template>
<script>
export default{
  data(){
    blogs: [],
    search: ''
  },
  created(){
    // same as above
  },
  computed:{
    filteredBlogs: function(){
      return this.blogs.filter((blog) => {
        return blog.title.match(this.search) || blog.body.match(this.search);
      });
    }
  }
}
</script>

<style scoped>
/* same as above */
</style>

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

  • A || B означает «А» или «В». В этом случае фильтр «filterBlogs» выполняет поиск по всем сообщениям в блогах, проверяет каждое сообщение в блоге, чтобы увидеть, содержит ли сообщение в блоге слово (слова), введенные в строке поиска в его заголовке или теле, и возвращает только совпавшие сообщения блога на экран.

36) Регистрация вещей локально (YouTube)

В предыдущих главах мы использовали фильтры «в верхний регистр» и «сниппет», зарегистрированные глобально.

[src > main.js]
Vue.filter('to-uppercase', function(value){
  return value.toUpperCase()
});
Vue.filter('snippet', function(value){
  return value.slice(0,100) + '...'
});

В этой главе мы зарегистрируем фильтры локально в showBlogs.vue. Кроме того, мы добавим директиву v-rainbow локально.

[src > components > showBlogs.vue]
<template>
  <div id='show-blogs'>
    <h1>All Blog Articles</h1>
    <div v-for='blog in filteredBlogs' class='single-blog'>
      <h2 v-rainbow>{{ blog.title | to-uppercase }}</h2>
      <article>{{ blog.body | snippet }}</article>
    </div>
  </div>
</template>
<script>
export default{
  data(){
    blogs: [],
    search: ''
  },
  created(){
    // same as above
  },
  computed:{
    // same as above
  },
  filters:{
    'to-uppercase': function(value){
      return value.toUpperCase();
    },
    snippet(value){
      return value.slice(0,100) + '...';
    }
  },
  directives:{
    'rainbow':{
      bind(el, binding, vnode){
    el.style.color = '#' + Math.random().toString().slice(2,8);
      }
    } 
  }
}
</script>

<style scoped>
/* same as above */
</style>
-----------------------------------
[src > main.js]
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'

Vue.prototype.$http = axios;

new Vue({
  el: '#app',
  render: h => h(App)
});

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

'to-uppercase': function(value) можно записать как toUppercase(value).

37) Миксины (YouTube)

Mixins - это гибкий способ распределения многоразовых функций для Vue компонентов. Объект mixin может содержать любые параметры компонента. Когда компонент использует mixin, все параметры в mixin будут «смешаны с собственными параметрами компонента (официальный веб-сайт) ».

[src > App.vue]
<template>
  <div>
    <show-blogs></show-blogs>
    <list-blogs></list-blogs>
  </div>
</template>

<script>
import showBlogs from './components/showBlogs.vue';
import listBlogs from './components/listBlogs.vue';

export default{
  components{
    'show-blogs': showBlogs,
    'list-blogs': listBlogs
  }
}
</script>
-----------------------------------
[src > components > showBlogs.vue]
<template>
  <!-- same as above -->
</template>
<script>
import searchMixin from '../mixins/searchMixin';
export default{
  data(){
    blogs: [],
    search: ''
  },
  created(){
    // same as above
  },
  filters:{
    // same as above
  },
  directives:{
    // same as above
  }
}
</script>

<style scoped>
/* same as above */
</style>
-----------------------------------
[src > components > listBlogs.vue]
<template>
  <!-- same as above -->
</template>
<script>
import searchMixin from '../mixins/searchMixin';
export default{
  data(){
    blogs: [],
    search: ''
  },
  created(){
    // same as showBlogs.vue
  },
  filters:{
    // same as showBlogs.vue
  },
  directives:{
    // same as showBlogs.vue
  }
}
</script>

<style scoped>
/* same as above */
</style>
-----------------------------------
[src > mixins > searchMixin.js]
export default{
  computed:{
    filteredBlogs: function(){
      return this.blogs.filter((blog) => {
        return blog.title.match(this.search) || blog.body.match(this.search);
      });
    }
  }
}

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

38) Настройка маршрутизации (YouTube)

Vue Router - официальный маршрутизатор для« Vue.js . Он глубоко интегрирован с Vue.js ядром, что упрощает создание одностраничных приложений с Vue.js (официальный сайт) ».

Установите vue-router с помощью диспетчера пакетов узлов (NPM): npm install vue-router --save.

[src > main.js]
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueRouter from 'vue-router'
import Routes from './routes'

Vue.prototype.$http = axios;
Vue.use(VueRouter);

const router = new VueRouter({
  routes : Routes  
});

new Vue({
  el: '#app',
  render: h => h(App),
  router: router
});
-----------------------------------
[src > routes.js]
import showBlogs from './components/showBlogs.vue';
import addBlog from './components/addBlogs.vue';

export default[
  { path: '/', component: showBlogs },
  { path: '/add', component: addBlog }
]
-----------------------------------
[src > App.vue]
<template>
  <div>
    <router-view></router-view>
  </div>
</template>
-----------------------------------
[src > components > showBlogs.vue]
<template>
  <!-- same as above -->
</template>
<script>
export default{
  data(){
    blogs: [],
    search: ''
  },
  created(){
    // same as above
  },
  computed:{
    filteredBlogs: function(){
      return this.blogs.filter((blog) => {
        return blog.title.match(this.search) || blog.body.match(this.search);
      });
    }
  },
  filters:{
    // same as above
  },
  directives:{
    // same as above
  }
}
</script>

<style scoped>
/* same as above */
</style>

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

39) Маршрутизация: хеш против истории (YouTube)

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

Чтобы избавиться от хеша, мы можем использовать режим истории маршрутизатора.

[src > main.js]
// same as above

const router = new VueRouter({
  routes : Routes,
  mode: 'history'
});

new Vue({
  // same as above
});

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

›Теперь« localhost: 8080 / »и« localhost: 8080 / add »работают! (Больше не нужно включать хэш-тег в URL)

40) Добавление ссылок на маршрутизатор (YouTube)

Давайте добавим вверху заголовок с панелью навигации с двумя ссылками, которые переключают представление между showBlogs.js и addBlog.js.

[src > App.vue]
<template>
  <div>
    <add-header></add-header>
    <router-view></router-view>
  </div>
</template>

<script>
import header from './components/header.vue'

export default{
  components{
    'add-header': header
  }
}
</script>
-----------------------------------
[src > components > header.vue]
<template>
  <nav>
    <ul>
      <li><router-link to='/' exact>Blog</router-link></li>
      <li><router-link to='/add' exact>Add a New Blog</router-link></li>
    </ul>
  </nav>
</template>
<style scoped>
ul{
    list-style-type: none;
    text-align: center;
    margin: 0;
}
li{
    display: inline-block;
    margin: 0 10px;
}
a{
    color: #fff;
    text-decoration: none;
    padding: 6px 8px;
    border-radius: 10px;
}
nav{
    background: #444;
    padding: 14px 0;
    margin-bottom: 40px;
}
.router-link-active{
  background: #eee;
  color: #444;
}
</style>

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

  1. Вместо <a href='/'> используется router-link. router-link перехватывает событие щелчка. Таким образом, нам не нужно перезагружать страницу, и это быстрее.
  2. router-link имеет класс router-link-active. Стиль router-link-active позволяет нам различать неактивный router-link и активный router-link.
  3. Когда свойство exact не включено в тег router-link, <router-link to='/'> имеет стиль router-link-active даже после того, как <router-link to='/add'> становится активным, а <router-link to='/'> становится неактивным. Причина в том, что '/add' содержит '/'. *** Свойство Exact делает router-link активным только в том случае, если URL-адрес в точности совпадает со ссылкой, включенной в тег router-link.

41) Параметры маршрута (YouTube)

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

Динамический сегмент обозначается двоеточием :. При сопоставлении маршрута значение динамических сегментов будет отображаться как this.$route.params в каждом компоненте. Следовательно, мы можем отобразить текущий идентификатор пользователя, обновив шаблон User до следующего: (официальный сайт) »

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
  routes: [
    // dynamic segments start with a colon
    { path: '/user/:id', component: User }
  ]
})

Другими словами, мы можем определить параметры маршрута и обработать их в компоненте, сделав HTTP запрос на правильный ресурс.

[src > routes.js]
import showBlogs from './components/showBlogs.vue';
import addBlog from './components/addBlogs.vue';
import singleBlog from './components/singleBlog.vue';
export default[
  { path: '/', component: showBlogs },
  { path: '/add', component: addBlog },
  { path: '/blog/:id', component: singleBlog }
]
-----------------------------------
[src > components > singleBlog.vue]
<template>
  <div id='single-blog'>
    <h1>{{ blog.title }}</h1>
    <article>{{ blog.body }}</article>
  </div>
</template>
<script>
export default{
  data(){
    return{
      id: this.$route.params.id,
      blog: {}
    }
  },
  created(){
    const axios = require('axios');
    axios.get('https://jsonplaceholder.typicode.com/posts/' + this.id
    ).then(response => {
      console.log(response);
      this.blog = response.data;
    });
  }
}
</script>
<style scoped>
#single-blog{
  max-width: 960px;
  margin: 0 auto;
  color: gray;
}
</style>

Между моим кодом и кодом Net Ninja есть несколько отличий, поскольку я использовал axios, а Net Ninja использовал vue-resource.

  1. Используйте import axios from ‘axios’ вместо import VueResource from 'vue-resource’ в файле main.js.
  2. Введите Vue.prototype.$http = axios вместо Vue.use(VueResource).
  3. Внутри post: function() включите const axios = require(‘axios').
  4. Введите axios.post вместо this.$http.post.
  5. Используйте => вместо function().

[Код Net Ninja]

.then(function(data) {
  console.log(data);
  this.blog = data.body;

[Мой код]

.then(response => {
  console.log(response);
  this.blog = response.data;

›Чтобы получить доступ к примерам объектов, предоставляемых JSON Placeholder , мне нужно было использовать data вместо body. Итак, чтобы не путать с этим, я передал response вместо data.

/blog/<a number> отображает другой объект, предоставленный JSON Placeholder. (например, localhost:8080/blog/30)

Но пользователи не будут вводить такой URL-адрес для доступа к веб-странице. Пользователи будут читать статьи блога и щелкать одну из них, чтобы перейти к конкретной статье блога.

Итак, заменил <h2 v-rainbow>{{ blog.title | to-uppercase }}</h2> в showBlogs.vue следующим:

<router-link v-bind:to="'/blog' + blog.id"><h2 v-rainbow>{{ blog.title | to-uppercase }}</h2></router-link>

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

42) Размещение в Firebase (YouTube)

До сих пор мы использовали поддельный онлайн-REST API, предоставляемый JSON Placeholder. Мы можем добавить наш собственный контент, сохранить его в базе данных и получить его с помощью инструмента под названием Firebase. Firebase позволяет нам хранить данные в базе данных NoSQL (язык структурированных запросов), что означает, что мы храним данные как объекты JavaScript.

После создания проекта вы будете перенаправлены на страницу проекта. На странице проекта щелкните в следующем порядке: значок «база данных» слева, «База данных реального времени» в средней ›вкладке« Правила ».

Если настройка по умолчанию не выглядит следующим образом, измените настройку следующим образом:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

".read" означает, разрешено ли пользователям читать данные или нет.

".write" обозначает, разрешено ли запись данных.

*** После того, как вы запустили свое приложение в рабочую среду, вам нужно будет настроить безопасность для своего приложения. Посетите здесь, чтобы узнать больше о правилах безопасности firebase.

На вкладке данные вы можете увидеть ссылку на базу данных Firebase для вашего проекта. мы бы использовали его вместо ссылки JSON Placeholder: https://jsonplaceholder.typicode.com/posts/.

[src > components > addBlog.vue]
<template>
  <!-- same as above -->
</template>
<script>
export default{
  data(){
    // same as above
  },
  methods:{
    post: function(){
      const axios = require('axios');
      axios.post('https://<name of your project>.firebaseio.com/posts.json', this.blog
      ).then(response => {
        console.log(response);
        this.submitted = true;
      });
    }
  }
}
</script>
<style scoped>
  /* same as above */
</style>

Доступно для просмотра кода с подсветкой синтаксиса на GitHubGist.

›Между моим кодом и кодом Net Ninja есть несколько отличий, поскольку я использовал axios, а Net Ninja использовал vue-resource. Если вы хотите увидеть подробности этого еще раз, ознакомьтесь с главой «31) HTTP-запросы» в начале этого сообщения в блоге.

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

43) Получение сообщений из Firebase (YouTube)

Мы по-прежнему видим образцы данных из JSON Placeholder. Чтобы увидеть сообщения блога, которые мы добавили в firebase, нам нужно предпринять некоторые шаги.

[ШАГ 1]: проверьте данные, которые мы получаем от Firebase на консоли (в showBlogs.vue)

created():{
  post: function(){
    const axios = require('axios');
    axios.get('https://<name of your project>.firebaseio.com/posts.json')
    .then(response => {
      console.log('1. response', response);
    })
  }
}

[ШАГ 2]: добавьте свойство id (в showBlogs.vue)

В главе 41 (Добавление ссылок на маршрутизатор) мы добавили ссылку на каждое отдельное сообщение в блоге: <router-link v-bind:to=”’/blog’ + blog.id”>.

Свойство id существовало в выборке данных. Но его нет в наших данных из Firebase. Однако у нас есть уникальный ключ для каждого объекта, который ссылается на сообщение в блоге.

[ШАГ 2–1]: вернуть promise объектов (в showBlogs.vue)

created():{
  post: function(){
    const axios = require('axios');
    axios.get('https://<name of your project>.firebaseio.com/posts.json')
    .then(response => {
      return response.data;
    });
  }
}

Объект Promise представляет окончательное завершение (или сбой) асинхронной операции и ее результирующее значение ( MDN ). Поскольку мы имеем дело с promise объектами, они асинхронны, и нам нужно использовать .then метод.

[Код Net Ninja]

.then(function(data) {
  return data.json();

[Мой код]

.then(response => {
  return response.data;

Поскольку Net Ninja использовал vue-resource, он использовал .json() для преобразования данных в данные JSON. Но я использовал axios. Так что мне не нужно было этого делать.

›В axios нам больше не нужно преобразовывать данные в данные JSON. Одной из возможностей axios является автоматическое преобразование данных JSON (GitHub).

[ШАГ 2–2]: вызовите call-back функцию (в showBlogs.vue)

created():{
  post: function(){
    const axios = require('axios');
    axios.get('https://<name of your project>.firebaseio.com/posts.json')
    .then(response => {
      console.log('2. response.data', response.data);
      return response.data;
    }).then(response => {
      console.log('3. response / callback function', response);
    });
  }
}

Теперь мы можем использовать метод .then, который запускает функцию call-back после выполнения response.data.

[ШАГ 2–3]: циклический переход между объектами (в showBlogs.vue)

created():{
  post: function(){
    const axios = require('axios');
    axios.get('https://<name of your   project>.firebaseio.com/posts.json')
    .then(response => {
       return response.data;
    }).then(response => {
      let blogsArray = [];
      for(let key in response){
        console.log('4. key', key);
        console.log('5. response[key]', response[key]);
      }
    });
  }
}

[ШАГ 2–4]: поместите объекты в пустой массив (в showBlogs.vue)

  1. Добавьте свойство под названием «id» к каждому объекту, которое будет равно key.
  2. Поместите все объекты в пустой массив, который мы создали: blogsArray.
created(){
  axios.get('https://<name of your     project>.firebaseio.com/posts.json')
    .then(response => {
      return response.data;
    }).then(response => {
      let blogsArray = [];
      for(let key in response){
        response[key].id = key;
        blogsArray.push(response[key]);
      }
    });
  }
}

[ШАГ 2–5]: отобразите объекты на экране (в showBlogs.vue)

  1. После помещения всех объектов в blogsArray присвойте массив this.blogs массиву. (This.blogs массив - это то, что показано на экране.)
  2. Ошибка все равно будет, потому что мы использовали blog.body для извлечения содержимого в образцах данных из JSON Placeholder. Чтобы получить содержимое наших данных из Firebase, нам нужно изменить blog.body на blog.content в searchMixins.js, showBlogs.vue и singleBlog.vue .
data(){
  return { blogs: [], search: '' }
},
created(){
  axios.get('https://<name of your     project>.firebaseio.com/posts.json')
    .then(response => {
      return response.data;
    }).then(response => {
      let blogsArray = [];
      for(let key in response){
        response[key].id = key;
        blogsArray.push(response[key]);
      }
      console.log('6. this.blogs', this.blogs);
      console.log('7. blogsArray', blogsArray);
      this.blogs = blogsArray;
    });
  }
}

[ШАГ 3]: при нажатии отображать отдельную запись блога на новой странице (в singleBlog.vue)

data(){
  return {
    id: this.$route.params.id,
    blog: {} 
  }
},
created(){
  axios.get('https://<name of your     project>.firebaseio.com/posts/' + this.id + '.json')
    .then(response => {
      return response.data;
    }).then(response => {
      this.blog = response;
    });
  }
}

Поскольку мы создали id с помощью key на шаге 2, мы можем использовать это, чтобы открывать отдельное сообщение в блоге на новой странице при нажатии.

Полный код доступен для просмотра с подсветкой синтаксиса на сайте GitHubGist.

Если вы хотите прочитать предыдущие части моего обзора Vue JS2 Tutorial от Net Ninja, посетите здесь для части 1 и здесь для части 2.

Спасибо за чтение! 💕 Если вам понравился этот пост в блоге, пожалуйста, хлопайте в ладоши👏