Recently, I met some problems in data transfer between components when I sorted out the code in the project, so I made this summary. If there is anything wrong, please correct it.

How does the parent pass data to the child

Parent components can pass data to child components via Prop.

Here are some things to note:

  • Prop is unidirectional: when a property of the parent component changes, it passes to the child component, but not vice versa. This is to prevent the child component from inadvertently modifying the state of the parent component to prevent the data flow of the application from becoming difficult to understand.

  • Every time the parent component is updated, all the Prop of the child component is updated to the latest value. This means that you should not change prop inside child components. If you do, Vue will warn you on the console.

There are two situations where it is tempting to modify data in prop:

  • PropOnce passed in as an initial value, the child component wants to use it as local data;

Solution: Define a local variable and initialize it with the value of prop:

props: ['initialCounter'].data: function () {
  return { counter: this.initialCounter }
}    
Copy the code
  • PropIt is passed in as raw data and processed by child components into other data output.

Workaround: Define a calculated property that handles the value of prop and returns:

props: ['size'].computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}
Copy the code

PS: The above content is said in the VUE document. I just extracted the problems I encountered in the project. link

Chestnut:

// The parent component index.vue<template>
    <div class="content">
        <child :lists="lists"></child>
    </div>
</template>
<script>
    import child from './child.vue';
    export default {
        components: {
            child
        },
        data() {
            return {
                lists: []}; }, mounted() {this.lists = [{
                name: '01'.content: 'hi,'
            }, {
                name: '02'.content: 'my name is Ellyliang'}]; }};</script>// Child component child.vue<template>
    <ul class="content">
       <li v-for="(list, index) in getLists" :key="index" v-html="list.name + list.content"></li>
    </ul>
</template>
<script>
    export default {
        props: ['lists'],
        data() {
            return {
                getLists: this.lists
            };
        },
        mounted() {
            this.getLists.push({
                name: '03'.content: 'Don't care about the content, I'm the test.'}); }};</script>
Copy the code

How does a child component pass data to its parent

The child component can pass data to the parent component via vm.$emit

vm.$emitWhat is

Triggers events on the current instance. Additional parameters are passed to the listener callback. link

Chestnut:

// The parent component index.vue<template>
    <div class="content">
        <child :lists="lists" @listenToChild="getChildMsg"></child>
    </div>
</template>
<script>
    import child from './child.vue';
    export default {
        components: {
            child
        },
        data() {
            return {
                lists: []}; }, mounted() {this.lists = [{
                name: '01'.content: 'hi,'
            }, {
                name: '02'.content: 'my name is Ellyliang'
            }];
        },
        methods: {
            getChildMsg(val) {
                alert(val);  // 'hello'}}};</script>// Child component child.vue<template>
    <div class="content">
        <ul class="lists">
            <li v-for="(list, index) in getLists" :key="index" v-html="list.name + list.content"></li>
        </ul>
    </div>
</template>
<script>
    export default {
        props: ['lists'],
        data() {
            return {
                getLists: this.lists
            };
        },
        mounted() {
            this.getLists.push({
                name: '03'.content: 'Don't care about the content, I'm the test.'
            });
            
            setTimeout((a)= > {
                this.$emit('listenToChild'.'hello');
            }, 15000); }};</script>
Copy the code

Is it also convenient for children to pass data to their parents? This is done by sending $emit data in the child component and receiving the value in the parent component via the event @event name.

Event Bus

The event bus method can not only handle parent-child component transfer, parent-child component transfer, but also handle the value transfer between horizontal components. Let bus = new vue(); . Send data via $emit, $ON, etc in the global bus. The problem with this approach is that because the Event Bus handles data passing conveniently and can be passed anywhere, it leads to abuse and makes the code hard to understand.

The Event Bus implementation

let bus = new Vue();
// Triggers the event in component A
bus.$emit('id-selected'.1);
// Listen for events in the hooks created by component B
bus.$on('id-selected'.function (id) {
// ...
});
Copy the code

For details about how to encapsulate and use components, see VUE-bus.

The other way

In addition to the above three methods, there is another way to deal with data transmission through VUEX, but I haven’t touched it yet. You should be interested and learn by yourself.