Создание персональной веб-страницы с помощью API dev.to и VueJS

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

API

Сначала я наткнулся на эту статью, в которой на примере PHP демонстрировалось, как использовать API платформы.

Как использовать API dev.to!

𝐍𝐚𝐭𝐚𝐥𝐢𝐞 𝐝𝐞 𝐖𝐞𝐞𝐛𝐫𝐝 ・ Jun 7 ’20 ・ 2 min read

#новички #webdev #php #tutorial

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

DEV API (бета-версия)| Forem Docs

Доступ к статьям, пользователям и другим ресурсам Forem через API. Реальный пример работы Forem в действии можно найти в [DEV] (https://www.dev.to). Все конечные точки, не требующие аутентификации, поддерживают CORS. Все запросы должны отправлять заголовок user-agent. Даты и время, если не указано иное, должны быть в формате [RFC 3339] (https://tools.ietf.org/html/rfc3339).

developers.forem.com

И благодаря этому я получил 2 нужные мне конечные точки:

  • пользователи
  • статьи

Vue

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

Потребление API

Первым шагом было создание метода для централизации запросов к api, что я сделал с помощью axios

import axios, {AxiosInstance} from "axios";

 const http: AxiosInstance = axios.create({
    baseURL: "https://dev.to/api/",
    headers: {
        'Accept': "application/json",
        'Content-Type': 'application/json'
    }
})

export default http;
Войдите в полноэкранный режим Выход из полноэкранного режима

После этого я создал отдельные службы для запросов к конечным точкам.

Сервис для получения статей:

import http from "@/http";

export const getArticles = () => http.get('articles', {
    params: {
        username: 'stsmuniz'
    }
})
Войдите в полноэкранный режим Выход из полноэкранного режима

И услуга по получению профиля

import http from "@/http";

export const getProfile = () => http.get('users/by_username', {
    params: {
        url: 'stsmuniz'
    }
})
Войдите в полноэкранный режим Выход из полноэкранного режима

Создав сервисы, мы можем теперь использовать их на сайте

Отображение профиля

Прежде всего, нам необходимо эффективно выполнить запрос. Поскольку я использовал composition api, я использовал метод onBeforeMount для получения данных перед рендерингом страницы.

  setup() {
    const profile = ref()

    onBeforeMount(() => {
      getProfile()
          .then(res => profile.value = res.data)
    })
    ....
    return {
        profile
    }
})
Войдите в полноэкранный режим Выход из полноэкранного режима

И на странице появляется компонент, который «монтирует» профиль

    <ProfileComponent profile="profile" v-if="profile"/>
    <i class="fa-solid fa-spinner fa-spin-pulse" v-else></i>
Войдите в полноэкранный режим Выход из полноэкранного режима

ProfileComponent — это компонент, который получает информацию о профиле и «собирает» профиль на экране.

<template>
  <div class="profile">
    <img class="profile-picture" :alt="profile.username" :src="profile.profile_image">
    <h1>{{profile.name}}</h1>
    <p class="description" v-html="profile.summary.replace('n', '<br />')"></p>
    <p><i class="fa-solid fa-location-dot"></i> {{profile.location}}</p>
  </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  name: "ProfileComponent",
  props: {
    profile: {
      required: true
    }
  },
})
</script>
Войдите в полноэкранный режим Выход из полноэкранного режима

И с помощью этого нам удалось вывести профиль на экран. Следующий шаг — проделать тот же процесс для статей

Отображение статей

Первое, что здесь нужно сделать, это создать представление для отображения статей, которое я назвал Blog. В настройке есть вызов API службой ArticleService, с помощью команды

<template>
  <div class="home" v-if="articles">
    <h1>Blog</h1>
    <ArticleList :articles="articles"/>
  </div>
  <i class="fa-solid fa-spinner fa-spin-pulse" v-else></i>
</template>

<script lang="ts">
import {defineComponent, onMounted, ref} from 'vue';
import {getArticles} from "@/service/ArticleService";

import ArticleList from '@/components/ArticleList.vue';

export default defineComponent({
  name: 'BlogView',
  components: {
    ArticleList,
  },
  setup() {
    const articles = ref()

    onMounted(() => {
      document.title = 'Blog'
    })

    getArticles()
        .then(res => articles.value = res.data)

    return {
      articles
    }
  }
});
</script>
Войдите в полноэкранный режим Выход из полноэкранного режима

ArticleList — это компонент контейнера, который в основном организует контейнер для списка статей.

<template>
  <div class="container">
    <ArticleItem v-for="article in articles" :article="article" :key="article.id" />
  </div>
</template>

<script>
import {defineComponent} from 'vue';
import ArticleItem from "@/components/ArticleItem";

export default defineComponent({
  name: 'ArticleList',
  components: {ArticleItem},
  props: {
    articles: {
      required: true
    }
  }
});
</script>
Войдите в полноэкранный режим Выход из полноэкранного режима

И, наконец, компонент ArticleItem организует информацию в шаблоне, чтобы сделать отображение

<template>
  <article>
    <a :href="article.url"
       :title="article.title"
       target="_blank">
      <img class="responsive"
           :src="article.cover_image"
           :alt="article.title" />
    </a>
    <div class="article-data">
      <h1>
        <a :href="article.url"
           :title="article.title"
           target="_blank">
          {{ article.title }}
        </a>
      </h1>
      <p class="article-description">{{article.description}}</p>
      <p class="publish-date">
        <i class="fa-solid fa-calendar"></i> <DateFormatter :date="article.published_at" />
      </p>
    </div>
  </article>
</template>

<script>
import DateFormatter from "./DateFormatter";
import {defineComponent} from "vue";

export default defineComponent({
  name: "ArticleItem",
  components: {DateFormatter},
  props: {
    article: {
      required: true
    }
  }
})
</script>
Войдите в полноэкранный режим Выход из полноэкранного режима

Поскольку я хотел отобразить дату в формате ddd/mm/yyyy, я создал компонент DateFormatter для обработки строки, которая приходит в формате ISO.

Развернуть

Я немного покопался и нашел интересную статью, в которой хорошо объясняется, как развернуть систему:

Автоматическая сборка и развертывание приложения Vue.js с помощью GitHub Pages — Блог LogRocket

Узнайте, как автоматически собрать и развернуть проект Vue.js на GitHub Pages — службе хостинга статических сайтов для ваших проектов на GitHub.

blog.logrocket.com

Если вы собираетесь использовать этот метод, будьте внимательны к имени основной ветви в файле gh-pages-deploy.js. В статье он называется master.

Закрытие

Используя это, а также базовую структуру vue и некоторые элементы стиля, вы сможете создать простой сайт с основной информацией, поступающей из вашего профиля dev.to, и страницей, на которой будут размещены ссылки на ваши последние статьи.

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

Спасибо, что следите за мной и до встречи в следующий раз 👋

Оцените статью
devanswers.ru
Добавить комментарий