javascript - วิธีเข้าถึงวิธีการลูกจากผู้ปกครองใน vue.js
ฉันมีคอมโพเนนต์ซ้อนสองอัน วิธีที่เหมาะสมในการเข้าถึงเมธอดของลูกจากผู้ปกติคืออะไร?
this.$children[0].myMethod() ดูเหมือนจะทําได้ดี แต่มันค่อนข้างน่าเกลียดใช่ไหม
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
คำตอบ #1
คุณสามารถใช้เอกสารอ้างอิงได้
import ChildForm from './components/ChildForm'
new Vue({
el: '#app',
data: {
item: {}
},
template: `
<div>
<ChildForm :item="item" ref="form" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.$refs.form.submit()
}
},
components: { ChildForm },
})
ถ้าคุณไม่ชอบการเชื่อมโยงที่แน่นหนา คุณสามารถใช้ Event Bus ตามที่ @Yosvel Quintero แสดง ด้านล่างเป็นตัวอย่างอีกตัวอย่างหนึ่งของการใช้ Event Bus โดยการส่ง bus เข้ามาเป็น props
import ChildForm from './components/ChildForm'
new Vue({
el: '#app',
data: {
item: {},
bus: new Vue(),
},
template: `
<div>
<ChildForm :item="item" :bus="bus" ref="form" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.bus.$emit('submit')
}
},
components: { ChildForm },
})
รหัสของส่วนประกอบ
<template>
...
</template>
<script>
export default {
name: 'NowForm',
props: ['item', 'bus'],
methods: {
submit() {
...
}
},
mounted() {
this.bus.$on('submit', this.submit)
},
}
</script>
https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/
คำตอบ #2
สำหรับ Vue 2.7 และ Vue 3.2.x
<!-- Parent -->
<script setup>
import { ref, onMounted } from 'vue'
import ChildComponent from './components/ChildComponent.vue'
const childComponentRef = ref()
onMounted(() => {
childComponentRef.value.doSomething()
})
</script>
<template>
<ChildComponent ref="childComponentRef" />
</template>
สคริปต์ตั้งค่า
<!-- Child -->
<script setup>
const doSomething = () => {
console.log('Im batman')
}
defineExpose({
doSomething
})
</script>
ฟังก์ชันการตั้งค่า
<!-- Child -->
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, context) {
const doSomething = () => {
console.log('Im batman')
}
context.expose({ doSomething })
}
})
</script>
หลีกเลี่ยงปัญหานี้ให้มากที่สุดและใช้องค์ประกอบ เว้นแต่คุณจะไม่สามารถควบคุมส่วนประกอบได้ (ปลั๊กอินของบุคคลที่สาม ฯลฯ)
แหล่งที่มา: https://vuejs.org/api/sfc-script-setup.html#defineexpose
คำตอบ #3
วิธีแก้ปัญหาที่แนะนำสำหรับ Vue 2 แต่หากคุณมาที่นี่เพราะกำลังมองหาวิธีแก้ปัญหา Vue 3 Composition API คุณสามารถทำตามขั้นตอนต่อไปนี้เมื่อต้องย้าย:
คอมโพเนนต์ลูกในเทมเพลต ซึ่งมีเมธอด "doSomething" :
<div class="form">
<child-component ref="childComponentRef" />
</div>
กับ Vue 2 :
this.$refs.childComponentRef.doSomething( );
ด้วย Vue 3 Composition API :
setup( )
{
const childComponentRef = ref( );
childComponentRef.value.doSomething( )
return {
childComponentRef
}
}
คำตอบ #4
การสื่อสารระหว่างผู้ปกครองและลูกใน VueJS
เมื่อมีการเข้าถึงอินสแตนซ์รากของ Vue ได้โดยลูกหลานทั้งหมดผ่าน this.$root คอมโพเนนต์พ่อแม่สามารถเข้าถึงคอมโพเนนต์ลูกผ่านอาร์เรย์ this.$children และคอมโพเนนต์ลูกสามารถเข้าถึงพ่อแม่ของมันผ่าน this.$parent สัญชาตญาณแรกของคุณอาจเป็นการเข้าถึงคอมโพเนนต์เหล่านี้โดยตรง
เอกสารของ VueJS เตือนเกี่ยวกับเรื่องนี้โดยเฉพาะด้วยเหตุผลที่ดีสองประการ:
- มันเชื่อมพ่อแม่เข้ากับลูกอย่างแน่นหนา (และในทางกลับกัน)
- คุณไม่สามารถพึ่งพาสถานะของพ่อแม่ได้ เนื่องจากสามารถถูกแก้ไขโดยคอมโพเนนต์ลูก
วิธีแก้ปัญหาคือการใช้ส่วนติดต่อเหตุการณ์แบบกำหนดเองของ Vue
อินเทอร์เฟซเหตุการณ์ที่ Vue นำไปใช้นั้นช่วยให้คุณสื่อสารขึ้นและลงในต้นไม้ของคอมโพเนนต์ การใช้ประโยชน์จากอินเทอร์เฟซเหตุการณ์แบบกำหนดเองจะให้คุณเข้าถึงสี่วิธีได้:
$on()- ช่วยให้คุณประกาศตัวฟัง (listener) บนอินสแตนซ์ Vue ของคุณเพื่อฟังเหตุการณ์$emit()- อนุญาตให้คุณเรียกใช้งานอีเวนต์บนอินสแตนซ์เดียวกัน (self)
ตัวอย่างการใช้ $on() และ $emit():
const events = new Vue({}),
parentComponent = new Vue({
el: '#parent',
ready() {
events.$on('eventGreet', () => {
this.parentMsg = `I heard the greeting event from Child component ${++this.counter} times..`;
});
},
data: {
parentMsg: 'I am listening for an event..',
counter: 0
}
}),
childComponent = new Vue({
el: '#child',
methods: {
greet: function () {
events.$emit('eventGreet');
this.childMsg = `I am firing greeting event ${++this.counter} times..`;
}
},
data: {
childMsg: 'I am getting ready to fire an event.',
counter: 0
}
});<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script>
<div id="parent">
<h2>Parent Component</h2>
<p>{{parentMsg}}</p>
</div>
<div id="child">
<h2>Child Component</h2>
<p>{{childMsg}}</p>
<button v-on:click="greet">Greet</button>
</div>คำตอบที่นำมาจากโพสต์ต้นฉบับ: การสื่อสารระหว่างคอมโพเนนต์ใน VueJS
