มีอะไรใหม่ใน Vue 3?
เผยแพร่แล้ว: 2022-03-10ด้วยการเปิดตัวของ Vue 3 นักพัฒนาจะต้องทำการอัปเกรดจาก Vue 2 เนื่องจากมาพร้อมกับฟีเจอร์ใหม่จำนวนหนึ่งซึ่งมีประโยชน์มากในการสร้างส่วนประกอบที่อ่านง่ายและบำรุงรักษาได้ และปรับปรุงวิธีจัดโครงสร้างแอปพลิเคชันของเราใน Vue เราจะมาดูคุณสมบัติบางอย่างเหล่านี้ในบทความนี้
ในตอนท้ายของบทช่วยสอนนี้ ผู้อ่านจะ;
- รู้จัก
provide / inject
และวิธีใช้งาน - มีความเข้าใจพื้นฐานเกี่ยวกับ Teleport และวิธีใช้งาน
- รู้เกี่ยวกับ Fragment และวิธีใช้งาน
- ทราบเกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้นกับ Global Vue API
- ทราบเกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้นกับ API เหตุการณ์
บทความนี้มุ่งเป้าไปที่ผู้ที่มีความเข้าใจอย่างถูกต้องเกี่ยวกับ Vue 2.x คุณสามารถค้นหาโค้ดทั้งหมดที่ใช้ในตัวอย่างนี้ใน GitHub
provide / inject
ใน Vue 2.x เรามี props
ที่ทำให้ง่ายต่อการส่งข้อมูล (สตริง อาร์เรย์ อ็อบเจ็กต์ ฯลฯ) จากองค์ประกอบหลักไปยังองค์ประกอบย่อยโดยตรง แต่ในระหว่างการพัฒนา เรามักพบกรณีที่เราต้องส่งข้อมูลจากองค์ประกอบหลักไปยังองค์ประกอบที่ซ้อนกันอย่างลึกซึ่งยากต่อการทำกับ props
ส่งผลให้มีการใช้ Vuex Store, Event Hub และบางครั้งส่งข้อมูลผ่านส่วนประกอบที่ซ้อนกันอย่างลึกล้ำ มาดูแอพง่าย ๆ กัน
สิ่งสำคัญคือต้องทราบว่า Vue 2.2.0 มาพร้อมกับ provide / inject
ซึ่งไม่แนะนำให้ใช้ในรหัสแอปพลิเคชันทั่วไป
# parentComponent.vue <template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Vue 3 is liveeeee!" :color="color" /> <select name="color" v-model="color"> <option value="" disabled selected> Select a color</option> <option :value="color" v-for="(color, index) in colors" :key="index">{{ color }}</option></select > </div> </template> <script> import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { color: "", colors: ["red", "blue", "green"], }; }, }; </script>
# childComponent.vue <template> <div class="hello"> <h1>{{ msg }}</h1> <color-selector :color="color"></color-selector> </div> </template> <script> import colorSelector from "@/components/colorComponent.vue"; export default { name: "HelloWorld", components: { colorSelector, }, props: { msg: String, color: String, }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h3 { margin: 40px 0 0; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
# colorComponent.vue <template> <p :class="[color]">This is an example of deeply nested props!</p> </template> <script> export default { props: { color: String, }, }; </script> <style> .blue { color: blue; } .red { color: red; } .green { color: green; } </style>
ที่นี่ เรามีหน้า Landing Page ที่มีรายการสีแบบดรอปดาวน์ และเราจะส่ง color
ที่เลือกไปยัง childComponent.vue
เป็นอุปกรณ์ประกอบฉาก องค์ประกอบย่อยนี้ยังมี msg
prop ที่ยอมรับข้อความที่จะแสดงในส่วนเทมเพลต สุดท้าย คอมโพเนนต์นี้มีคอมโพเนนต์ย่อย ( colorComponent.vue
) ที่ยอมรับอุปกรณ์ป้องกัน color
จากคอมโพเนนต์หลักซึ่งใช้ในการกำหนดคลาสสำหรับข้อความในคอมโพเนนต์นี้ นี่คือตัวอย่างการส่งข้อมูลผ่านส่วนประกอบทั้งหมด
แต่ด้วย Vue 3 เราสามารถทำได้ในระยะสั้นและสะอาดยิ่งขึ้นโดยใช้คู่ Provide และ inject ใหม่ ตามชื่อที่สื่อถึง เราใช้ provide
เป็นฟังก์ชันหรืออ็อบเจ็กต์เพื่อให้ข้อมูลพร้อมใช้งานจากองค์ประกอบหลักไปยังองค์ประกอบที่ซ้อนกันไม่ว่าองค์ประกอบดังกล่าวจะซ้อนกันอยู่ลึกเพียงใด เราใช้รูปแบบอ็อบเจ็กต์เมื่อส่งค่าที่ฮาร์ดโค้ดเพื่อ provide
ลักษณะเช่นนี้
# parentComponent.vue <template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Vue 3 is liveeeee!" :color="color" /> <select name="color" v-model="color"> <option value="" disabled selected> Select a color</option> <option :value="color" v-for="(color, index) in colors" :key="index">{{ color }}</option></select > </div> </template> <script> import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { colors: ["red", "blue", "green"], }; }, provide: { color: 'blue' } }; </script>
แต่สำหรับกรณีที่คุณต้องการส่งคุณสมบัติอินสแตนซ์ส่วนประกอบเพื่อ provide
เราใช้โหมดฟังก์ชันเพื่อให้เป็นไปได้
# parentComponent.vue <template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Vue 3 is liveeeee!" /> <select name="color" v-model="selectedColor"> <option value="" disabled selected> Select a color</option> <option :value="color" v-for="(color, index) in colors" :key="index">{{ color }}</option></select > </div> </template> <script> import HelloWorld from "@/components/HelloWorld.vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { selectedColor: "blue", colors: ["red", "blue", "green"], }; }, provide() { return { color: this.selectedColor, }; }, }; </script>
เนื่องจากเราไม่ต้องการอุปกรณ์ประกอบฉาก color
ทั้งใน childComponent.vue
และ colorComponent.vue
เราจึงจะกำจัดมัน สิ่งที่ดีเกี่ยวกับการใช้ provide
คือองค์ประกอบหลักไม่จำเป็นต้องรู้ว่าองค์ประกอบใดต้องการคุณสมบัติที่มีให้
เพื่อใช้ประโยชน์จากสิ่งนี้ในส่วนประกอบที่ต้องการในกรณีนี้ colorComponent.vue
เราทำเช่นนี้
# colorComponent.vue <template> <p :class="[color]">This is an example of deeply nested props!</p> </template> <script> export default { inject: ["color"], }; </script> <style> .blue { color: blue; } .red { color: red; } .green { color: green; } </style>
ที่นี่เราใช้ inject
ซึ่งรับอาร์เรย์ของตัวแปรที่จำเป็นที่ส่วนประกอบต้องการ ในกรณีนี้ เราต้องการแค่คุณสมบัติ color
ดังนั้นเราจึงส่งผ่านมันไปเท่านั้น หลังจากนั้น เราก็สามารถใช้ color
แบบเดียวกับที่ใช้กับอุปกรณ์ประกอบฉากได้
เราอาจสังเกตเห็นว่าหากเราพยายามเลือกสีใหม่โดยใช้เมนูแบบเลื่อนลง สีจะไม่อัปเดตใน colorComponent.vue
และนี่เป็นเพราะโดยค่าเริ่มต้น คุณสมบัติที่ provide
ไว้จะไม่ตอบสนอง ในการแก้ไขปัญหานั้น เราใช้วิธีการ computed
# parentComponent.vue <template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Vue 3 is liveeeee!" /> <select name="color" v-model="selectedColor"> <option value="" disabled selected> Select a color</option> <option :value="color" v-for="(color, index) in colors" :key="index">{{ color }}</option></select > </div> </template> <script> import HelloWorld from "@/components/HelloWorld.vue"; import { computed } from "vue"; export default { name: "Home", components: { HelloWorld, }, data() { return { selectedColor: "", todos: ["Feed a cat", "Buy tickets"], colors: ["red", "blue", "green"], }; }, provide() { return { color: computed(() => this.selectedColor), }; }, }; </script>
ที่นี่ เรานำเข้าจากการ computed
และส่งผ่านสีที่เรา selectedColor
เพื่อให้สามารถโต้ตอบและอัปเดตได้เมื่อผู้ใช้เลือกสีอื่น เมื่อคุณส่งตัวแปรไปยังวิธีการคำนวณ จะส่งกลับวัตถุที่มี value
คุณสมบัตินี้เก็บ ค่า ของตัวแปรของคุณ ดังนั้นสำหรับตัวอย่างนี้ เราจะต้องอัปเดต colorComponent.vue
ให้มีลักษณะดังนี้
# colorComponent.vue <template> <p :class="[color.value]">This is an example of deeply nested props!</p> </template> <script> export default { inject: ["color"], }; </script> <style> .blue { color: blue; } .red { color: red; } .green { color: green; } </style>
ที่นี่ เราเปลี่ยน color
เป็น color.value
เพื่อแสดงการเปลี่ยนแปลงหลังจากทำปฏิกิริยา color
โดยใช้วิธีการ computed
ณ จุดนี้ class
ของข้อความในส่วนประกอบนี้จะเปลี่ยนไปทุกครั้งที่ selectedColor
เปลี่ยนแปลงในองค์ประกอบหลัก
เทเลพอร์ต
มีบางกรณีที่เราสร้างส่วนประกอบและวางไว้ในส่วนหนึ่งของแอปพลิเคชันของเราเนื่องจากตรรกะที่แอปใช้ แต่มีจุดมุ่งหมายเพื่อแสดงในส่วนอื่นของแอปพลิเคชันของเรา ตัวอย่างทั่วไปของสิ่งนี้อาจเป็นโมดอลหรือป๊อปอัปที่มีขึ้นเพื่อแสดงและครอบคลุมทั้งหน้าจอ แม้ว่าเราจะสามารถสร้างวิธีแก้ปัญหาสำหรับสิ่งนี้ได้โดยใช้คุณสมบัติ position
ของ CSS ในองค์ประกอบดังกล่าว แต่ด้วย Vue 3 เราสามารถทำได้โดยใช้ Teleport
เทเลพอร์ตช่วยให้เราสามารถนำส่วนประกอบออกจากตำแหน่งเดิมในเอกสาร จากค่าเริ่มต้น #app
คอนเทนเนอร์ Vue แอปจะถูกห่อและย้ายไปยังองค์ประกอบที่มีอยู่บนหน้าเว็บที่มีการใช้งาน ตัวอย่างที่ดีคือการใช้ Teleport เพื่อย้ายองค์ประกอบส่วนหัวจากภายใน #app
div ไปยัง header
สิ่งสำคัญที่ควรทราบคือคุณสามารถเทเลพอร์ตไปยังองค์ประกอบที่มีอยู่ภายนอก Vue DOM เท่านั้น
คอมโพเนนต์ Teleport ยอมรับอุปกรณ์ประกอบฉากสองชิ้นที่กำหนดพฤติกรรมของส่วนประกอบนี้และเป็นไปตามนั้น
-
to
พร็อพนี้ยอมรับทั้งชื่อคลาส, id, องค์ประกอบหรือแอตทริบิวต์ data-* นอกจากนี้เรายังสามารถทำให้ค่านี้เป็นไดนามิกโดยส่ง:to
prop ตรงข้ามto
และเปลี่ยนองค์ประกอบ Teleport แบบไดนามิก -
:disabled
พร็อพนี้ยอมรับBoolean
และสามารถใช้เพื่อสลับคุณสมบัติเทเลพอร์ตบนองค์ประกอบหรือส่วนประกอบ สิ่งนี้มีประโยชน์สำหรับการเปลี่ยนตำแหน่งขององค์ประกอบแบบไดนามิก
ตัวอย่างที่ดีของการใช้ Teleport มีลักษณะดังนี้
# index.html** <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title> <%= htmlWebpackPlugin.options.title %> </title> </head> <!-- add container to teleport to --> <header class="header"></header> <body> <noscript> <strong >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong > </noscript> <div></div> <!-- built files will be auto injected --> </body> </html>
ในไฟล์ index.html
เริ่มต้นในแอพ Vue ของคุณ เราเพิ่มองค์ประกอบ header
เพราะเราต้องการเทเลพอร์ตองค์ประกอบส่วนหัวของเราไปยังจุดนั้นในแอปของเรา เรายังได้เพิ่มคลาสให้กับองค์ประกอบนี้สำหรับการจัดสไตล์และเพื่อการอ้างอิงที่ง่ายในองค์ประกอบ Teleport ของเรา
# Header.vue** <template> <teleport to="header"> <h1 class="logo">Vue 3 </h1> <nav> <router-link to="/">Home</router-link> </nav> </teleport> </template> <script> export default { name: "app-header", }; </script> <style> .header { display: flex; align-items: center; justify-content: center; } .logo { margin-right: 20px; } </style>
ที่นี่ เราสร้างองค์ประกอบส่วนหัวและเพิ่มโลโก้พร้อมลิงก์ไปยังหน้าแรกในแอปของเรา เรายังเพิ่มองค์ประกอบ Teleport และ to
prop ค่าของ header
เพราะเราต้องการให้ส่วนประกอบนี้แสดงผลภายในองค์ประกอบนี้ สุดท้าย เรานำเข้าส่วนประกอบนี้ไปยังแอปของเรา
# App.vue <template> <router-view /> <app-header></app-header> </template> <script> import appHeader from "@/components/Header.vue"; export default { components: { appHeader, }, }; </script>
ในไฟล์นี้ เรานำเข้าองค์ประกอบส่วนหัวและวางไว้ในเทมเพลตเพื่อให้มองเห็นได้ในแอปของเรา
ตอนนี้ หากเราตรวจสอบองค์ประกอบของแอป เราจะสังเกตเห็นว่าองค์ประกอบส่วนหัวอยู่ภายในองค์ประกอบ header
ชิ้นส่วน
ด้วย Vue 2.x เป็นไปไม่ได้ที่จะมีองค์ประกอบรูทหลายรายการใน template
ของไฟล์ของคุณ และในการแก้ปัญหาชั่วคราว นักพัฒนาจึงเริ่มห่อองค์ประกอบทั้งหมดในองค์ประกอบหลัก แม้ว่าจะดูไม่เป็นปัญหาร้ายแรง แต่ก็มีบางกรณีที่นักพัฒนาต้องการแสดงส่วนประกอบโดยไม่มีคอนเทนเนอร์ล้อมรอบองค์ประกอบดังกล่าว แต่ต้องดำเนินการด้วย
ด้วย Vue 3 ได้มีการแนะนำคุณลักษณะใหม่ที่เรียกว่า Fragments และคุณลักษณะนี้ช่วยให้นักพัฒนามีองค์ประกอบหลายอย่างในไฟล์เทมเพลตรากของตน ดังนั้นด้วย Vue 2.x นี่คือลักษณะขององค์ประกอบคอนเทนเนอร์ฟิลด์อินพุต
# inputComponent.vue <template> <div> <label :for="label">label</label> <input :type="type" : :name="label" /> </div> </template> <script> export default { name: "inputField", props: { label: { type: String, required: true, }, type: { type: String, required: true, }, }, }; </script> <style></style>
ในที่นี้ เรามีองค์ประกอบองค์ประกอบแบบฟอร์มอย่างง่ายที่ยอมรับอุปกรณ์ประกอบฉากสองรายการ label
และ type
และส่วนเทมเพลตขององค์ประกอบนี้รวมอยู่ใน div ไม่จำเป็นต้องเป็นปัญหา แต่ถ้าคุณต้องการให้ป้ายกำกับและช่องป้อนข้อมูลอยู่ภายในองค์ประกอบ form
ของคุณโดยตรง ด้วย Vue 3 นักพัฒนาสามารถเขียนองค์ประกอบนี้ใหม่ได้อย่างง่ายดายเพื่อให้มีลักษณะเช่นนี้
# inputComponent.vue <template class="testingss"> <label :for="label">{{ label }}</label> <input :type="type" : :name="label" /> </template>
ด้วยโหนดรูทเดียว แอตทริบิวต์ จะถูกนำมาประกอบกับโหนดรูทเสมอ และเรียกอีกอย่างว่า แอตทริบิวต์ที่ไม่ใช่อุปกรณ์ ประกอบ เป็นเหตุการณ์หรือแอตทริบิวต์ที่ส่งผ่านไปยังส่วนประกอบที่ไม่มีคุณสมบัติที่เกี่ยวข้องที่กำหนดไว้ใน props
หรือการ emits
ตัวอย่างของแอตทริบิวต์ดังกล่าว ได้แก่ class
และ id
อย่างไรก็ตาม จำเป็นต้องกำหนดอย่างชัดเจนว่าองค์ประกอบใดในคอมโพเนนต์โหนดแบบหลายรูทที่ควรนำมาประกอบ
นี่คือสิ่งที่หมายถึงการใช้ inputComponent.vue
จากด้านบน;
- เมื่อเพิ่ม
class
ให้กับองค์ประกอบนี้ในองค์ประกอบหลัก จะต้องระบุว่าองค์ประกอบใดที่class
นี้จะถูกนำมาประกอบเป็นอย่างอื่น แอตทริบิวต์จะไม่มีผล
<template> <div class="home"> <div> <input-component class="awesome__class" label="name" type="text" ></input-component> </div> </div> </template> <style> .awesome__class { border: 1px solid red; } </style>
เมื่อคุณทำสิ่งนี้โดยไม่ได้กำหนดว่าแอตทริบิวต์ควรมาจากที่ใด คุณจะได้รับคำเตือนนี้ในคอนโซลของคุณ
และ border
ไม่มีผลกับส่วนประกอบ
- ในการแก้ไขปัญหานี้ ให้เพิ่ม
v-bind="$attrs"
ในองค์ประกอบที่คุณต้องการแจกจ่ายแอตทริบิวต์ดังกล่าว
<template> <label :for="label" v-bind="$attrs">{{ label }}</label> <input :type="type" : :name="label" /> </template>
ที่นี่ เรากำลังบอก Vue ว่าเราต้องการให้แอตทริบิวต์ถูกแจกจ่ายไปยังองค์ประกอบ label
ซึ่งหมายความว่าเราต้องการใช้ awesome__class
กับมัน ตอนนี้ หากเราตรวจสอบองค์ประกอบของเราในเบราว์เซอร์ เราจะเห็นว่าขณะนี้มีการเพิ่มคลาสใน label
และด้วยเหตุนี้จึงมีเส้นขอบรอบป้ายกำกับ
Global API
ไม่ใช่เรื่องแปลกที่จะเห็น Vue.component
หรือ Vue.use
ในไฟล์ main.js
ของแอปพลิเคชัน Vue เมธอดประเภทนี้รู้จักกันดีคือ Global APIs และมีหลายวิธีใน Vue 2.x ความท้าทายอย่างหนึ่งของวิธีนี้คือทำให้ไม่สามารถแยกฟังก์ชันการทำงานบางอย่างกับอินสแตนซ์หนึ่งของแอปของคุณ (ถ้าคุณมีมากกว่าหนึ่งอินสแตนซ์ในแอปของคุณ) โดยไม่ส่งผลต่อแอปอื่นๆ เนื่องจากทั้งหมดติดตั้งอยู่บน Vue นี่คือสิ่งที่ผมหมายถึง
Vue.directive('focus', { inserted: el => el.focus() }) Vue.mixin({ /* ... */ }) const app1 = new Vue({ el: '#app-1' }) const app2 = new Vue({ el: '#app-2' })
สำหรับโค้ดด้านบนนี้ เป็นไปไม่ได้ที่จะระบุว่า Vue Directive เชื่อมโยงกับ app1
และ Mixin กับ app2
แทน แต่ทั้งสองมีอยู่ในทั้งสองแอปแทน
Vue 3 มาพร้อมกับ Global API ใหม่ในความพยายามที่จะแก้ไขปัญหาประเภทนี้ด้วยการเปิดตัว createApp
วิธีนี้จะคืนค่าอินสแตนซ์ใหม่ของแอป Vue อินสแตนซ์ของแอปเปิดเผยชุดย่อยของ API ส่วนกลางปัจจุบัน ด้วยวิธีนี้ API ทั้งหมด (ส่วนประกอบ มิกซ์อิน คำสั่ง การใช้งาน ฯลฯ) ที่เปลี่ยน Vue
จาก Vue 2.x จะถูกย้ายไปยังอินสแตนซ์ของแอปแต่ละรายการ และตอนนี้ แต่ละอินสแตนซ์ของแอป Vue สามารถมีฟังก์ชันการทำงานเฉพาะสำหรับ โดยไม่กระทบต่อแอพอื่นๆ ที่มีอยู่
ตอนนี้โค้ดข้างต้นสามารถเขียนใหม่เป็น;
const app1 = createApp({}) const app2 = createApp({}) app1.directive('focus', { inserted: el => el.focus() }) app2.mixin({ /* ... */ })
อย่างไรก็ตาม คุณสามารถสร้างฟังก์ชันที่คุณต้องการแชร์กับแอปทั้งหมดของคุณได้ ซึ่งสามารถทำได้โดยใช้ฟังก์ชันจากโรงงาน
เหตุการณ์ API
วิธีหนึ่งที่นักพัฒนามักนำมาใช้เพื่อส่งข้อมูลระหว่างส่วนประกอบที่ไม่มีความสัมพันธ์แบบพาเรนต์ถึงลูกนอกเหนือจากการใช้ Vuex Store คือการใช้ Event Bus สาเหตุหนึ่งที่ทำให้วิธีนี้เป็นเรื่องปกติเพราะความง่ายในการเริ่มต้น
# eventBus.js const eventBus = new Vue() export default eventBus;
หลังจากนี้ สิ่งต่อไปคือการนำเข้าไฟล์นี้ไปยัง main.js
เพื่อให้สามารถใช้งานได้ทั่วโลกในแอพของเรา หรือเพื่อนำเข้าในไฟล์ที่คุณต้องการ
# main.js import eventBus from 'eventBus' Vue.prototype.$eventBus = eventBus
ตอนนี้คุณสามารถปล่อยเหตุการณ์และฟังเหตุการณ์ที่ปล่อยออกมาเช่นนี้
this.$eventBus.$on('say-hello', alertMe) this.$eventBus.$emit('pass-message', 'Event Bus says Hi')
มี Vue codebase มากมายที่เต็มไปด้วยโค้ดแบบนี้ อย่างไรก็ตาม ด้วย Vue 3 จะไม่สามารถดำเนินการได้ เนื่องจาก $on
, $off
และ $once
on ถูกลบออกทั้งหมดแล้ว แต่ $emit
ยังคงใช้งานได้เนื่องจากจำเป็นสำหรับองค์ประกอบลูกในการส่งเหตุการณ์ไปยังองค์ประกอบหลัก อีกทางเลือกหนึ่งคือการใช้ provide / inject
หรือไลบรารีของบุคคลที่สามที่แนะนำ
บทสรุป
ในบทความนี้ เราได้กล่าวถึงวิธีที่คุณสามารถส่งข้อมูลไปรอบๆ จากองค์ประกอบหลักลงไปที่องค์ประกอบย่อยที่ซ้อนกันอย่างล้ำลึกโดยใช้คู่การ provide / inject
นอกจากนี้เรายังได้พิจารณาถึงวิธีที่เราสามารถเปลี่ยนตำแหน่งและถ่ายโอนส่วนประกอบจากจุดหนึ่งในแอพของเราไปยังอีกจุดหนึ่ง อีกสิ่งหนึ่งที่เราดูคือคอมโพเนนต์โหนดหลายรูทและจะแน่ใจได้อย่างไรว่าเราแจกจ่ายแอตทริบิวต์เพื่อให้ทำงานได้อย่างถูกต้อง สุดท้าย เรายังครอบคลุมถึงการเปลี่ยนแปลงของ Events API และ Global API
แหล่งข้อมูลเพิ่มเติม
- “ฟังก์ชั่นโรงงาน JavaScript กับ ES6+” Eric Elliott, Medium
- “การใช้ Event Bus เพื่อแบ่งปันอุปกรณ์ประกอบฉากระหว่างส่วนประกอบ Vue” Kingsley Silas, CSS-Tricks
- การใช้เทเลพอร์ตหลายรายการในเป้าหมายเดียวกัน Vue.js Docs
- แอตทริบิวต์ที่ไม่ใช่อุปกรณ์ประกอบฉาก, Vue.js Docs
- การทำงานกับปฏิกิริยา Vue.js Docs
-
teleport
เลพอร์ต , Vue.js Docs - Fragments, Vue.js Docs
- ไวยากรณ์ 2.x, Vue.js Docs