Это последняя часть руководства о том, как создать простую (но увлекательную !!) викторину для веб-приложений с использованием Vue.js

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

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

А теперь займемся этим.

Исходное репо:

Https://github.com/omar1893/vue-quiz.git

Создание диаграммы

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

Теперь нам нужно установить vue-chart.js. Для этого нам нужно запустить следующую команду:

yarn add vue-chartjs chart.js

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

<script>
import {Doughnut} from 'vue-chartjs'
export default {
   extends: Doughnut,
   data(){
    return{
     incorrects:'',
     corrects: ''
    }
   },
}
</script>

Итак, в основном, здесь мы импортируем базовую диаграмму для этого компонента (посетите документацию vue-chartjs, чтобы проверить другие диаграммы) и расширили ее как обычный компонент с созданным объектом данных. Теперь нам нужно получить счет в магазине. Поэтому вместо инициализации атрибутов, таких как пустые строки, давайте сделаем следующее:

incorrects: this.$store.state.results.incorrect_answers,
corrects: this.$store.state.results.correct_answers

Теперь наши атрибуты начнутся с данных, которые сохранены в нашем магазине.

Теперь, когда у нас есть данные, нам не хватает только функции для визуализации диаграммы. Для этого воспользуемся еще одним крючком жизненного цикла, который называется «смонтированный». Итак, давайте добавим следующее:

mounted () {
   this.renderChart({
    labels: [‘Incorrects Answers’, ‘Correct Answers’],
    datasets: [{
      backgroundColor: [‘#E74C3C’,’#82BF56'],
      data: [this.incorrects, this.corrects]
    }]}, 
    {responsive: true, maintainAspectRatio: false})
}

Несмотря на то, что это действительно читается на естественном языке, давайте быстро это объясним. Мы вызываем метод renderChart (метод, зарезервированный из vue-chartjs), а затем передаем ему два объекта. В первом объекте находятся данные, которые мы хотим отобразить на нашей диаграмме, а во втором объекте - в основном параметры того, как должна отображаться диаграмма.

Решив это, нам нужно создать родительский компонент, который будет содержать компонент «пончик» и отображать кнопки, так что давайте создадим его. Мы назовем его «Results.vue» и, учитывая, что в этом компоненте нет ничего нового, давайте наберем сразу весь компонент:

<template>
  <div class=”results”>
    <div class=”card w-75 animated bounce text-center py-4 mb-3 mx-auto”>
     <doughnut></doughnut>
     <div class=”container”>
      <router-link to=”/import”>
       <button class=”action-button animate blue my-2 w-100">
        Upload Score
       </button>
      </router-link>
      <router-link to=”/”>
       <button class=”action-button animate green w-100">Home Page
       </button>
      </router-link>
     </div>
    </div>
   </div>
</template>
<script>
import Doughnut from ‘./Doughnut’
export default {
  name: ‘results’,
  data () {return {}},
  components:{
   “doughnut”: Doughnut
  }
}
</script>

Единственное, что здесь нового - это router-link, хотя вы, возможно, уже догадались, что это такое, я могу сказать, что это похоже на «href» нашего маршрутизатора. Поэтому, если пользователь хочет загрузить свою оценку, он перейдет к «/ import», но если он не справился с этой викториной, он может перейти к домашнему экрану («/»).

Затем мы должны не забыть импортировать его в наш router / index.js в качестве маршрута:

import Results from ‘@/components/Results’

А также:

{
 path: ‘/results’,
 name: ‘results’,
 component: Results
},

Теперь давайте создадим компонент импорта.

Создание компонента импорта.

Давайте создадим внутри папки «component» vue-файл с именем «Import.vue» и запомним его базовую структуру:

<template>
  <div>
   This is x Component
  </div>
</template>
<script>
  export default{}
</script>
<style scoped>
</style>

Затем мы должны создать данные нашего компонента. Итак, введите:

data () {
   return {
     upload:{
       username: '',
       score: ''
     }
   }
},

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

methods: {
   sendData: function(){
     console.log(this.upload);
     this.$http.post('FIREBASE_LINK',this.upload)
     .then(function(data){
     console.log(data)
     this.$router.push({name: 'start'})
     })
     .catch(function(data){
     console.log("Error: ",data)
     })
   }
 },

С помощью этого метода мы должны отправить запрос на публикацию в нашу базу данных firebase, в случае успеха он вернет игрока домой, в противном случае он должен распечатать ошибку в нашей консоли. Теперь мы почти готовы ... но ... нам нужно получить счет игрока и установить его в атрибуте upload.score, а кроме этого, мы отправляем счет в формате 'x из 10' (x / 10) . Итак, давайте воспользуемся крючком жизненного цикла created для достижения этой цели:

created(){
   this.upload.score = this.$store.getters.getScore;
}

Как вы могли заметить, мы вызываем геттер (которого еще не существует), который вернет счет игры в желаемом формате.

Теперь нам нужно задать структуру этого компонента:

<template>
   <div class=”import”>
    <div class=”card w-75 animated bounce text-center py-4 mb-3 mx-auto”>
      <h3 class=”bits mb-3">Upload Score</h3>
      <div class=”container”>
        <label for=”user” class=”bits w-100 bold mt-2 mb-0">Your Score:</label>
        <label for=”user” class=”bits w-100">{{upload.score}}</label>
        <label for=”user” class=”bits w-100 bold mt-3">Enter your username:</label>
        <input type=”text” class=”bits w-75" v-model=”upload.username” maxlength=”12">
        <button class=”action-button animate blue mt-4 mb-2 w-100" v-on:click=”sendData()”>Upload</button>
        <router-link to=”/results”>
        <button class=”action-button animate green my-2 w-100">Back</button>
     </router-link>
    </div>
   </div>
  </div>
</template>

Давайте быстро создадим геттер.

Получатель результатов.

Это будет легко. В «store / store.js» нам нужно ввести следующее:

getters: {
   getScore(state) {
      var total = state.results.correct_answers +   state.results.incorrect_answers;
      return state.results.correct_answers + “ / “ + total
 }
},

В этом методе мы устанавливаем общее количество вопросов (var total), а затем возвращаем количество правильных ответов из общего количества вопросов (return state.results.correct_answers + «/« + total).

После этого нам нужно создать наш проект firebase. Итак, перейдем на страницу firebase.

Создание нашего проекта Firebase.

Теперь в проекте firebase нам нужно войти в систему с одной учетной записью google. Затем мы должны перейти к нашей консоли (ПЕРЕЙТИ К КОНСОЛИ).

Теперь внутри нашей консоли мы должны нажать кнопку «Добавить проект»:

После этого мы должны ввести желаемое имя для нашего приложения firebase. Я использую «quiz-medium», вы можете использовать все, что захотите (даже если это то же самое). Затем нажимаем «Создать проект».

Теперь нам нужно открыть раздел «База данных» на панели управления Firebase и нажать кнопку «Пуск» (даже если она на испанском).

Затем нам нужно перейти в раздел «правила» и добавить следующие правила:

{
   “rules”: {
      “.read”: true,
      “.write”: true
   }
}

Затем нажмите кнопку «Опубликовать». Теперь давайте немного расскажем об этих правилах. Firebase по умолчанию требует, чтобы пользователи прошли аутентификацию перед отправкой данных в проект вашей базы данных. Мы отменяем эти правила, и теперь любой (хороший или плохой) может отправлять сообщения в нашу базу данных firebase. Я рекомендую после того, как вы завершите этот проект, ознакомьтесь с услугами аутентификации, которые предоставляет firebase.

Теперь, с учетом сказанного, давайте вернемся к разделу «данные», и мы должны увидеть URL-адрес нашей базы данных firebase в заголовке внутренней карты.

Давайте скопируем его и вернемся в наш проект к нашему компоненту 'import' и внутри нашего метода sendData, давайте изменим 'FIREBASE_LINK' для нашей фактической ссылки на firebase, плюс нам нужно указать, что мы хотим, чтобы наши данные хранились в коллекции данных , так что назовем это «счет». В конце наша ссылка на firebase должна выглядеть примерно так:

‘https://{{my_firebase_link}}/score.json’.

После добавления этого мы сможем импортировать счет и пользователя в нашу базу данных firebase. Теперь единственное, чего не хватает, - это получить список баллов и вывести его на экран. Сначала перейдем к компоненту «Start.vue», чтобы что-нибудь добавить.

Вывод результатов

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

<router-link to='/score'>
   <button class=”action-button animate blue w-100">
     Ranking
   </button>
</router-link>

Теперь каждый раз, когда пользователь нажимает на эту кнопку, он переходит к «счету». Теперь давайте создадим наш компонент «Score», вы уже должны быть профессионалом в этом, внутри «components» давайте создадим файл «Score.vue» с базовой структурой:

<template>
   <div>
     This is x Component
   </div>
</template>
<script>
   export default{}
</script>
<style scoped>
</style>

И создайте маршрут внутри «router / index.js» с таким счетом:

import Score from '@/components/Score'
{
   path: '/score',
   name: 'score',
   component: Score
},

Теперь внутри нашего компонента Score давайте создадим данные нашей игры:

data () {
   return {
      score: []
   }
},

Он будет содержать массив оценок после того, как мы получим его из firebase. Теперь нам нужно получать данные каждый раз при создании этого компонента, поэтому давайте воспользуемся жизненным циклом created () для этого. Итак, введите следующее:

created(){
  this.$http.get('https://{{my_firebase_link}}/score.json')
  .then(function(data){
    this.score = data.body;
    console.log(this.score);
  })
  .catch(function(data){
    console.log('Error: ', data)
  })
}

Теперь давайте распечатаем данные внутри нашего компонента:

<template>
  <div class='score'>
    <div class='card w-75 animated bounce text-center py-4 px-5 mb-3 mx-auto'>
    <h3 class='bits'>Ranking</h3>
    <div class='container mb-4 px-5'>
     <div class='d-flex justify-content-between mb-4'>
      <span class='bits'>Username</span>
      <span class='bits text-right'>Score</span>
     </div>
     <div class='d-flex justify-content-between bits' v-for='user in
score'>
      <span>{{user.username}}</span>
      <span>{{user.score}}</span>
     </div>
    </div>
    <div class='w-100'>
      <router-link class='w-100 d-flex justify-content-center' to='/'>
       <button class='w-50 action-button animate green bits'>
        Back
       </button>
      </router-link>
    </div>
   </div>
  </div>
</template>

Здесь данные должны отображаться внутри нашего списка. Итак, в основном мы закончили с нашей игрой ... но нам нужно отсортировать эти данные, чтобы придать им стиль ранжирования. Итак, давайте обновим жизненный цикл «созданного» следующим образом:

created() {
   this.$http.get(‘https://quiz-medium.firebaseio.com/score.json')
   .then(function(data) {
     let arr = []
     for (let x in data.body) {arr.push(data.body[x])}
     this.score = arr.sort((a, b) => a.score < b.score ? 1 : -1)
     console.log(this.score)})
   .catch(function(data) {
     console.log(‘Error: ‘, data)
   })
}

С помощью этого фрагмента кода мы просто выполняем преобразование из структуры вложенных объектов firebase в структуру массива. Затем мы можем использовать метод sort () в нашем массиве.

Теперь мы можем сказать, что наша игра готова !! 🎉 🎉 🎉

Заключительная речь

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

Если вам нравится эта игра, просто заставьте эти руки хлопать в ладоши.