VUE 父子组件的传递 props、$ref 、 $emit、$parent、$children、$root

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/alokka/article/details/87104189

组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。那么组件间如何通信,也就成为了vue中重点知识了。这篇文章将会通过props、$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信。

1.父向子 通过 props 传递数据

parent.vue

<template>
  <div class="parent">
    父亲:{{message}}
    <child :my-message="message" mm="123"></child> 
    // 注意传递参数时要用—代替驼峰命名,HTML不区分大小写
    // 通过属性传递 可传递动态属性 也可以传递静态属性 可传递数字、布尔值、数组、对象等任何类型的值
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data(){ // 组件的data必须是函数
          return {
            message:'好好学习'
          }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

child.vue

<template>
  <div class="child">
    儿子:{{myMessage}}+{{mm}}
  </div>
</template>

<script>

    export default {
        props:['myMessage','mm'],// 方式一
        // 方式二
        // props: {
        //     myMessage: Array  //指定传入的类型,如果类型不对,会警告
        // },
        // // 方式三
        // props: {
        //     myMessage: {
        //         type: Array,
        //         default: [5,6,7]  //指定默认的值
        //     }
        // }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

2.父向子 通过 $ref 获取子组件数据 调用子组件方法

parent.vue

<template>
  <div class="parent">
  <div class="todo" @click='todo'></div>
    <child ref='child'></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data(){ // 组件的data必须是函数
          return {
          }
        },
        methods:{
            todo(){
                console.log(this.$refs.child.msg)
                this.$refs.child.do()
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .todo{
    width: 100px;
    height: 100px;
    background-color: red;
  }
</style>

child.vue

<template>
  <div class="child">
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            do(){
                alert('我是子组件的方法')
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

3.父向子 通过 $children 获取子组件数据和调用子组件方法

parent.vue

<template>
  <div class="parent" @click='fatherMethod'>
    <child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        methods:{
          fatherMethod() {
              this.$children[0].childClick() // $children获取的是子组件的数组 通过索引找到对应的子组件的实例
              console.log(this.$children[0].msg)
          }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .parent{
    width: 100px;
    height: 100px;
    background-color: blue;
  }

</style>

child.vue

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$children.fatherMethod()
                console.log(this.$children.msg)
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }

</style>

1.子向父 通过 $emit 向父组件派发事件,父组件调用获取子组件参数

parent.vue

<template>
  <div class="parent">
    <child @tell='know'></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data(){ // 组件的data必须是函数
          return {
          }
        },
        methods:{
            know(msg) {
                alert(msg);
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

child.vue

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$emit('tell',this.msg) // 向父组件派发事件,this.msg为向父组件传递的数据
        	}
            }
        }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }

</style>

2.子向父 通过 $emit 向父组件触发一个事件 子组件就可以调用父组件的方法

parent.vue

<template>
  <div class="parent">
    <child @tell='fatherMethod'></child>// 父组件中 在子组件上监听子组件派发的tell方法 然后调用函数 就能调用子组件的方法
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data(){ // 组件的data必须是函数
          return {
          }
        },
        methods:{
            fatherMethod() {
                alert('我是父组件的know方法');
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

child.vue

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$emit('tell') // 向父组件派发事件
        	}
            }
        }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }

</style>

3.子向父 父组件把方法传入子组件中 在子组件里直接调用这个方法

parent.vue

<template>
  <div class="parent">
    <child :fatherMethod='fatherMethod'></child>// 父组件把方法传入子组件中,在子组件里直接调用这个方法
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        methods:{
            fatherMethod() {
                alert('我是父组件的know方法');
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

child.vue

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        props:{
            fatherMethod: {
                type: Function,
                default: null
            }
        },
        methods:{
            childClick(){
                this.fatherMethod()
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }
  
</style>

4.子向父 通过 $parent 获取父组件数据和调用父组件方法

$root 和 $parent 都能够实现访问父组件的属性和方法,两者的区别在于,如果存在多级子组件,通过parent 访问得到的是它最近一级的父组件,通过root 访问得到的是根父组件(App.vue) 所以存在组件嵌套的情况下 不要使用 $root

parent.vue

<template>
  <div class="parent">
    <child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data() { // 组件的data必须是函数
          return {
            msg:'父组件数据测试'
          }
        },
        methods:{
          fatherMethod() {
            alert('我是父组件的方法')
          }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>


child.vue

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$parent.fatherMethod()
                console.log(this.$parent.msg)
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }

</style>

上面这些方法都可以实现父子组件互相传递数据和方法调用,但是效率有所不同,根据实际需求选择合适的方法,❤

猜你喜欢

转载自blog.csdn.net/alokka/article/details/87104189