Самоучитель №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)
запросов.
v-if='!submitted'
используется для скрытия формы после нажатия кнопки «Добавить блог».- Используя
v-if='submitted'
, отобразите «Спасибо за добавление сообщения!» сообщение. 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
учебнике, я внес несколько изменений.
- Используйте
import axios from ‘axios’
вместоimport VueResource from 'vue-resource’
в файле main.js. - Введите
Vue.prototype.$http = axios
вместоVue.use(VueResource)
. - Внутри
post: function()
включитеconst axios = require(‘axios')
. - Введите
axios.post
вместоthis.$http.post
. response
вместоdata
вthen() method
: объяснит причину в следующей главе.- Используйте
=>
вместо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.
- В
v-theme:column
используются одинарные кавычки, чтобы заключить «узкий» в двойные кавычки. Без одинарных кавычек в консоли появляется следующее сообщение об ошибке: Свойство или метод «узкий» не определен в экземпляре, но на него ссылаются во время рендеринга. «Узкий» - это не свойство или метод. Это просто ценность. Чтобы указать, что это строка, нам нужно заключить слово в одинарные кавычки. - Добавлен
'#'
перед функциейMath.random()
, поскольку шестнадцатеричный цвет начинается с символа «#» (например, # 00fefe). - Функция
Math.random()
возвращает псевдослучайное число с плавающей запятой в диапазоне 0–1 (включая 0, но не 1) с приблизительно равномерным распределением в этом диапазоне, которое затем можно масштабировать до желаемого диапазона (MDN ). Результатомconsole.log(Math.random())
будет 0.XXXXX… Следовательно, первое число в функцииslice()
- 2.
34) Фильтры (YouTube)
- Заглавные буквы сделаны в верхнем регистре
- Вырежьте тела, чтобы показать максимум 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.
| <name of a filter>
в showBlogs.vue: добавляется в конец выражения JavaScript, обозначается символом «вертикальная черта».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.
- Компонент
<router-view>
- это функциональный компонент, который отображает согласованный компонент для заданного пути. Компоненты, отображаемые в<router-view>
, также могут содержать свои собственные<router-view>
, которые будут отображать компоненты для вложенных путей («официальный сайт) ». - «Режим по умолчанию для
vue-router
- режим хеширования - он использует хэш URL для имитации полного URL, чтобы страница не перезагружалась при изменении URL. ("Официальный сайт")". - Доступ к ссылкам можно получить с помощью символа «#» (например, «localhost: 8080 / # /» и «localhost: 8080 / # / add»).
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.
- Вместо
<a href='/'>
используетсяrouter-link
.router-link
перехватывает событие щелчка. Таким образом, нам не нужно перезагружать страницу, и это быстрее. router-link
имеет классrouter-link-active
. Стильrouter-link-active
позволяет нам различать неактивныйrouter-link
и активныйrouter-link
.- Когда свойство
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
.
- Используйте
import axios from ‘axios’
вместоimport VueResource from 'vue-resource’
в файле main.js. - Введите
Vue.prototype.$http = axios
вместоVue.use(VueResource)
. - Внутри
post: function()
включитеconst axios = require(‘axios')
. - Введите
axios.post
вместоthis.$http.post
. - Используйте
=>
вместо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)
- Добавьте свойство под названием «
id
» к каждому объекту, которое будет равноkey
. - Поместите все объекты в пустой массив, который мы создали:
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)
- После помещения всех объектов в
blogsArray
присвойте массивthis.blogs
массиву. (This.blogs
массив - это то, что показано на экране.) - Ошибка все равно будет, потому что мы использовали
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.
Спасибо за чтение! 💕 Если вам понравился этот пост в блоге, пожалуйста, хлопайте в ладоши👏