En esta página:
Demo
En la Parte anterior llamada Como Integrar Vue JS y Ruby on Rails – Parte 1 creamos un nuevo proyecto con Ruby on Rails 6, luego hicimos uso de webpack que viene ya con Ruby on Rails 6 para instalar Vue JS y verificamos si Vue JS se había instalado correctamente haciendo una integración básica mostrando el texto Hello Vue!, en esta parte 2 vamos a crear una tabla HTML con Bootstrap y convertirla en un componente, esto es para ver que ya tenemos Vue JS integrado en Rails y podemos crear cosas al menos un poquito más avanzadas.
Partes
Antes de continuar te invito a leer los siguientes artículos:
- Que es Ruby on Rails (RoR) y otros detalles
- Tu primer Hola Mundo con Ruby on Rails
- Que es Vue JS, Historia y otros detalles
- Tu primer Hola Mundo con Vue JS
- Como crear un CRUD con Ruby on Rails 6 y Bootstrap 4 – Parte 1
- Como Integrar React JS (16.13.1) en Ruby on Rails (6.0.3.2)
- Como usar Scopes en Ruby on Rails
- Creando una Aplicación Web similar a SoundCloud con Ruby on Rails 6 y Angular 10 – Parte 1
- Lee más artículos en la categoría Ruby on Rails.
Asimismo te invito a escuchar el Podcast: “Con Que Lenguaje De Programación Comenzar Para El Desarrollo Web”:
Spotify: | Sound Cloud: |
Bien ahora continuemos con el Post: Como Integrar Vue JS y Ruby on Rails – Parte 2.
Componente Postres
Para verificar que podemos crear cosas más allá de un simple mensaje Hello Vue!, recordemos que este mensaje lo mostramos en la Parte 1 de ese tutorial, vamos a mostrar una tabla HTML de Bootstrap 4 que lea datos en formato JSON, los datos JSON que leeré se encuentran en el repositorio GitHub de este proyecto, exactamente en este enlace https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/postres.json y contiene los siguientes datos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
// https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/postres.json [ { "id":"1", "nombre":"Torta de Chocolate", "stock":"35", "precio":"5.00", "url":"torta-de-chocolate", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/tc.jpg", "fecha":"2019-06-17 15:56:23" }, { "id":"2", "nombre":"Pie de Manzana", "stock":"45", "precio":"4.50", "url":"pie-de-manzana", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/pm.jpg", "fecha":"2018-08-11 16:25:33" }, { "id":"3", "nombre":"Arroz con Leche", "stock":"36", "precio":"2.50", "url":"arroz-con-leche", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/al.jpg", "fecha":"2018-08-11 16:25:36" }, { "id":"4", "nombre":"Gelatina de Fresa", "stock":"60", "precio":"1.50", "url":"gelatina-de-fresa", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/gf.jpg", "fecha":"2018-08-11 16:25:39" }, { "id":"5", "nombre":"Suspiro a la Limeña", "stock":"26", "precio":"6.00", "url":"suspiro-a-la-limeña", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/sl.jpg", "fecha":"2019-06-17 15:58:43" }, { "id":"6", "nombre":"Mazamorra Morada", "stock":"50", "precio":"3.00", "url":"mazamorra-morada", "img":"https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/img/mm.png", "fecha":"2018-08-11 16:25:45" } ] |
Antes de crear mi componente voy a instalar el paquete NPM axios que me permite leer datos en formato JSON, para instalarlo ejecuto el siguiente comando.
1 2 3 4 5 6 7 8 9 10 11 12 |
# Comando para instalar el paquete 'axios' npm install --save axios + axios@0.21.0 removed 3 packages, updated 1 package and audited 1124 packages in 7.195s 50 packages are looking for funding run `npm fund` for details found 0 vulnerabilities |
Una vez que instalamos axios, debemos de instanciarlo en el archivo hello_vue.js, este archivo se encuentra en app > javascript > packs > hello_vue.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/integrar_vuejs26_rubyonrails6 ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /channels ├── /packs ├── application.js ├── hello_vue.js Abrimos este Archivo ├── app.vue // ├── Postres.vue ├── /jobs ├── /mailers ├── /models ├── /views ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /node_modules ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .browserslistrc ├── .gitignore ├── .ruby-version ├── babel.config.js ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── postcss.config.js ├── Rakefile ├── README.md ├── yarn.lock |
Dentro del archivo hello_vue.js creamos una variable global y también una propiedad global para axios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* eslint no-console: 0 */ // Run this example by adding <%= javascript_pack_tag 'hello_vue' %> (and // <%= stylesheet_pack_tag 'hello_vue' %> if you have styles in your component) // to the head of your layout file, // like app/views/layouts/application.html.erb. // All it does is render <div>Hello Vue</div> at the bottom of the page. import Vue from 'vue' import App from '../app.vue' // Creamos una variable global 'axios' window.axios = require('axios'); // Creamos una propiedad global para axios Vue.prototype.$axios = axios document.addEventListener('DOMContentLoaded', () => { const app = new Vue({ render: h => h(App) }).$mount() document.body.appendChild(app.$el) console.log(app) }) // The above code uses Vue without the compiler, which means you cannot // use Vue to target elements in your existing html templates. You would // need to always use single file components. // To be able to target elements in your existing html/erb templates, // comment out the above code and uncomment the below // Add <%= javascript_pack_tag 'hello_vue' %> to your layout // Then add this markup to your html template: // // <div id='hello'> // {{message}} // <app></app> // </div> // import Vue from 'vue/dist/vue.esm' // import App from '../app.vue' // // document.addEventListener('DOMContentLoaded', () => { // const app = new Vue({ // el: '#hello', // data: { // message: "Can you say hello?" // }, // components: { App } // }) // }) // // // // If the project is using turbolinks, install 'vue-turbolinks': // // yarn add vue-turbolinks // // Then uncomment the code block below: // // import TurbolinksAdapter from 'vue-turbolinks' // import Vue from 'vue/dist/vue.esm' // import App from '../app.vue' // // Vue.use(TurbolinksAdapter) // // document.addEventListener('turbolinks:load', () => { // const app = new Vue({ // el: '#hello', // data: () => { // return { // message: "Can you say hello?" // } // }, // components: { App } // }) // }) |
Bien, ahora creo un archivo llamado Postres.vue que será el archivo para mi componente Postres, en este componente mostraré una lista de postres en una tabla HTML de Bootstrap 4, el archivo Postres.vue lo creamos en app > javascript > Postres.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/integrar_vuejs26_rubyonrails6 ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /channels ├── /packs ├── application.js ├── hello_vue.js ├── app.vue ├── Postres.vue // Creo y abro este Archivo ├── /jobs ├── /mailers ├── /models ├── /views ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /node_modules ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .browserslistrc ├── .gitignore ├── .ruby-version ├── babel.config.js ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── postcss.config.js ├── Rakefile ├── README.md ├── yarn.lock |
Abro el archivo Postres.vue y comienzo agregando la tabla HTML en la zona del template de mi componente Postres.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<template> <div class="table-responsive"> <table class="table mt-3" :items="data" :fields="fields"> <thead class="thead-dark"> <tr> <th scope="col">Nombre</th> <th scope="col">Precio</th> <th scope="col">Stock</th> <th scope="col">Imagen</th> </tr> </thead> <tbody> <tr v-for="producto in data" v-bind:key="producto.id"> <td>{{ producto.nombre }}</td> <td>{{ producto.precio }}</td> <td>{{ producto.stock }}</td> <td> <img v-bind:src="producto.img" class="img-fluid" width="30px" v-bind:alt="producto.nombre"> </td> </tr> </tbody> </table> </div> </template> |
En el código anterior, si te fijas en la tabla dentro del elemento <tbody></tbody> hago uso de la directiva v-for para listar los datos del archivo JSON.
1 2 3 4 5 6 7 8 9 10 11 12 |
<tbody> <tr v-for="producto in data" v-bind:key="producto.id"> <td>{{ producto.nombre }}</td> <td>{{ producto.precio }}</td> <td>{{ producto.stock }}</td> <td> <img v-bind:src="producto.img" class="img-fluid" width="30px" v-bind:alt="producto.nombre"> </td> </tr> </tbody> |
Ahora dentro de las etiquetas <script></script> creamos los campos que usaré del JSON, estos son nombre, precio, stock e img. Luego creo data para obtener los datos y pasarlos a la tabla, debajo leemos el JSON con axios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<script> export default { name: 'Postres', data: function () { return { // Campos fields: ['nombre', 'precio', 'stock', 'img'], // Obtenemos los datos en el array 'data' data: [] } }, // Leemos los datos JSON con axios mounted() { axios .get("https://raw.githubusercontent.com/collectivecloudperu/integrar_vuejs26_rubyonrails6/main/postres.json") .then(response => { this.data = response.data; console.log(this.data); }); }, } </script> |
Para que me mi componente Postres funcione, lo debo colocar en el componente app.vue que se creo por defecto luego de instalar Vue JS en Ruby on Rails (RoR), entonces abro el archivo app.vue que se encuentra en app > javascript > app.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/integrar_vuejs26_rubyonrails6 ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /channels ├── /packs ├── application.js ├── hello_vue.js ├── app.vue // Abro este Archivo ├── Postres.vue ├── /jobs ├── /mailers ├── /models ├── /views ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /node_modules ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .browserslistrc ├── .gitignore ├── .ruby-version ├── babel.config.js ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── postcss.config.js ├── Rakefile ├── README.md ├── yarn.lock |
Dentro del archivo app.vue coloco en las etiquetas <template></template> el componente Postres para que cargue en la vista.
1 2 3 4 5 6 7 8 9 10 11 |
<template> <div id="app"> <p>{{ message }}</p> <!-- Componente Postres --> <Postres/> </div> </template> |
Y dentro de las etiquetas <script></script> importo el componente Postres, también lo defino dentro de components y en message coloco el texto Lista de Postres.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<script> // Importo el componente 'Postres' import Postres from './Postres' export default { // Defino el componente 'Postres' components: { Postres, }, data: function () { return { message: "Lista de Postres" } } } </script |
Para mi entorno de desarrollo debo ejecutar 2 consolas al mismo tiempo, yo abriré 2 consolas GitBash, en la primera consola ejecuto el servidor de desarroll ode webpack que va a compilar todos los archivos del proyecto mediante el siguiente comando.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
./bin/webpack-dev-server i 「wdm」: Compiled successfully. i 「wdm」: Compiling... i 「wdm」: Hash: c49208c03dcd5e373961 Version: webpack 4.44.2 Time: 331ms Built at: 23/10/2020 19:50:57 Asset Size Chunks Chunk Names js/application-45c1bcf43c25641d8a80.js 508 KiB application [immutable] application js/application-45c1bcf43c25641d8a80.js.map 573 KiB application [dev] application js/hello_vue-76a8f7e38e6fe91050ab.js 721 KiB hello_vue [emitted] [immutable] hello_vue js/hello_vue-76a8f7e38e6fe91050ab.js.map 807 KiB hello_vue [emitted] [dev] hello_vue manifest.json 689 bytes [emitted] i 「wdm」: Compiled successfully. |
Y en la segunda consola ejecuto el servidor de Ruby on Rails 6 (RoR) con el siguiente comando.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
rails server => Booting Puma => Rails 6.0.3.4 application starting in development => Run `rails server --help` for more startup options *** SIGUSR2 not implemented, signal based restart unavailable! *** SIGUSR1 not implemented, signal based restart unavailable! *** SIGHUP not implemented, signal based logs reopening unavailable! Puma starting in single mode... * Version 4.3.6 (ruby 2.7.2-p137), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://[::1]:3000 * Listening on tcp://127.0.0.1:3000 Use Ctrl-C to stop Started GET "/" for ::1 at 2020-10-23 19:51:37 -0500 (2.8ms) SELECT sqlite_version(*) Processing by AppController#index as HTML Rendering app/index.html.erb within layouts/application Rendered app/index.html.erb within layouts/application (Duration: 2.1ms | Allocations: 258) Completed 200 OK in 44ms (Views: 33.6ms | ActiveRecord: 0.0ms | Allocations: 7622) |
Si voy a la dirección local http://localhost:3000/ en el navegador, debo de ver los datos sin problemas.
Con esto hemos realizado algo más que un simple mensaje Hello Vue!, recordemos que este mensaje lo mostramos en la Parte 1 de ese tutorial.
Bien hasta aquí terminamos esta primera parte en donde creamos un componente llamado Postres para listar datos JSON en una tabla HTML.
Ten Paciencia, lo que quiero es que conozcas bien como crear este proyecto y no llenarte el capitulo de mucho contenido porque te puedes marear y no tendrás un óptimo aprendizaje.
Nota (s)
- En la 3ra parte de este tutorial vamos a estilizar la interface agregando una tabla HTML de Bootstrap 4 y otros detalles.
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.