So erstellen Sie eine Vue.js-Shopify-Frontend-App mit Polaris

Veröffentlicht: 2019-06-17

Hinweis: In diesem Artikel geht es um das Erstellen einer Vue.js-Single-Page-App auf der Grundlage der in diesem Artikel erstellten Laravel-App. Bevor Sie dies lesen, stellen Sie sicher, dass Sie den vorherigen Artikel über das Erstellen einer App mit Laravel gelesen haben, da wir diesen vorhandenen Code verwenden werden.

Was ist Vue.js?

Vue.js ist ein JavaScript-Frontend-Framework, vergleichbar mit ähnlichen Frameworks wie React und ursprünglich von AngularJS abgeleitet. Im Vergleich zu den anderen Frameworks ist es etwas leichter konzipiert, so dass Sie es nur als Präsentationsschicht verwenden können, wenn Sie möchten - aber Sie können es auch massiv mit vollständigem Statusmanagement skalieren oder ein Framework auf Vue verwenden, z als Nuxt.js. Weitere Informationen zu Vue.js finden Sie hier.

Was ist Polaris?

Polaris ist das UI-Design-Framework von Shopify, vergleichbar mit anderen UI-Frameworks wie Bootstrap oder SemanticUI. Bei Eastside Co haben wir eine Vue.js-Portierung der Bibliothek für eine konsistente Benutzeroberfläche in unseren Apps.

Vue.js zum Kompilieren einrichten

Vue wird standardmäßig mit Laravel geliefert, aber es gibt einige Anpassungen, die die Entwicklung erleichtern. Laravel wird mit Laravel Mix geliefert, einem ordentlichen Wrapper für Webpack. Webpack kompiliert alle Ihre Frontend-Assets auf das, was Sie dem Browser des Clients zur Verfügung stellen möchten - Laravel enthält eine Implementierung davon mit vielen integrierten Standardeinstellungen. Lassen Sie uns die Ausgabe von Webpack ein wenig optimieren. Öffnen Sie webpack.mix.js im Stammverzeichnis Ihres Projekts. Ändern Sie es in:

 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” });

Hier haben wir webpack angewiesen, Dateien im Ordner „resources/assets/js“ zur Verwendung in Importanweisungen zu aliasieren und die Erweiterungen „.vue“ und „.js“ zu erkennen, sodass wir in JavaScript keine vollständigen Dateinamen verwenden müssen. Die devtool-Option lässt wepack auch Quellkarten für unser kompiliertes JS generieren, um das Debuggen im Browser schneller zu unterstützen.

Wir können jetzt npm ausführen, um unsere Front-End-Abhängigkeiten zu installieren, und einen Server ausführen, um nach Änderungen an unseren JavaScript-Dateien zu suchen. Gehen Sie zum Terminal und geben Sie Folgendes ein:

 Npm install Npm run dev

Jetzt müssen wir unsere Laravel-Basisroute in unsere Vue-App einbinden.

Vue.js in Laravel einrichten

Wir müssen ein wenig optimieren, um ein anständiges Gerüst von Laravel zu Vue zu bekommen. Als erstes müssen wir Vue in eine Basis-Twig-Vorlage importieren und dann einen Einstiegspunkt für unsere App erstellen.

Damit wir die Dinge nicht verwirren, erstellen wir eine neue Route, Controller-Methode und Twig-Vorlage.

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

Da Vue einen von uns in Laravel erstellten Endpunkt verwenden wird, haben wir die ShopifyAPI fallen gelassen - aber diese wird später verwendet. Jetzt müssen wir Vue mit unserer neuen Twig-Vorlage verbinden, die wir vueapp genannt haben. Erstellen Sie die folgende Datei:

 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>

Das CSRF-Token ist wichtig – Laravel übergibt ein Token an Vue, um Cross-Site-Request-Fälschungen zu verhindern. Hier passieren noch ein paar andere Dinge - erstens ist <div id=”app”> das div-Tag, an das wir Vue binden, und <app-entry> ist eine benutzerdefinierte Vue-Komponente, die wir noch nicht erstellt haben das bauen wir in Kürze aus.

Bau von Vue-Gerüsten

Als Nächstes müssen wir unseren App-Einstiegspunkt für unsere App erstellen. Wir behandeln es wie eine Komponente, platzieren es aber außerhalb des Ordners für eingebaute Komponenten, da es der Front-End-Einstiegspunkt für den Rest von Vue ist. Erstellen Sie eine neue Datei:

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

Der letzte Teil besteht also darin, die Komponente <app-entry> im Vue-Bootloader zu registrieren. Gehen Sie zu

resources/js/app.js

Hier sind viele Kommentare aus dem Laravel-Boilerplate-Code - löschen Sie den gesamten Code und ersetzen Sie ihn durch Folgendes:

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

Unsere Eingabekomponente wurde also geladen und Vue wurde gebootet und an die div id-App gebunden. Laden Sie die Route in Ihren Browser:

http://localhost:8000/vueapp

Und wir können bei geöffneten Browser-Entwicklungstools sehen, dass vue initialisiert ist. Wir sind am Laufen!

Erstellen eines API-Endpunkts

Jetzt haben wir einen Einstiegspunkt, an dem wir eine neue Komponente erstellen, die eine Liste von Produkten ausgeben wird. Bevor wir die Frontend-Komponente erstellen können, müssen wir einen API-Endpunkt erstellen, der effektiv ein Proxy der Shopify-API ist.

Laravel wird mit einem automatisch konfigurierten /api/-Basisstamm für API-Aufrufe geliefert, mit getrennter Logik von HTTP-Routen. Fügen Sie die folgende Zeile hinzu:

 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; }

Navigieren Sie zu Ihrem Endpunkt und Sie sollten die Daten zurückerhalten:

Das war es für den API-Endpunkt – wir verwenden keine Autorisierung, da dies eine grundlegende Anleitung ist, aber Sie können https://laravel.com/docs/5.7/authentication für weitere Informationen zu benutzerdefinierten Authentifizierungsimplementierungen, einschließlich Basic, Bearer, besuchen Token und oAuth.

Erstellen einer Komponente und Abrufen von API-Daten

Lassen Sie uns die Komponente erstellen, in der wir die Produkte rendern werden - erstellen Sie eine neue Datei im Komponentenverzeichnis:

 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>

Registrieren Sie nun die Komponente in Vue:

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

Und ziehen Sie die Komponente in unsere App-Vorlage:

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

Es gibt ein paar Dinge, die mit der Vue-Vorlage erklärt werden müssen, bevor wir Produkte vom API-Endpunkt abrufen und sie durchlaufen können. Erstens die Logik hinter dem <script> -Tag – jede Vue-Komponente hat einen Lebenszyklus, der in verschiedenen Phasen angezapft werden kann und es Ihnen ermöglicht, Ereignisse auszusenden, Beobachter festzulegen; Alles, was Sie brauchen, kann hier codiert werden.

Hier erfahren Sie mehr über die Codierung von Komponenten. Wir haben damit begonnen, einfach die Methode data() hinzuzufügen, die Daten zurückgibt, die Sie verwenden oder an die Komponente binden. Wir haben hier einen Schlüssel apidata genannt und ihn als leere Zeichenfolge erstellt – der Grund dafür ist, dass dort die Produkte für die Komponenten gespeichert werden – sobald wir einen Abruf codieren, nachdem das Modul im Lebenszyklus geladen wurde.

Um diese Daten zu füllen, fügen wir eine Methode hinzu, die Axios verwendet, die aufgerufen wird, wenn die Methode created() im Lebenszyklus ausgeführt wird.

 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>

Produkte sind jetzt für die Vorlage unter apidata verfügbar - mit der v-for-Schleife von Vue können wir über das Array in der Vorlage iterieren:

Rendern in Polaris

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

Laden Sie die Seite und Bingo! Hier sind unsere Produkte gerendert:

Bei der Entwicklung in Vue ist die Vue devtools-Erweiterung äußerst nützlich für das Debugging. Sie können diese Tools hier sehen.

Wenn wir die devtools verwenden, können wir den Wert sehen, den unser apidata-Datenobjekt angenommen hat (d. h. die Antwort der API, die in ein Array umgewandelt wurde):

Einhaken in Polaris

Unser letzter Teil besteht also darin, den Vue Polaris-Port von EastsideCo zu verwenden, um unsere Produkte zu rendern. Wir installieren die Polaris-Bibliothek über npm:

 Npm install @eastsideco/polaris-vue

Dann binden wir es in unsere Vue-App ein:

 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', });

Wir haben jetzt Zugriff auf benutzerdefinierte HTML-Tags mit dem Namen Polaris – Sie können eine vollständige Liste der portierten Tags auf der Dokumentseite unter http://demo.polaris-vue.eastsideco.io/ sehen.

Unsere Vorlage sieht jetzt wie folgt aus:

 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>

Hier ist ziemlich viel los, also lass es uns aufschlüsseln -

Das öffnende <div> ist nur ein Container - das liegt daran, dass Vue.js-Komponenten immer ein Root-Element benötigen. Anschließend definieren wir mit <polaris-page> einen CSS-Container für die Seite.

Der Das Layoutsystem ist in den zuvor erwähnten Dokumenten recht gut definiert.

Die <polaris-resource-list> jedoch eine komplexere Komponente – sie benötigt eine übergebene Stütze, die wir in diesem Fall in der Antwort an den von uns erstellten API-Endpunkt übergeben. Die Ressourcenliste hat dann einen Scoped-Slot, in dem wir ein <polaris-resource-list-item> erstellen. Innerhalb des Slots definieren Sie einen weiteren Slot – „item“ (stellen Sie sich dies als eine Iteration über eine foreach-Schleife als einfache Erklärung vor) und dann wird der gesamte Bereich des Slots (der apidata ist) als Requisiten des Slots benannt. Um also an dieser Stelle Zugriff auf die Eigenschaften der aktuellen Iterationen zu erhalten, verwenden wir props.item. Diese Attribute wie Attribut Eins und Medien werden von der Komponente analysiert und in der Polaris-Bibliothek gerendert. Das Ergebnis ist eine grundlegende Produktliste:

Und da sind wir – eine Liste von Produkten, die an Vue Polaris angeschlossen sind.

Eine funktionierende Kopie dieses Democodes finden Sie in unserem Repo unter https://github.com/EastsideCo/polaris-vue.

Bei Eastside Co haben wir ein App-Entwicklungsteam. Wenn Sie also Fragen haben, zögern Sie nicht, sich mit uns in Verbindung zu setzen!