preface
Component is one of the most powerful functions of vue.js, and the scope of component instances is independent of each other, which means that data between different components cannot be referenced to each other. However, in the actual project development, like the communication between pages, Vue components and components certainly need to communicate with each other and share state. Next, before understanding component communication, let's first understand several relationships between components:
As shown in the figure:
- A and B, B and C, B and D are all parent-child relationships
- C and D are brothers
- A and C are inter generational (possibly multi generational)
For different component relationships, we will have more suitable communication methods. Next, let's take a look.
Component communication
1. Pass value props from parent component to child component
Props can well complete the communication between parent and child components in the form of one-way data flow. The so-called one-way data flow means that data can only flow from the parent component to the child component through props, and the child component cannot modify the corresponding state of the parent component by modifying the data transmitted from props. As for why, Vue's official website explains:
All props form a one-way downstream binding between their parent and child props: the updates of the parent props will flow down to the child components, but not vice versa. This will prevent the child component from accidentally changing the state of the parent component, which will make the data flow of your application difficult to understand.
-Vue official website
<!--Parent component--> <template> <div> <children :child="message"></children> //The user-defined name of the former is convenient for the sub component to call, and the data name to be passed by the latter </div> </template> <script> import children from "@/views/send/children";//Introducing sub components export default { name: "parent", data(){ return{ message: 'I am the value of the parent component!' } }, components:{ children }, } </script>
<!--Subcomponents-->
<template>
<div>
<h1>{{child}}</h1>
</div>
</template>
<script>
export default {
name: "children",
props:["child"], //You can also receive data using the following object types
props:{
child:{
type:String,
require:true //It means that the value child must be passed when using this component, otherwise an error will be reported
}
},
}
</script>
2. The child component passes the value $emit to the parent component
<!--Subcomponents--> <template> <div> <input type="text" v-model="message"> <button @click="click">Send</button> </div> </template> <script> export default { name: "children", data(){ return{ message:'I am the value of the subcomponent!' } }, methods:{ click(){ this.$emit('childFn',this.message);//Custom event name childFn } } } </script>
<!--Parent component--> <template> <div> <children @childFn="parentFn"></children> //Note that the component should be bound to the opposite method name <p>Value from subcomponent:{{paMess}}</p> </div> </template> <script> import children from "@/views/send/children"; export default { name: "Cart", data(){ return{ paMess:'' } }, components:{ children }, methods:{ parentFn(payload){ this.paMess = payload;//payload Is the value passed from the subcomponent,Parent component receive } } } </script>
3. ref and $refs pass values
- Parent component passes value to child component
<!--Parent component--> <template> <div> <!-- Click the trigger method to transfer the data to the sub component--> <button @click="sendData">send</button> <children ref="myChild"></children> </div> </template> <script> import children from "@/views/send/children"; export default { name: "parent", data(){ return{ } }, components:{ children }, methods:{ sendData(){ //The parent component triggers the of the child component init method this.$refs.myChild.init("waq",22) } } } </script>
<!--Subcomponents--> <template> <div> <h1>{{name}}</h1> <h1>{{age}}</h1> </div> </template> <script> export default { name: "children", data(){ return{ name: '', age: '' } }, methods:{ init(name,age){ this.name = name; this.age = age; } } } </script>
- The parent component can also obtain the value of the child component through ref, that is, the child component passes the value to the parent component
<!--Parent component--> <template> <div> <!-- Click the trigger method to obtain the data of the sub component--> <button @click="getData">send</button> <children ref="myChild"></children> <p>{{parMes}}</p> </div> </template> <script> import children from "@/views/send/children"; export default { name: "parent", data(){ return{ parMes:'', } }, components:{ children }, methods:{ getData(){ //Get child component from parent component message value this.parMes = this.$refs.myChild.message; } } } </script>
<!--Subcomponents--> <template> <div> </div> </template> <script> export default { name: "children", data(){ return{ message:'I am the value of the subcomponent!!' } }, } </script>
4. $parent and $children
$parent Is the instance object of the parent component,
$children It is the direct subcomponent instance of the current instance, but the attribute value is of Array type, does not guarantee order, and is not responsive. If you find yourself trying to use $ children For data binding, consider using an Array v-for To generate subcomponents, and use Array as the real source. The parent component can also access all its child components through this.$children
<!--Parent component--> <template> <div> <button @click="changeChild">change</button> <children></children> </div> </template> <script> import children from "@/views/send/children"; export default { name: "parent", data(){ return{ message:'hello' } }, components:{ children }, methods:{ changeChild(){ this.$children[0].mymessage = 'hello'; } } } </script>
<!--Subcomponents--> <template> <div> <input type="text" v-model="mymessage" @change="changeValue"> </div> </template> <script> export default { name: "children", data(){ return{ mymessage: this.$parent.$message } }, methods: { changeValue(){ this.$parent.message = this.mymessage;//The value of the parent component can be changed by such a call } } } </script>
In the above example code, the parent and child components are defined respectively, which are direct parent-child relationships. The two components define their own properties internally. In the parent component, directly use this.$children[0].mymessage = 'hello'; Assign a value to the mymessage attribute in the child component, and in the child sub component, also directly assign a value to the message in the parent component through this.$parent.message, forming a parent-child component communication.
Communication about this method will be described in detail in the next blog.
Reference article: https://juejin.cn/post/6844903784963899405#heading-7