paint-brush
Construyamos una aplicación web con Vue, Chart.js y una APIpor@apertureless
64,541 lecturas
64,541 lecturas

Construyamos una aplicación web con Vue, Chart.js y una API

por Jakub Juszczak2017/04/19
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Los datos son hermosos. Y con las tecnologías modernas, es increíblemente fácil visualizar sus datos y crear grandes experiencias. En esta guía rápida, cubrimos cómo interactuar con la API npm 💘 para obtener estadísticas de descarga de un paquete y generar un gráfico a partir de estos datos con <a href="http://www.chartjs.org/" target="_blank">Chart.js</a>

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Construyamos una aplicación web con Vue, Chart.js y una API
Jakub Juszczak HackerNoon profile picture

La primera parte de la creación de una pequeña aplicación web que interactúa con la API de npm y genera buenos gráficos

Los datos son hermosos. Y con las tecnologías modernas, es increíblemente fácil visualizar sus datos y crear grandes experiencias. En esta guía rápida, cubrimos cómo interactuar con la API npm 💘 para obtener estadísticas de descarga de un paquete y generar un gráfico a partir de estos datos con Chart.js

⚡ Inicio rápido

Construiremos npm-stats.org y utilizaremos las siguientes herramientas:

Con Vue.js construiremos la interfaz básica de la aplicación y el enrutamiento con vue-router . Y armamos nuestro proyecto con vue-cli, que crea la estructura básica de nuestro proyecto. Para la generación de gráficos, usaremos Chart.js y, como contenedor para Vue, vue-chartjs . Como necesitamos interactuar con una API, estamos usando axios para realizar las solicitudes http. Sin embargo, siéntase libre de cambiar ese con cualquier otro lib.

🔧 Instalación y configuración

Primero necesitamos instalar vue-cli para montar nuestro proyecto. ¡Espero que ya tenga instalada una versión actual de node y npm! 🙏 ¡Aún mejor si tienes hilo instalado! ¡Si no, realmente deberías! Si no lo desea, simplemente cambie los comandos de hilo con los equivalentes de npm.

$ npm install -g vue-cli

Luego podemos montar nuestro proyecto con vue-cli. Si desea, puede habilitar la unidad y las pruebas e2e, sin embargo, no las cubriremos. 🔥 ¡Pero debe verificar vue-router!

$ vue init paquete web npm-stats

Luego hacemos cd en nuestra carpeta de proyecto e instalamos las dependencias con cd npm-stats && yarn install . Entonces nuestras dependencias básicas del proyecto están instaladas. Ahora necesitamos agregar el de nuestra aplicación.

$ hilo agregar vue-chartjs chart.js axios

Solo una verificación rápida si todo se está ejecutando con yarn run dev . Ahora deberíamos ver la página repetitiva de vue.

¡Aaaay hemos terminado! 👏

💪 Hora de construir

Solo un pequeño descargo de responsabilidad aquí, no me centraré en el estilo. Supongo que puedes hacer que el sitio se vea bien por tu cuenta 💅, así que solo cubrimos el código relacionado con javascript.

Y otro descargo de responsabilidad, este es más bien un MVP pequeño que un código súper limpio en este momento. Refactorizaré algo de esto en etapas posteriores. Como en el mundo real.

Componentes

Pensemos qué componentes necesitamos. Mientras miramos la captura de pantalla, vemos un campo de entrada para el nombre del paquete que está buscando y un botón. Tal vez un encabezado y pie de página y el propio gráfico.

Podría hacer que el botón y el campo de entrada sean un componente; sin embargo, como no construimos una aplicación compleja, ¿por qué molestarse? Hazlo simple. ¡Hazlo funcionar!

Así que terminé con los siguientes componentes:

  • componentes/Pie de página.vue
  • componentes/Header.vue
  • componentes/LineChart.vue
  • páginas/Inicio.vue

Omitiré el encabezado y el pie de página , ya que solo contienen el logotipo y algunos enlaces. Nada especial aquí. El gráfico de líneas y la página de inicio son los más importantes.

Gráfico de linea

El componente LineChart será nuestra instancia de chart.js que representa el gráfico. Necesitamos importar el componente Line y extenderlo. Creamos dos accesorios por ahora. Uno para los datos que es el número de descargas y las etiquetas que son por ejemplo los días, semanas, años.










accesorios: {chartData: {tipo: Array, requerido: falso},chartLabels: {tipo: Array, requerido: true}},

Como queremos que todos nuestros gráficos tengan el mismo aspecto, definimos algunas de las opciones de estilo de Chart.js en un modelo de datos que se pasan como opciones al método renderChart() .

Y como solo tendremos un conjunto de datos por ahora, podemos construir la matriz del conjunto de datos y vincular las etiquetas y los datos.

📺 Nuestra página de inicio

Como tenemos nuestro componente LineChart en funcionamiento. Es hora de construir el resto. Necesitamos un campo de entrada y un botón para enviar el nombre del paquete. Luego solicite los datos y pase los datos a nuestro componente gráfico.

Entonces, primero pensemos qué datos necesitamos y qué estados/modelos de datos. En primer lugar, necesitamos un modelo de datos de package , que usaremos con v-model en nuestro campo de entrada. También queremos mostrar el nombre del paquete como título. Entonces packageName sería bueno. Luego, nuestras dos matrices para las downloads y labels de datos solicitadas y, como estamos solicitando un período de tiempo, debemos establecer el period . Pero, tal vez la solicitud salga mal, por lo que necesitamos errorMessage y showError . Y, por último, pero no menos importante, loaded , ya que queremos mostrar el gráfico solo después de realizar la solicitud.

API de npm

Hay varios puntos finales para obtener las descargas de un paquete. uno es por ejemplo

OBTENGA https://api.npmjs.org/downloads/point/{período}[/{paquete}]

Sin embargo, este solo obtiene un valor en puntos. Así que las descargas totales. Pero para dibujar nuestro genial gráfico, necesitamos más datos. Así que necesitamos el punto final del rango.

OBTENGA https://api.npmjs.org/downloads/range/{período}[/{paquete}]

El período se puede definir como, por ejemplo last-day o last-month o un rango de fechas específico 2017-01-01:2017-04-19 Pero para simplificar, establecemos el valor predeterminado en last-month . Más adelante, en la Parte II, podemos agregar algunos campos de entrada de fecha para que el usuario pueda establecer un rango de fechas.

Así que nuestros modelos de datos se ven así:












data () {return {package: null,packageName: '',period: 'last-month',loaded: false,downloads: [],labels: [],showError: false,errorMessage: 'Por favor ingrese un nombre de paquete' }},

💅 Plantilla

Ahora es el momento de construir la plantilla. Necesitamos 5 cosas:

  • Campo de entrada
  • Botón para activar la búsqueda
  • Salida de mensaje de error
  • Titular con el nombre del paquete
  • Nuestro Gráfico.






<inputclass=”Search__input” @keyup .enter=”requestData”placeholder=”npm package name”type=”search” name=”search”v-model=”package”

<button class=”Buscar__button” @click =”requestData”>Buscar</button>



<div class="mensaje-de-error" v-if="showError">{{ mensaje-de-error }}</div>


<h1 class="title" v-if="loaded">{{ packageName }}</h1><line-chart v-if="loaded" :chart-data="downloads" :chart-labels="labels "></gráfico de líneas>

Simplemente ignore las clases css por ahora. Tenemos nuestro campo de entrada que tiene un evento keyup al ingresar. Entonces, si presionas enter, activas el método requestData() . Y unimos v-model al package

Para el error potencial tenemos una condición, solo si showError es verdadero mostramos el mensaje. Hay dos tipos o errores que pueden ocurrir. La primera es que alguien intenta buscar un paquete sin ingresar ningún nombre o está ingresando un nombre que no existe.

Para el primer caso, tenemos nuestro mensaje de error predeterminado, para el segundo caso, tomaremos el mensaje de error que proviene de la solicitud.

Así que nuestra plantilla completa se verá así:

🤖 JavaScript

Ahora es el momento de la codificación. Primero haremos nuestro método requestData() . Es bastante simple. Necesitamos hacer una solicitud a nuestro punto final y luego mapear los datos que ingresan. En nuestra respuesta.datos tenemos información sobre el paquete:

respuesta.datos

Como los datos de inicio, la fecha de finalización, el nombre del paquete y luego la matriz de descargas. Sin embargo, la estructura de la matriz de descargas es algo como esto:





descargas: [{día: '2017–03–20', descargas: '3'},{día: '2017–03–21', descargas: '2'},{día: '2017–03–22', descargas: '10'},]

Pero necesitamos separar las descargas y los días, porque para chart.js necesitamos una matriz solo con los datos (descargas) y una matriz con las etiquetas (día). Este es un trabajo fácil para el mapa













requestData () {axios.get(` https://api.npmjs.org/downloads/range/${this.period}/${this.package}` ).then(response => {this.downloads = respuesta .data.downloads.map(download => download.downloads)this.labels = response.data.downloads.map(download => download.day)this.packageName = response.data.packagethis.loaded = true}).catch (err => {this.errorMessage = err.response.data.errorthis.showError = true})}

Ahora, si ingresamos un nombre de paquete, como vue y presionamos enter, se realiza la solicitud, se asignan los datos y se representa el gráfico. Pero espera. No ves nada. Porque necesitamos decirle a vue-router que establezca el índice en nuestra página de inicio.

En router/index.js importamos o paginamos y le decimos al enrutador que lo use



importar Vue desde 'vue'importar enrutador desde 'vue-router'importar página de inicio desde '@/pages/Start'

Vue.use (enrutador)









exportar el nuevo enrutador predeterminado ({rutas: [{ruta: '/', nombre: 'Inicio', componente: Página de inicio},]})

💎 polaco

Pero aún no hemos terminado. Tenemos algunos problemas, ¿verdad? Primero, nuestra aplicación se rompe si no ingresamos ningún nombre. Y tenemos problemas si ingresa un nuevo paquete y presiona enter. Y después de un error el mensaje no desaparece.

Bueno, es hora de limpiar un poco. Primero, creemos un nuevo método para restablecer nuestro estado.




resetState () {this.loaded = falsethis.showError = false},

Que llamamos en nuestro método requestData requestData() antes de la llamada a axios api. Y necesitamos un cheque para el nombre del paquete.






if (este.paquete === nulo|| este.paquete === ''|| este.paquete === 'indefinido') {este.showError = truereturn}

Ahora, si intentamos buscar un nombre de paquete vacío, obtenemos un mensaje de error predeterminado.

Lo sé, cubrimos mucho, pero agreguemos otra pequeña característica interesante. Tenemos vue-router, pero en realidad no lo usamos. En nuestra raíz / vemos la página de inicio con el campo de entrada. Y después de una búsqueda nos quedamos en nuestra página raíz. Pero sería genial si pudiéramos compartir nuestro enlace con las estadísticas, ¿no?

Entonces, después de una búsqueda válida, agregamos el nombre del paquete a nuestra URL.

npm-stats.org/#/vue-chartjs

Y si hacemos clic en ese enlace, debemos tomar el nombre del paquete y usarlo para solicitar nuestros datos.

Vamos a crear un nuevo método para configurar nuestra url



setURL () {history.pushState({ información: `npm-stats ${this.package}`}, this.package, `/#/${this.package}`)}

Necesitamos llamar a this.setURL() en nuestra promesa de respuesta. Ahora, después de realizar la solicitud, agregamos el nombre del paquete a nuestra URL. Pero, si abrimos una nueva pestaña del navegador y la llamamos, no pasa nada. Porque necesitamos decirle a vue-router que todo lo que esté después de nuestro / también apuntará a la página de inicio y definirá la cadena como un parámetro de consulta. Que es súper fácil.

En nuestro router/index.js solo necesitamos establecer otra ruta en la matriz de rutas. Llamamos al paquete param.




{ruta: '/:paquete', componente: Página de inicio}

Ahora, si va a localhost:8080/#/react-vr obtendrá la página de inicio. Pero sin carta. Porque necesitamos tomar el parámetro y hacer nuestra solicitud con él.

De vuelta en nuestro Start.vue tomamos el parámetro en el gancho montado.






montado () {if (this.$route.params.package) {this.package = this.$route.params.packagethis.requestData()}},

¡Y eso es!

Puede consultar la fuente completa en GitHub y ver la página de demostración en 📺 http://npm-stats.org/

Mejoras

Pero bueno, todavía hay margen de mejora. Podríamos agregar más gráficos. Como estadísticas mensuales, estadísticas anuales y agregar campos de fecha para establecer el período y muchas cosas más. ¡Cubriré algunos de ellos en la Parte II ! ¡Así que estad atentos!

Parte 2: https://hackernoon.com/lets-build-a-web-app-with-vue-chart-js-and-an-api-part-ii-39781b1d5acf