Cómo construir una aplicación Vue.js Shopify Frontend con Polaris

Publicado: 2019-06-17

Nota: este artículo trata sobre la creación de una aplicación de una sola página Vue.js sobre la aplicación Laravel creada en este artículo. Antes de leer esto, asegúrese de haber leído el artículo anterior sobre la creación de una aplicación con Laravel, ya que usaremos ese código existente.

¿Qué es Vue.js?

Vue.js es un framework front-end de JavaScript, comparable a frameworks similares como React y originalmente derivado de AngularJS. En comparación con los otros marcos, está diseñado para ser algo más liviano, de modo que puede usarlo solo como una capa de presentación si lo desea, pero también puede escalarlo masivamente con administración de estado completa o usar un marco encima de Vue como como Nuxt.js. Puede encontrar más información sobre Vue.js aquí.

¿Qué es Polaris?

Polaris es el marco de diseño de interfaz de usuario de Shopify, comparable a otros marcos de interfaz de usuario como Bootstrap o SemanticUI. En Eastside Co, tenemos un puerto Vue.js de la biblioteca para una interfaz de usuario consistente en nuestras aplicaciones.

Configurar Vue.js para compilar

Vue viene con Laravel listo para usar, pero hay algunas personalizaciones que facilitarán el desarrollo. Laravel viene con Laravel Mix, que es un envoltorio limpio alrededor de Webpack. Webpack compila todos sus activos frontend hasta lo que desea servir al navegador del cliente: Laravel viene con una implementación de esto con muchos valores predeterminados integrados. Optimicemos un poco la salida de Webpack. Abra webpack.mix.js en la raíz de su proyecto. cambiarlo a:

 mix.js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css'); mix.webpackConfig({ resolve: { extensions: [ '.js', '.vue', ], alias: { '@': path.resolve(__dirname, 'resources/assets/js'), }, }, devtool: “inline-source-map” });

Aquí le hemos dicho a webpack que cree un alias de los archivos dentro de la carpeta resources/assets/js para usarlos en declaraciones de importación, y que reconozca las extensiones .vue y .js para que no necesitemos usar nombres de archivo completos en JavaScript. La opción devtool también hace que wepack genere mapas de origen para nuestro JS compilado para ayudar a la depuración en el navegador más rápido.

Ahora podemos ejecutar npm para instalar nuestras dependencias frontales y ejecutar un servidor para observar los cambios en nuestros archivos JavaScript. Dirígete a la terminal y escribe:

 Npm install Npm run dev

Ahora, necesitamos conectar nuestra ruta base de Laravel a nuestra aplicación Vue.

Configurando Vue.js en Laravel

Necesitamos hacer algunos ajustes para obtener un andamio decente de Laravel a Vue. Lo primero que debemos hacer es importar Vue a una plantilla base de Twig y luego crear un punto de entrada para nuestra aplicación.

Para no confundir las cosas, creemos una nueva ruta, método de controlador y plantilla twig.

 routes/web.php Route::get('/vueapp', 'ShopifyController@vueapp'); app/Http/Controllers/ShopifyController.php public function vueapp() { return view('vueapp'); }

Como Vue va a usar un punto final que creamos en Laravel, nos hemos deshecho de ShopifyAPI, pero se usará más adelante. Ahora necesitamos conectar Vue a nuestra nueva plantilla Twig, a la que llamamos vueapp. Cree el siguiente archivo:

 resources/views/vueapp.twig <!DOCTYPE html> <html> <head> <title>My VueJs app</title> <meta name="csrf-token" content="{{ csrf_token() }}"> </head> <body> <div> <app-entry></app-entry> </div> <script src="{{ asset('js/app.js') }}"></script> </body> </html>

El token CSRF es importante: Laravel pasa un token a Vue para evitar falsificaciones de solicitudes entre sitios. Aquí suceden un par de cosas más: en primer lugar, <div id=”app”> es la etiqueta div a la que vinculamos Vue, y <app-entry> es un componente personalizado de Vue que aún no hemos creado, por lo que lo construiremos en breve.

Construcción de andamios Vue

A continuación, debemos crear nuestro punto de entrada de la aplicación para nuestra aplicación. Lo tratamos como un componente, pero lo ubicamos fuera de la carpeta de componentes integrados, ya que es el punto de entrada frontal para el resto de Vue. Crear un nuevo archivo:

 resources/js/AppEntry.vue <template> <p>App Entry Point</p> </template> <script> export default { mounted() { console.log('Rendered app entry point') } } </script>

Entonces, la última parte es registrar el componente <app-entry> en el gestor de arranque de Vue. Dirigirse a

recursos/js/app.js

Hay muchos comentarios aquí del código repetitivo de Laravel: elimine todo el código y reemplácelo con lo siguiente:

 require('./bootstrap'); window.Vue = require('vue'); Vue.component('app-entry', require('./AppEntry.vue').default); const app = new Vue({ el: '#app', });

Entonces, nuestro componente de entrada se cargó y Vue se inició, vinculado a la aplicación div id. Cargue la ruta en su navegador:

http://localhost:8000/vueapp

Y podemos ver con las herramientas de desarrollo de nuestro navegador abiertas que vue está inicializado. ¡Estamos en funcionamiento!

Creación de un punto final de API

Ahora que tenemos un punto de entrada, crearemos un nuevo componente que generará una lista de productos. Antes de que podamos crear el componente front-end, necesitaremos crear un punto final de API que será efectivamente un proxy de la API de Shopify.

Laravel viene con una raíz base /api/ configurada automáticamente para llamadas API, con lógica separada de las rutas HTTP. Agregue la siguiente línea:

 routes/api.php Route::get('/products', 'ShopifyController@products'); We've not created the 'products' method in the ShopifyController, so let's create it: app/Http/Controllers/ShopifyController.php public function products() { $shopifyApi = app('ShopifyAPI'); $products = $shopifyApi->call('GET', '/admin/products.json'); return (array) $products; }

Navegue a su punto final y debería recuperar los datos:

Eso es todo para el punto final de la API: no estamos usando ninguna autorización, ya que esta es una guía básica, pero puede consultar https://laravel.com/docs/5.7/authentication para obtener más información sobre las implementaciones de autenticación personalizadas, incluido el portador básico. fichas y oAuth.

Crear un componente y obtener datos de la API

Vamos a crear el componente en el que vamos a representar los productos: cree un nuevo archivo en el directorio de componentes:

 resources/js/components/ProductComponent.vue <template> <div id=”root element”>Vue components always need one root element</div> </template> <script> export default { mounted() { console.log('Component loaded') }, data() { return { apidata: "" } }, } </script>

Ahora registre el componente en Vue:

 resources/js/app.js Vue.component('shopify-products', require('./components/ProductsComponent.vue').default);

Y suelte el componente en nuestra plantilla de aplicación:

 <template> <div> <shopify-products></shopify-products> </div> </template>

Hay algunas cosas que explicar con la plantilla de Vue antes de que podamos obtener productos del punto final de API y recorrerlos. En primer lugar, la lógica detrás de la etiqueta <script> : cada componente de Vue tiene un ciclo de vida que se puede aprovechar en varias etapas y le permite emitir eventos, establecer observadores; todo lo que necesite se puede codificar aquí.

Puede obtener más información sobre la codificación de componentes aquí. Comenzamos simplemente agregando el método data(), que devuelve datos que usará o vinculará al componente. Nombramos una clave aquí apidata y la creamos como una cadena en blanco; la razón de esto es que será donde se almacenarán los productos para los componentes, una vez que codificamos en una búsqueda después de que el módulo se haya cargado en el ciclo de vida.

Para completar estos datos, vamos a agregar un método, usando axios, que se llamará cuando se ejecute el método created() en el ciclo de vida.

 resources/js/components/ProductComponent.vue <script> export default { mounted() { console.log('Component loaded') }, created() { this.fetchProducts() }, data() { return { apidata: "" } }, methods: { fetchProducts() { axios.get('/api/products').then(response => { this.apidata = response.data.products }) } } } </script>

Los productos ahora estarán disponibles para la plantilla en apidata: al usar el bucle v-for de Vue, podemos iterar sobre la matriz en la plantilla:

Renderizado en Polaris

 <template> <div> <div class="card" v-for="product in apidata"> <h5>{{ product.title }}</h5> <p>{{ product.body_html }}</p> </div> </div> </template>

¡Carga la página y bingo! Aquí están nuestros productos presentados:

Al desarrollar en Vue, la extensión Vue devtools es extremadamente útil para la depuración. Puedes ver estas herramientas aquí.

Si usamos las herramientas de desarrollo, podemos ver el valor que ha tomado nuestro objeto de datos apidata (es decir, la respuesta de la API que se ha convertido en una matriz):

Enganchando en Polaris

Entonces, nuestra parte final es usar el puerto Vue Polaris de EastsideCo para renderizar nuestros productos. Instalamos la librería Polaris vía npm:

 Npm install @eastsideco/polaris-vue

Luego lo vinculamos a nuestra aplicación Vue:

 resources/js/app.js require('./bootstrap'); import PolarisVue from '@eastsideco/polaris-vue/lib/polaris-vue'; import PolarisVueCss from '@eastsideco/polaris-vue/lib/polaris-vue.css'; window.Vue = require('vue'); Vue.component('app-entry', require('./AppEntry.vue').default); Vue.component('shopify-products', require('./components/ProductsComponent.vue').default); Vue.use(PolarisVue); const app = new Vue({ el: '#app', });

Ahora tendremos acceso a las etiquetas HTML personalizadas con nombre de polaris; puede ver una lista completa de las etiquetas portadas en la página de documentos en http://demo.polaris-vue.eastsideco.io/

Nuestra plantilla ahora está refactorizada para verse así:

 resources/js/components/ProductsComponent.vue <template> <div> <polaris-page> <polaris-card sectioned title="My Shopify Vue App"> Uses EastsideCo port of Polaris to Vue </polaris-card> <polaris-card sectioned> <polaris-layout-section> <polaris-resource-list :items="apidata"> <template slot="item" slot-scope="props"> <polaris-resource-list-item :attribute-one="props.item.title" :attribute-two="props.item.created_at" :media="props.item.image"> </polaris-resource-list-item> </template> </polaris-resource-list> </polaris-layout-section> </polaris-card> </polaris-page> </div> </template>

Están sucediendo muchas cosas aquí, así que analicemos:

El <div> de apertura es solo un contenedor; esto se debe a que los componentes de Vue.js siempre necesitan un elemento raíz. Luego definimos un contenedor CSS para la página usando <polaris-page> .

El El sistema de diseño se define bastante bien en los documentos mencionados anteriormente.

Sin embargo <polaris-resource-list> es un componente más complejo: requiere que se le pase una prop, que en este caso estamos pasando en la respuesta al extremo de la API que creamos. La lista de recursos tiene una ranura con ámbito, en la que estamos creando un <polaris-resource-list-item> . Dentro de la ranura, define otra ranura: "elemento" (piense en esto como una iteración sobre un ciclo foreach como una explicación simple) y luego todo el alcance de la ranura (que es apidata) se nombra como accesorios de la ranura. Entonces, para obtener acceso en este punto a las propiedades de las iteraciones actuales, usamos props.item. Estos atributos, como el atributo uno y los medios, son analizados por el componente y representados en la biblioteca polaris. El resultado es una lista básica de productos:

Y ahí estamos: una lista de productos conectados a Vue Polaris.

Puede encontrar una copia funcional de este código de demostración en nuestro repositorio en https://github.com/EastsideCo/polaris-vue.

En Eastside Co contamos con un equipo de desarrollo de aplicaciones, por lo que si tiene alguna pregunta, ¡no dude en ponerse en contacto!