Как создать внешнее приложение Vue.js Shopify с помощью Polaris

Опубликовано: 2019-06-17

Примечание: эта статья посвящена созданию одностраничного приложения Vue.js поверх приложения Laravel, созданного в этой статье. Прежде чем читать это, убедитесь, что вы прочитали предыдущую статью о создании приложения с помощью Laravel, так как мы будем использовать этот существующий код.

Что такое Vue.js?

Vue.js — это интерфейсный фреймворк JavaScript, сравнимый с аналогичными фреймворками, такими как React, и изначально производный от AngularJS. По сравнению с другими фреймворками он несколько легче, так что вы можете использовать его только как уровень представления, только если хотите, но можете ли вы также масштабировать его с полным управлением состоянием или использовать фреймворк поверх Vue, такой как как Nuxt.js. Вы можете узнать больше о Vue.js здесь.

Что такое Поларис?

Polaris — это платформа проектирования пользовательского интерфейса Shopify, сравнимая с другими средами пользовательского интерфейса, такими как Bootstrap или SemanticUI. В Eastside Co у нас есть порт библиотеки Vue.js для согласованного пользовательского интерфейса в наших приложениях.

Настройка Vue.js для компиляции

Vue поставляется с Laravel из коробки, но есть некоторые настройки, которые упростят разработку. Laravel поставляется с Laravel Mix, который представляет собой аккуратную оболочку Webpack. Webpack компилирует все ресурсы вашего внешнего интерфейса до того, что вы хотите предоставить браузеру клиента — Laravel поставляется с реализацией этого с множеством встроенных значений по умолчанию. Давайте немного оптимизируем вывод Webpack. Откройте webpack.mix.js в корне вашего проекта. Измените его на:

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

Здесь мы сказали веб-пакету создавать псевдонимы файлов в папке resources/assets/js для использования в операторах импорта и распознавать расширения .vue и .js, чтобы нам не нужно было использовать полные имена файлов в JavaScript. Опция devtool также заставляет wepack генерировать исходные карты для нашего скомпилированного JS, чтобы ускорить отладку в браузере.

Теперь мы можем запустить npm, чтобы установить наши внешние зависимости, и запустить сервер, чтобы следить за изменениями в наших файлах JavaScript. Подойдите к терминалу и введите:

 Npm install Npm run dev

Теперь нам нужно подключить наш базовый маршрут Laravel к нашему приложению Vue.

Настройка Vue.js в Laravel

Нам нужно немного подправить, чтобы получить приличный каркас от Laravel до Vue. Первое, что нам нужно сделать, это импортировать Vue в базовый шаблон Twig, а затем создать точку входа для нашего приложения.

Чтобы ничего не путать, давайте создадим новый маршрут, метод контроллера и шаблон ветки.

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

Поскольку Vue будет использовать конечную точку, которую мы создадим в Laravel, мы отказались от ShopifyAPI, но он будет использоваться позже. Теперь нам нужно подключить Vue к нашему новому шаблону Twig, который мы назвали vueapp. Создайте следующий файл:

 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>

Токен CSRF важен — Laravel передает токен Vue, чтобы предотвратить подделку межсайтовых запросов. Здесь происходит еще несколько вещей: во-первых, <div id=”app”> — это тег div, к которому мы привязываем Vue, а <app-entry> — это пользовательский компонент Vue, который мы еще не создали, поэтому мы построим это в ближайшее время.

Создание строительных лесов Vue

Далее нам нужно создать точку входа для нашего приложения. Мы относимся к нему как к компоненту, но размещаем его вне папки встроенных компонентов, поскольку это точка входа для остальной части Vue. Создайте новый файл:

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

Итак, последняя часть — зарегистрировать компонент <app-entry> в загрузчике Vue. Направляйтесь к

ресурсы/js/app.js

Здесь много комментариев из шаблонного кода Laravel — удалите весь код и замените его следующим:

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

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

http://локальный:8000/vueapp

И мы можем видеть с открытыми инструментами разработчика браузера, что vue инициализирован. Мы готовы!

Создание конечной точки API

Теперь у нас есть точка входа, мы создадим новый компонент, который будет отображать список продуктов. Прежде чем мы сможем создать внешний компонент, нам нужно создать конечную точку API, которая фактически будет прокси-сервером от API Shopify.

Laravel поставляется с автоматически настроенным базовым корнем /api/ для вызовов API с отдельной логикой от маршрутов HTTP. Добавьте следующую строку:

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

Перейдите к своей конечной точке, и вы должны вернуть данные:

Это все, что касается конечной точки API — мы не используем никакой авторизации, так как это базовое руководство, но вы можете проверить https://laravel.com/docs/5.7/authentication для получения дополнительной информации о пользовательских реализациях аутентификации, включая базовую, несущую токены и oAuth.

Создание компонента и получение данных API

Давайте создадим компонент, в котором мы будем рендерить продукты — создадим новый файл в каталоге компонентов:

 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>

Теперь зарегистрируйте компонент в Vue:

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

И поместите компонент в наш шаблон приложения:

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

Есть несколько вещей, которые нужно объяснить с шаблоном Vue, прежде чем мы сможем получать продукты из конечной точки API и циклически перебирать их. Во-первых, логика <script> — у каждого компонента Vue есть жизненный цикл, который можно использовать на разных этапах и который позволяет вам создавать события, устанавливать наблюдателей; все, что вам нужно, может быть закодировано здесь.

Вы можете узнать больше о компонентах кодирования здесь. Мы начали с простого добавления метода data(), который возвращает данные, которые вы будете использовать или привязывать к компоненту. Здесь мы назвали ключ apidata и создали его как пустую строку — причина этого в том, что в нем будут храниться продукты для компонентов — после того, как мы закодируем выборку после загрузки модуля в жизненном цикле.

Чтобы заполнить эти данные, мы добавим метод, использующий axios, который будет вызываться при выполнении метода created() в жизненном цикле.

 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>

Продукты теперь будут доступны для шаблона под apidata — используя цикл Vue v-for, мы можем перебирать массив в шаблоне:

Рендеринг в Polaris

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

Загрузите страницу и бинго! Вот наши продукты вынесены:

При разработке в Vue расширение Vue devtools чрезвычайно полезно для отладки. Вы можете увидеть эти инструменты здесь.

Если мы используем devtools, мы можем увидеть значение, которое принял наш объект данных apidata (то есть ответ API, который был преобразован в массив):

Подсечка в Polaris

Итак, наша последняя часть — использовать порт EastsideCo Vue Polaris для рендеринга наших продуктов. Устанавливаем библиотеку Polaris через npm:

 Npm install @eastsideco/polaris-vue

Затем мы привязываем его к нашему приложению 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', });

Теперь у нас будет доступ к пользовательским тегам HTML с именами polaris — вы можете увидеть полный список перенесенных тегов на странице документации по адресу http://demo.polaris-vue.eastsideco.io/

Наш шаблон теперь выглядит следующим образом:

 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>

Здесь происходит довольно много всего, так что давайте разберемся -

Открывающий <div> — это просто контейнер, потому что компонентам Vue.js всегда нужен корневой элемент. Затем мы определяем контейнер CSS для страницы, используя <polaris-page> .

То система компоновки довольно хорошо определена в документах, упомянутых ранее.

Однако <polaris-resource-list> является более сложным компонентом — он принимает переданную поддержку, которую в данном случае мы передаем в ответ на созданную нами конечную точку API. Затем в списке ресурсов есть слот с ограниченной областью действия, в котором мы создаем элемент <polaris-resource-list-item> . Внутри слота вы определяете другой слот — «элемент» (подумайте об этом как об итерации цикла foreach в качестве простого объяснения), а затем вся область слота (которая является apidata) называется реквизитами слота. Итак, чтобы получить доступ в этот момент к свойствам текущих итераций, мы используем props.item. Эти атрибуты, такие как attribute-one и media, анализируются компонентом и отображаются в библиотеке polaris. В результате получается базовый список продуктов:

Вот и мы — список продуктов, подключенных к Vue Polaris.

Вы можете найти рабочую копию этого демонстрационного кода в нашем репозитории по адресу https://github.com/EastsideCo/polaris-vue.

В Eastside Co есть команда разработчиков приложений, поэтому, если у вас есть какие-либо вопросы, не стесняйтесь обращаться к нам!