Front words
Sometimes a parent component is required to access a child component, a child component to access a parent component, or a child component to access the root component. In the component instance, Vue provides the corresponding properties, including $parent, $children, $refs and $root, which are mounted on the component's this. This article details direct access between instances of Vue components
$parent
$parent represents an instance of the parent component, which is read-only
Here is a simple example
<div id="example"> <parent-component></parent-component> </div> <template id="parent-component"> <div class="parent"> <h3>I am the parent component</h3> <input v-model="parentMsg"> <p>{{parentMsg}}</p> <child-component></child-component> </div> </template> <template id="child-component"> <div class="child"> <h3>I am a subcomponent</h3> <p>{{msg}}</p> <button v-on:click="showData">Display parent component data</button> </div> </template>
<script> // register Vue.component('parent-component', { template: '#parent-component', data(){ return{ parentMsg:'I am the data of the parent component' } }, components:{ 'child-component':{ template:'#child-component', data(){ return{ msg:'' } }, methods:{ showData(){ this.msg = this.$parent.parentMsg; } } } } }) // Create a root instance new Vue({ el: '#example' }) </script>
$root
$root represents the root Vue instance of the current component tree. If the current instance does not have a parent instance, the instance will be its own. This property is read-only
<div id="example"> <h3>I am the root component</h3> <input v-model="rootMsg"> <p>{{rootMsg}}</p> <parent-component></parent-component> </div> <template id="parent-component"> <div class="parent"> <h3>I am the parent component</h3> <input v-model="parentMsg"> <p>{{parentMsg}}</p> <child-component></child-component> </div> </template> <template id="child-component"> <div class="child"> <h3>I am a subcomponent</h3> <p> <button v-on:click="showRootData">Display root component data</button><span>{{rootMsg}}</span> </p> <p> <button v-on:click="showParentData">Display parent component data</button><span>{{parentMsg}}</span> </p> </div> </template>
<script> // register Vue.component('parent-component', { template: '#parent-component', data(){ return{ parentMsg:'I am the data of the parent component' } }, components:{ 'child-component':{ template:'#child-component', data(){ return{ parentMsg:'', rootMsg:'' } }, methods:{ showParentData(){ this.parentMsg = this.$parent.parentMsg; }, showRootData(){ this.rootMsg = this.$root.rootMsg; }, } } } }) // Create a root instance new Vue({ el: '#example', data:{ rootMsg:'I am the root component data' } }) </script>
$children
$children represents a direct subcomponent of the current instance. It should be noted that $children does not guarantee order or responsiveness. If you're trying to use $children for data binding, consider using an array with v-for to generate subcomponents, and using Array as the real source
<div id="example"> <parent-component></parent-component> </div> <template id="parent-component"> <div class="parent"> <h3>I am the parent component</h3> <button @click="getData">Getting subcomponent data</button> <br> <div v-html="msg"></div> <child-component1></child-component1> <child-component2></child-component2> </div> </template> <template id="child-component1"> <div class="child"> <h3>I am a sub-component</h3> <input v-model="msg"> <p>{{msg}}</p> </div> </template> <template id="child-component2"> <div class="child"> <h3>I am subcomponent 2</h3> <input v-model="msg"> <p>{{msg}}</p> </div> </template>
<script> // register Vue.component('parent-component', { template: '#parent-component', data(){ return{ msg:'', } }, methods:{ getData(){ let html = ''; let children = this.$children; for(var i = 0; i < children.length;i++){ html+= '<div>' + children[i].msg + '</div>'; } this.msg = html; } }, components:{ 'child-component1':{ template:'#child-component1', data(){ return{ msg:'', } }, }, 'child-component2':{ template:'#child-component2', data(){ return{ msg:'', } }, }, } }) // Create a root instance new Vue({ el: '#example', }) </script>
$refs
When the number of components is large, it is difficult to remember the order and location of each component. It is not convenient to access subcomponents by serial number.
Using ref attributes on subcomponents, you can specify an index ID for subcomponents:
<child-component1 ref="c1"></child-component1> <child-component2 ref="c2"></child-component2>
In the parent component, an instance of the child component is accessed through the $refs. index ID
this.$refs.c1
this.$refs.c2
<div id="example"> <parent-component></parent-component> </div> <template id="parent-component"> <div class="parent"> <h3>I am the parent component</h3> <div> <button @click="getData1">Getting subcomponents c1 Data</button> <p>{{msg1}}</p> </div> <div> <button @click="getData2">Getting subcomponents c2 Data</button> <p>{{msg2}}</p> </div> <child-component1 ref="c1"></child-component1> <child-component2 ref="c2"></child-component2> </div> </template> <template id="child-component1"> <div class="child"> <h3>I am a sub-component</h3> <input v-model="msg"> <p>{{msg}}</p> </div> </template> <template id="child-component2"> <div class="child"> <h3>I am subcomponent 2</h3> <input v-model="msg"> <p>{{msg}}</p> </div> </template>
<script> // register Vue.component('parent-component', { template: '#parent-component', data(){ return{ msg1:'', msg2:'', } }, methods:{ getData1(){ this.msg1 = this.$refs.c1.msg; }, getData2(){ this.msg2 = this.$refs.c2.msg; }, }, components:{ 'child-component1':{ template:'#child-component1', data(){ return{ msg:'', } }, }, 'child-component2':{ template:'#child-component2', data(){ return{ msg:'', } }, }, } }) // Create a root instance new Vue({ el: '#example', }) </script>
summary
Although vue provides direct access to component instances in the above way, it is not recommended to do so. This can lead to tight coupling between components and difficult to understand their own state, so use it as much as possible. props,Custom Events as well as Content distribution slot To transfer data