วิธีสร้างแอป Vue.js Shopify Frontend ด้วย Polaris

เผยแพร่แล้ว: 2019-06-17

หมายเหตุ: บทความนี้เกี่ยวกับการสร้างแอปหน้าเดียว Vue.js ที่ด้านบนของแอป Laravel ที่สร้างขึ้นในบทความนี้ ก่อนอ่านสิ่งนี้ อย่าลืมอ่านบทความก่อนหน้าเกี่ยวกับการสร้างแอปด้วย Laravel เนื่องจากเราจะใช้โค้ดที่มีอยู่นั้น

Vue.js คืออะไร?

Vue.js เป็นเฟรมเวิร์กส่วนหน้าของ JavaScript เทียบได้กับเฟรมเวิร์กที่คล้ายคลึงกัน เช่น React และได้มาจาก AngularJS ดั้งเดิม เมื่อเทียบกับเฟรมเวิร์กอื่นๆ มันถูกออกแบบให้เบากว่าเล็กน้อย เพื่อให้คุณสามารถใช้มันเป็นเลเยอร์การนำเสนอได้ก็ต่อเมื่อคุณต้องการ - แต่คุณยังสามารถขยายขนาดอย่างหนาแน่นด้วยการจัดการสถานะเต็มรูปแบบ หรือใช้เฟรมเวิร์กที่ด้านบนของ Vue ได้ เป็น Nuxt.js คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับ Vue.js ได้ที่นี่

โพลาริสคืออะไร?

Polaris คือเฟรมเวิร์กการออกแบบ UI ของ Shopify ซึ่งเทียบได้กับเฟรมเวิร์ก UI อื่นๆ เช่น Bootstrap หรือ SemanticUI ที่ Eastside Co เรามีพอร์ต Vue.js ของไลบรารีสำหรับ UI ที่สอดคล้องกันในแอปของเรา

การตั้งค่า 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” });

ในที่นี้ เราได้แจ้งให้ webpack ทราบถึงไฟล์นามแฝงภายในโฟลเดอร์ 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 bootloader มุ่งหน้าสู่

ทรัพยากร/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://localhost:8000/vueapp

และเราสามารถเห็นได้เมื่อเปิด devtools ของเบราว์เซอร์ว่า 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 ซึ่งจะถูกเรียกเมื่อเมธอด create() ถูกดำเนินการในวงจรชีวิต

 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 โดยใช้ v-for loop ของ Vue เราสามารถวนซ้ำอาร์เรย์ในเทมเพลตได้:

การแสดงผลใน 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 ที่ส่งไปยังอาร์เรย์):

เกี่ยวในโพลาริส

ดังนั้นส่วนสุดท้ายของเราคือการใช้พอร์ต Vue Polaris ของ EastsideCo เพื่อแสดงผลผลิตภัณฑ์ของเรา เราติดตั้งห้องสมุด 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 แอตทริบิวต์เหล่านี้ เช่น แอตทริบิวต์-หนึ่ง และสื่อ แยกวิเคราะห์โดยคอมโพเนนต์และแสดงผลในไลบรารีโพลาริส ผลลัพธ์คือรายการผลิตภัณฑ์พื้นฐาน:

และเราอยู่ที่นั่น - รายการผลิตภัณฑ์ที่เชื่อมต่อกับ Vue Polaris

คุณสามารถหาสำเนาการทำงานของโค้ดสาธิตนี้ได้จาก repo ของเราที่ https://github.com/EastsideCo/polaris-vue

ที่ Eastside Co เรามีทีมพัฒนาแอพ หากคุณมีคำถามใด ๆ โปรดติดต่อเรา!