Vue component value transfer

Posted by ben_johnson1991 on Wed, 09 Feb 2022 16:48:35 +0100

Vue parent-child component value transfer

Function of components

Components are user-defined elements, extensible html elements, and encapsulate reusable code.

Benefits:

1. If there is a function that can be used in many places, there is no need to write this function repeatedly as a component;
2. The content of the page will be concise; Convenient control;

How to register components

Syntax:
Vue. Component ('My component name ', {/ *... * /}) my component name is the defined component name, and parameter 2 is an object

Precautions for registering components:

  • Components are reusable, and data is followed by a function, because each component is independent, and the returned object will reopen space
  • Component template content must be a single root element
  • The content of a component template can be a template string
  • To define the component name of a component, set the tag name of the sub component to the component name in HTML. For example, the component name in the following code is son, and the tag in html is < son > < son / >
 <div id="app">
        <son></son>
    </div>
    <template id="tmp">
        <div>
            <button>I click on the component content{{msg}}</button>
        </div>
    </template>
    <script src="./js/vue.js"></script>
    <script>

        var son = {
            data: function () {
                return {
                    msg: 'Content in my component'
                }
            },
            template: '#tmp'
        }

        Vue.component('son', son)
        var vm = new Vue({
            el: '#app'
        })

Parent component passes value to child component

  • The parent component transmits data to the child component through props. In fact, the core is to add custom attributes to the label of the child component in the parent component. The child component receives the data internally through props, and the custom attributes are added to the component
  • props pass attribute data type can be string, array, object, Boolean, numeric
  • The props attribute name is in the form of hump. The template needs to use the form of dashes, which is not limited in the template in the form of string. In order to avoid trouble, it is recommended to use the form of dashes without hump naming
  <div id="app">
        <!-- <son :obj='obj'></son> -->
        <son :arr='arr' content='nihao' :obj='obj'></son>
    </div>
    <template id="tmp">
        <div>
            <ul>
                <li :key='index' v-for='(item,index) in arr'>{{item}} ------{{content}}</li>
            </ul>
            <span>{{obj.myname}}</span>
            <span>{{obj.age}}</span>
        </div>
    </template>
    <script src="./js/vue.js"></script>
    <script>
        Vue.component('son', {
            props: ['arr', 'content', 'obj'],
            template: '#tmp'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                arr: ['apple', 'orange', 'pear'],
                obj: {
                    myname: 'zlj',
                    age: '18'
                }
            }
        })
    </script>

Single data flow

After the parent component transmits data to the child component, it cannot modify the value of the data transmitted through props in the child component. The value of the data on the parent component, that is, the so-called single data flow, sometimes depends on whether the transmitted data is a simple data type or a complex data type. If the simple data type is carried out, it is to re assign the value, which is contrary to the single data flow, so an error will be reported, However, if it is a complex data type, modifying the attribute value in the complex data type does not reopen the memory space. Such an operation will not report an error, but if you modify the complex data type as a whole, an error will be reported; For example, if an original object is redeclared and an empty object is modified, it belongs to re assignment, which violates the single data flow, and an error will be reported

Example code for directly modifying simple data types:

 <div id="app">
        <div>{{pmsg}}</div>
        <text-box :title='ptitle'></text-box>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        Vue.component('text-box', {
            props: ['title'],
            data() {
                return {
                    msg: 'I am the content of the sub component'
                }
            },
            template: `<div><input type='text' v-model='title'></div>`
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: 'My parent component content',
                ptitle: 'I am the content of the parent component'
            }
        })
    </script>

Example code for directly modifying simple data types:

 var CartList = {
            props: ['list'],
            template: `
        <div>
          <div :key='item.id' v-for='item in list' class="item">
            <img :src="item.img"/>
            <div class="name">{{item.name}}</div>
            <div class="change">
              <a href="" @click.prevent='delNum(item)'>-</a>
              <input type="text" class="num"  v-model='item.num'/>
              <a href="" @click.prevent='addNum(item)'>+</a>
            </div>
            <div class="del" @click='delList(item.id)'>×</div>
          </div>
        </div>
      `,
            methods: {
                // changeNum(id, event) {
                //     this.$emit('change-num', {
                //         id: id,
                //         num: event.target.value
                //     })
                // },
                delList(id) {
                    // Bind a custom event to the parent component through $emit(), so that the child can pass data to the parent
                    this.$emit('car-del', id)
                },
                addNum(item) {
                    item.num++
                },
                delNum(item) {
                    if (item.num <= 0) {
                        return
                    } else {
                        item.num--
                    }

                }
            }
        }
      
        Vue.component('my-cart', {
            data: function () {
                return {
                    uname: 'Li Si',
                    list: [{
                        id: 1,
                        name: 'TCL Color TV',
                        price: 1000,
                        num: 1,
                        img: 'img/a.jpg'
                    }, {
                        id: 2,
                        name: 'Set top box',
                        price: 1000,
                        num: 1,
                        img: 'img/b.jpg'
                    }, {
                        id: 3,
                        name: 'Haier refrigerator',
                        price: 1000,
                        num: 1,
                        img: 'img/c.jpg'
                    }, {
                        id: 4,
                        name: 'Mi phones',
                        price: 1000,
                        num: 1,
                        img: 'img/d.jpg'
                    }, {
                        id: 5,
                        name: 'PPTV television',
                        price: 1000,
                        num: 2,
                        img: 'img/e.jpg'
                    }]
                }
            },

The child component passes data to the parent component

Steps to implement data transferred from child component to parent component:

  • In the parent component, bind the custom event to the label of the child component (how to trigger the custom event:), and bind the custom event defined on the child component in the label of the child component of the parent component
  • Find a way to trigger the custom event this bound to you in the sub component$ Emit (custom event name, parameter) is to bind custom events on the subcomponent through the $emit method
  • After the subcomponent successfully executes $emit, the custom event on the subcomponent is triggered. At this time, the event execution function corresponding to the custom event

Case 1 of value transfer from child component to parent component: $emit(), followed by no parameters

 <div id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
       
        <son @enlarge-text='handle'></son>
    </div>
    <template id="tmp">
        <div>
            <button @click='$emit("enlarge-text")'>Click me to make the text bigger</button>
        </div>
    </template>
    <script src="./js/vue.js"></script>
    <script>
        Vue.component('son',{
            template: '#tmp'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: 'I am the text of the parent component',
                fontSize: 15
            },
            methods: {
                handle() {
                    this.fontSize += 15
                }
            }
        })
    </script>

Case 1 of value transfer from child component to parent component: $emit(), followed by parameters

 <div id="app">
        <div>I am the parent component{{pmsg}}----</div>
        <!-- handle Parameters after function $event It can be omitted -->
        <son @change-text='handle'></son>
    </div>
    <template id="tmp">
        <div>
            <button @click='$emit("change-text",this.smsg)'>Click I have a surprise</button>
        </div>
    </template>
    <script src="./js/vue.js"></script>
    <script>
        Vue.component('son', {
            data: function () {
                return {
                    smsg: 'I am the text in the subcomponent'
                }
            },
            template: '#tmp'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: 'I am the text in the parent component'
            },
            methods: {
                handle: function (val) {
                    this.pmsg = val
                }
            }
        })
    </script>

Value transfer between sibling components

To transfer data between brothers, you need to use the event center to transfer data through the event center. Provide the event center: var eventBus=new Vue(), transfer the data party, and trigger eventbus through an event$ Emit (method name, passed data)

The data receiving party triggers eventbus through the mounted() {} hook$ On() method name

Destroy the event through hub$ Data cannot be transferred after the off() method name is destroyed

Flow diagram of sibling components transferring values through the event center:

Implementation steps of data transmission of brother components:

Through the event center, the life cycle adds listening events to two brother components respectively

Each sibling subcomponent can trigger the other's events through conditions to realize the transmission of values
 

<body>
    <div id="app">
        <div class="box">
            <h1>I'm the title</h1>
            <son1></son1>
            <son2></son2>
        </div>
    </div>
    <template id="tmp1">
        <div>
            <h2>assembly A</h2>
            <button @click='clickhandle'>Transfer data B</button>
            <h3>Incoming data B------{{msg_formb}}</h3>
        </div>
    </template>
    <template id="tmp2">
        <div>
            <h2>assembly B</h2>
            <button @click='clickhandle'>Transfer data A</button>
            <h3>Incoming data A--------{{msg_forma}}</h3>
        </div>
    </template>
    <script src="./js/vue.js"></script>
    <script>
        // Create event center
        var eventBus = new Vue()
        var son1 = {
            // Create listening events for each sub component through the hook function in the life cycle
            mounted() {
                eventBus.$on('a_event', (val) => {
                    // The declared null data is used to receive the incoming parameter data
                    this.msg_formb = val
                })
            },
            data() {
                return {
                    smsga: 'assembly a Data',
                    msg_formb: ''
                }
            },
            template: '#tmp1',
            methods: {
                clickhandle() {
                    // Call listener events of another brother component in the current component, and import the data of the current component.
                    eventBus.$emit('b_event', this.smsga)
                }
            }
        }
        Vue.component('son1', son1)

        var son2 = {
            mounted() {
                eventBus.$on('b_event', (val) => {
                    this.msg_forma = val
                })
            },
            data() {
                return {
                    smsgb: 'Component handle b Data',
                    msg_forma: ''
                }
            },
            template: '#tmp2',
            methods: {
                clickhandle() {
                    eventBus.$emit('a_event', this.smsgb)
                }
            }
        }
        Vue.component('son2', son2)
        var vm = new Vue({
            el: '#app'
        })
    </script>

Summary:

  • First, create an event bus, such as bus, as a communication bridge;
  • In the components that need to transfer values, a user-defined event is triggered through e m i t and parameters are passed;
  • In the component receiving data, trigger a user-defined event through emit and pass parameters;
  • In the component receiving data, listen to user-defined events through on and process the passed parameters;

The data interaction between sibling components and between parent and child components. Compared with the two, the communication between sibling components is actually somewhat similar to the value transfer from child components to parent components. In fact, their communication principles are the same. For example, the value transfer from child to parent is also in the form of e m i t, and emit and on, but there is no eventBus event Zhan, but if we think about it carefully, At this point, the parent component actually acts as the event bus.
 

Topics: Front-end Vue