VUE2 VUE3 父子、隔代、兄弟组件的传值方式

2022年6月2日08:19:33

时隔一年多 vue 又增加了新的方法 所以又把此篇文章从新整理
2.2.0 新增 provide 和 inject (隔代传值)
2.4.0 新增 $attrs 和 $listeners (隔代传值)
已经 2022 年 vue 已经出了3.0版本,在组件传值方便也有了一些改动,最近有时间来做一些添加和修正

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

方法1:props /$emit(父子传值)

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

parent.vue

<template><divclass="parent">
    父亲:{{message}}<child:my-message="message"mm="123"></child> 
    // 注意传递参数时要用—代替驼峰命名,HTML不区分大小写
    // 通过属性传递 可传递动态属性 也可以传递静态属性 可传递数字、布尔值、数组、对象等任何类型的值</div></template><script>import childfrom'../base/child'exportdefault{data(){// 组件的data必须是函数return{
            message:'好好学习'}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

child.vue

<template><divclass="child">
    儿子:{{myMessage}}+{{mm}}</div></template><script>exportdefault{
        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 --><stylescoped></style>

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

parent.vue

<template><divclass="parent"><child@tell='know'></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用</div></template><script>import childfrom'../base/child'exportdefault{data(){// 组件的data必须是函数return{}},
        methods:{know(msg){alert(msg);}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

VUE 2 写法

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{childClick(){this.$emit('tell',this.msg)// 向父组件派发事件,this.msg为向父组件传递的数据}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

VUE 3 写法

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{
    	emits:['tell'],// vue 3需要对可触发的事件进行注册data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{childClick(){this.$emit('tell',this.msg)// 向父组件派发事件,this.msg为向父组件传递的数据}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

方法2:$refs /$emit (父子调用方法)

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

parent.vue

<template><divclass="parent"><divclass="todo"@click='todo'></div><childref='child'></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用</div></template><script>import childfrom'../base/child'exportdefault{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 --><stylescoped>.todo{width: 100px;height: 100px;background-color: red;}</style>

child.vue

<template><divclass="child"></div></template><script>exportdefault{data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{do(){alert('我是子组件的方法')}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

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

parent.vue

<template><divclass="parent"><child@tell='fatherMethod'></child>// 父组件中 在子组件上监听子组件派发的tell方法 然后调用函数 就能调用子组件的方法</div></template><script>import childfrom'../base/child'exportdefault{data(){// 组件的data必须是函数return{}},
        methods:{fatherMethod(){alert('我是父组件的know方法');}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{childClick(){this.$emit('tell')// 向父组件派发事件}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

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

parent.vue

<template><divclass="parent"><child:fatherMethod='fatherMethod'></child>// 父组件把方法传入子组件中,在子组件里直接调用这个方法</div></template><script>import childfrom'../base/child'exportdefault{
        methods:{fatherMethod(){alert('我是父组件的know方法');}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{
        props:{
            fatherMethod:{
                type: Function,default:null}},
        methods:{childClick(){this.fatherMethod()}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

方法3:$children /$parent(父子传值、调方法)

1.父向子 通过 $children 获取子组件数据和调用子组件方法(VUE 3已经移除,用 $refs 代替)

parent.vue

<template><divclass="parent"@click='fatherMethod'><child></child></div></template><script>import childfrom'../base/child'exportdefault{
        methods:{fatherMethod(){this.$children[0].childMethod()// $children获取的是子组件的数组 通过索引找到对应的子组件的实例
              console.log(this.$children[0].msg)}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.parent{width: 100px;height: 100px;background-color: blue;}</style>

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{childMethod(){alert('我是子组件的方法')}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

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

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

parent.vue

<template><divclass="parent"><child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用</div></template><script>import childfrom'../base/child'exportdefault{data(){// 组件的data必须是函数return{
            msg:'父组件数据测试'}},
        methods:{fatherMethod(){alert('我是父组件的方法')}},
        components:{
            child}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>

child.vue

<template><divclass="child"@click='childClick'></div></template><script>exportdefault{data(){return{
                msg:'我是子组件传递过来的数据'}},
        methods:{childClick(){this.$parent.fatherMethod()
                console.log(this.$parent.msg)}}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.child{width: 100px;height: 100px;background-color: blue;}</style>

方法4:$emit /$on(父子 兄弟 跨级)(VUE3 不支持)

VUE 2

父子 兄弟 跨级 这种方法通过一个空的Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案 vuex。

eventBus.js

import Vuefrom'vue';exportdefaultnewVue();

a.vue

<template><div>
  • 作者:alokka
  • 原文链接:https://blog.csdn.net/alokka/article/details/87104189
    更新时间:2022年6月2日08:19:33 ,共 6204 字。