vue 父子组件相互通信

2020-08-18  本文已影响0人  付蔷蔷

父子组件通信包括:

  1. 父组件调用子组件的方法、子组件调用父组件的方法、
  2. 父组件改变子组件的属性值、子组件改变父组件的属性值。

细分起来这是四种情况,其实可以总结为两种:
1. 父组件通过调用子组件方法改变子组件的属性值、
2.子组件通过调用父组件方法改变子组件值

换言之,明白怎么父调子方法,子调父方法,就知道怎么改变属性值了。

父调子:

1. 通过给子组件设置ref

// 父组件 father.vue:
<template>
  <div class="father">
    I'm {{name}}, and {{sonName}}'s father
    <child :father="name" ref="child" />
    <button @click="changeName('大头')"></button>
   </div>
</template>
<script>
import child from "./child"
export default {
  name: "father",
  data () {
    return {
      name: "小头爸爸",
      sonName: "",
      changeName: null
      }
   },
   mounted () {
      this.sonName = this.$refs.child.name;
      this.changeName = this.$refs.child.changeName;
   },
  methods: {
      showFatherName () {
         alert(`I'm a father, call me ${this.name}`)
      }
   },
    components: {
        child
      }
    }
</script>  
    // 子组件 child.vue
    <template>
        <div>
            I'm {{name}}
        </div>
    </template>
    <script>
        export default {
            name: 'child',
            data () {
                return {
                    name: "大头儿子"
                }
            },
            methods: {
                changeName (name) {
                    this.name = name
                }
            }
        }
    </script>

这样通过vm.$refs.child直接就能调用子组件的方法改变子组件属性,或者使用子组件的某些变量。 以上点击按钮,就可以通过调用子组件的changeName改变子组件的name了,效果如下图


父调子.gif

子调父:

1. 通过 vm.$parent 直接调用

    // 父组件
    <template>
        <div class="father">
            I'm {{name}}, and {{sonName}}'s father
            <child :fatherName="name" />
            <button @click="changeName('大头')"></button>
        </div>
    </template>
    <script>
        import child from "./child"
        export default {
            name: "father",
            data () {
                return {
                    name: "小头爸爸",
                    sonName: "",
                    changeName: null
                }
            },
            methods: {
                showName () {
                    alert(`I'm a father, call me ${this.name}`)
                }
            },
            components: {
                child
            }
        }
    </script> 
    // 子组件 child.vue
    <template>
        <div>
            I'm {{name}},and {{fatherName}}'s son.
            <button @click="changeName">点击</button>
        </div>
    </template>
    <script>
        export default {
            name: 'child',
            data () {
                return {
                    name: "大头儿子"
                }
            },
            methods: {
                changeName (name) {
                    return this.$parent.showName()
                }
            }
        }
    </script>

2. 通过 props 引用父组件的方法

    // 父组件 father.vue:
    <template>
        <div class="father">
            I'm {{name}}, and {{sonName}}'s father
            <child :fatherName="name" changeName="showName" />
        </div>
    </template>
    <script>
        import child from "./child"
        export default {
            name: "father",
            data () {
                return {
                    name: "小头爸爸",
                    sonName: "",
                    changeName: null
                }
            },
            methods: {
                showName () {
                    alert(`I'm a father, call me ${this.name}`)
                }
            },
            components: {
                child
            }
        }
    </script>  
    // 子组件 child.vue
    <template>
        <div>
            I'm {{name}}, and {{fatherName}}'s son.
            <button @click="changeName">点击</button>
        </div>
    </template>
    <script>
        export default {
            name: 'child',
            data () {
                return {
                    name: "大头儿子"
                }
            },
            props: {
                fatherName: {
                    type: String
                },
                changeName: {
                    type: String
                }
            }
        }
    </script>

通过 $emit 调用父组件的方法

     // 父组件 father.vue:
    <template>
        <div class="father">
            I'm {{name}}, and {{sonName}}'s father
            <child :fatherName="name" @showName="showName" />
        </div>
    </template>
    <script>
        import child from "./child"
        export default {
            name: "father",
            data () {
                return {
                    name: "小头爸爸",
                    sonName: ""
                }
            },
            methods: {
                showName (name) {
                    alert(`I'm a father, call me ${name}`)
                }
            },
            components: {
                child
            }
        }
    </script>  
    // 子组件 child.vue
    <template>
        <div>
            I'm {{name}}, and {{fatherName}}'s son.
            <button @click="changeName">点击</button>
        </div>
    </template>
    <script>
        export default {
            name: 'child',
            data () {
                return {
                    name: "大头儿子"
                }
            },
            props: {
                fatherName: {
                    type: String
                }
            },
            methods: {
                changeName: {
                    return this.$emit("showName", "小头爸爸")
                }
            }
        }
    </script>

三种方式实现的效果一样,图如下


子调父.gif

以上是父子组件相互间调用方法的例子,如果想子改变父变量或者父改变子的变量,直接在调用的方法里修改就行。

上一篇下一篇

猜你喜欢

热点阅读