vue 组件之间传值 父转子,子传父,同级别之间的传参,跨级别传参

写这篇文章之前,我对vue组件之间的传值,还是只知道一些基础的传值方式。虽然工作中勉强能够应对,但是想要行云流水感觉还是心有余而力不足,所以在此,我想总结一下vue组件之间的一些传值方式供大家参考,同时也是给自己加深下记忆。

vue的传值方式大概分为以下几种

  1. 父传子
  2. 子传父
  3. 兄弟间
  4. 隔代传参

首先我们介绍下第一种 父传子:

父传子方式1:最常用的就是props传值,这种方式大家都很熟悉,但是也有点小坑,比如父组件没有传递某一个值过来而子组件缺定义了这个值,这时候我们就需要设置默认值的方式解决该问题的出现,具体代码如下

//这是父组件 就叫father.vue
<template>
  <div id="father">
    <child :unit=unit></child>
  </div>
</template>

<script>
import child from './child.vue'
export default {
    data(){
        return {
            unit:'this is a unit'
        }
    },
    components:{child }
}
</script>




//这是一个子组件   就叫child.vue
<template>
  <div id="child">
    <p>unit:{{unit}}</p>
  </div>
</template>

<script>
export default {
  props: ['items', 'unit']  //注意这里父组件暂没有传items
}
</script>

如果items在父组件中没有传值,并且在child.vue里面接收且想要的是字符转类型的我们可以这么操作


//这是父组件 就叫father.vue
<template>
  <div id="father">
    <child :unit=unit></child>
  </div>
</template>

<script>
import child from './child.vue'
export default {
    data(){
        return {
            unit:'this is a unit'
        }
    },
    components:{child }
}
</script>




//这是一个子组件   就叫child.vue
<template>
  <div id="child">
    <p>unit:{{unit}}</p>
  </div>
</template>

<script>
export default {
 props: {
  items: {
    type: String,
    required: true, // 必须提供字段
    default:'this is a default'  //这是第一种写法
  },
  unit: {   // 可选字段,有默认值
    type: String,
    default:()=>{
       return 'this is a default'  // 这是第二种写法 
    }
  }
 }
}
</script>

//以上是传字符串的方式,其他类型类似,但是数组除外,如果是数组就要采用以下形式

array:{
    type: Array,
    default: function () { //这里也可以使用箭头函数的方式  和以上第二种形式类似
        return []
    }
}

 

父传子方式2:$refs 

$refs 利用ref标识组件,通过事件传参把数据传给子组件,数据相互独立

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue $ref</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
    Vue.component("parent",{
       data(){
           return{
               parentMsg:"我是父组件数据parent"
           }
       },
       template:`<div>
            <h3>父组件:{{parentMsg}}</h3>
            <button @click="send">点击改变子组件的数据</button><br/>
            <button @click="changSlef">点击改变父组件数据,但子组件的数据不变哦</button>
            <child ref="child"></child>            
        </div>`,
        methods:{
            send:function(){
                this.$refs.child.changeChild(this.parentMsg); //this.$refs.child 代表child组件。changeChild方法对应的child组件里面的changeChild方法  数据传参的形式传给子组件
            },
            changSlef:function(){
                this.parentMsg="我是父组件数据,我发生改变了"
            }
        }
    })
    
    Vue.component("child",{
        data() {
            return {
                childMsg:"我是子组件数据child"
            }
        },
       template:`<div>
            <h4>子组件:{{ childMsg }}</h4>
        </div>`,
        methods: {
            changeChild:function(val){
                this.childMsg=val; // 传参后接受,改变子组件的值
            }
        },
    })
    new Vue({
        el:"#app",
        template:`<div>
                <parent></parent>
            </div>`
    })
    </script>
</body>
</html>

父传子方式3:$attrs

$attrs通过绑定属性,来实现传值;可以实现,父传子,孙组件;$attrs是vue2.4版本提出的方法

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue $attrs</title>
<script src="https://cdn.staticfile.org/vue/2.4.0/vue.min.js"></script>
</head>
<body>
<div id="app"></div>
<script>
 Vue.component("component-c",{
        inheritAttrs:false,  //继承所有的父组件属性(除了prop传递的属性、class 和 style )
        template:`<div>
            <h5>c组件:{{$attrs.c}}</h5>
        </div>`
    })

    Vue.component("component-b",{
        inheritAttrs:false,  //继承所有的父组件属性(除了prop传递的属性、class 和 style )
        template:`<div>
            <h2>$attrs传递的值:{{$attrs.b}}</h2>
            <component-c v-bind="$attrs"></component-c>     
        </div>`
        //v-bind="attrs";绑定属性,是c组件可以接收a逐渐传值  注意注意注意注意
    })
    Vue.component("component-a",{
        data () {
            return {
                aMsg:"组件a",
                msgB:"组件a传给b的值",
                msgC:"组件a传给c的值",
                d:"默认值"
            }
        },
        template:`<div>
            <h1>a组件:{{ aMsg }}</h1>  
            <component-b :b="msgB" :c="msgC" ></component-b>
        </div>`
    })
    var app=new Vue({
        el:'#app',
        template:`<div>
             <component-a></component-a>
        </di> `
    })
</script>
</body>
</html>

父传子方式4:$children[0]

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue $children</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
</div>

<script>
    Vue.component("parent",{
       data(){
           return{
               parentMsg:"我是父组件数据parent"
           }
       },
       template:`<div>
            <h3>父组件:{{parentMsg}}</h3>
			<child></child>            
        </div>`,
		mounted(){
			this.$children[0].childMsg = 'hahah'+ this.parentMsg  //改变子组件的childMsg的值
		},
        methods:{}
    })
    
    Vue.component("child",{
        data() {
            return {
                childMsg:"我是子组件数据child"
            }
        },
       template:`<div>
            <h4 >子组件:{{ childMsg }}</h4>
        </div>`,
        methods: {},

    })

    new Vue({
        el:"#app",
        template:`<div>
                <parent></parent>
            </div>`
    })
    </script>
</body>
</html>

  以上是父传子的四种方式,可以根据需要自己选择,$attrs既可以实现父传子,又可以实现父传孙实现隔代传

接下来我们介绍下第二种 子传父:

  常用的就是$emit,具体代码如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue $ref</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
</div>

<script>
    Vue.component("parent",{
       data(){
           return{
               parentMsg:"我是父组件数据parent"
           }
       },
       template:`<div>
            <h3>父组件:{{parentMsg}}</h3>
            <button @click="send">点击改变子组件的数据</button><br/>
            <button @click="changSlef">点击改变父组件数据,但子组件的数据不变哦</button>
            <child ref="child" @parentClick="parentClick"></child>            
        </div>`,
        methods:{
            send:function(){
                this.$refs.child.changeChild(this.parentMsg);
            },
            changSlef:function(){
                this.parentMsg="我是父组件数据,我发生改变了"
            },
			parentClick:function(val){ //父接受子传来的值,改变父
			    this.parentMsg = val
			}
        }
    })
    
    Vue.component("child",{
        data() {
            return {
                childMsg:"我是子组件数据child"
            }
        },
       template:`<div>
            <h4 @click="changeParent">子组件:{{ childMsg }}</h4>
        </div>`,
        methods: {
            changeChild:function(val){
                this.childMsg=val;
            },
			changeParent:function(){ //子改父用emit传值
				this.$emit("parentClick" , this.childMsg)
			},
        },
    })

    new Vue({
        el:"#app",
        template:`<div>
                <parent></parent>
            </div>`
    })
    </script>
</body>
</html>

以上是子传父,如果大家还有其他的方式,欢迎以下留言,我再补上去,感谢

继续我们介绍下第三种 兄弟间:(这个有点意思了)

兄弟间传值需要创建一个新的js文件,内容不多就是如下两行代码,但是百度的时候大家可能看到有两种一个是eventVue.js一个是bus.js,其实内容是一样,只不过名字不同而已。在这里我就叫做bus.js,然后用$emi触发传参,$on去接收赋值。原理就是类似window的全局自定义事件,利用一个新的vue示例作为媒介,而不是当前vue示例(this)

import Vue from 'vue'
export default new Vue()

创建好了bus.js后,具体代码如下

<template>
     <components-a></components-a>  //组件A
     <components-b></components-b>  //组件B
</template>


//组件A
<template>
      <div class="components-a">
           <button @click="abtn">A按钮</button>
      </div>
</template>
<script>
import bus from '../../js/bus.js'
export default {
      name: 'app',
      data () {
        return {
                'msg':"我是组件A"
        }
      },
      methods:{
           abtn:function(){
               bus.$emit("myFun",this.msg)   //$emit这个方法会触发一个事件
           }
      }
}
</script>



//组件B 
<template>
     <div class="components-a">
         <div>{{btext}}</div>
     </div>
</template>
<script>
import bus from '../../js/bus.js'
export default {
   name: 'app',
   data () {
        return {
           'btext':"我是B组件内容"
        }
   },
   created:function(){
       this.bbtn();
   },
   methods:{
       bbtn:function(){
            bus.$on("myFun",(message)=>{   //这里最好用箭头函数,不然this指向有问题
              this.btext = message      
            })
       }
    }
}
</script>

最后我们介绍下最后一种隔代传参

采用的是provide / inject的形式,用法和父传子的props类似,具体代码如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue provide inject</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
</div>

<script>
    Vue.component("parent",{
       data(){
           return{
               parentMsg:"我是父组件,现在我想改变子子组件"
           }
       },
	   provide(){
	   	 return{
		 	 parentValue:"我是父组件"
		 }
	   },
       template:`<div>
            <h3>父组件:{{parentMsg}}</h3>
            <child></child>            
        </div>`,
        methods:{
        }
    })
    
    Vue.component("child",{
        data() {
            return {
                childMsg:"子组件"
            }
        },
       template:`<div>
            <h4>子组件:{{ childMsg }}</h4>
			<third></third>
        </div>`,
        methods: {
        },

    })
	
	 Vue.component("third",{
        data() {
            return {
                childMsg:"子子组件"
            }
        },
	   inject:['parentValue'],
       template:`<div>
            <h4>子子组件:{{ childMsg }}</h4>
        </div>`,
        mounted(){
			this.childMsg = this.parentValue
        },

    })

    new Vue({
        el:"#app",
        template:`<div>
                <parent></parent>
            </div>`
    })
    </script>
</body>
</html>

在定义父组件的时候用provide方法和data一样通过return 返回,在组件里需要改变的时候用inject 用法和props一样包括设置默认值的方式.

以上是组件之间的全部传参方式,包含了父转子,子传父,同级别之间的传参,跨级别传参的方法,如有不足之处还望指出,再加修改

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue中,组件向子组件传递数据是通过props来实现的。而子组件组件传递数据,则需要通过自定义事件来实现。 首先,在组件中,通过props属性将数据传递给子组件。可以在子组件标签上使用v-bind指令来动态绑定组件的数据,或者直接在子组件标签上写入固定的值。 例如,在组件中定义一个名为message的prop,并将一个字符串传递给子组件: ```vue <template> <div> <child-component :message="parentMessage"></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from parent' }; } }; </script> ``` 然后,在子组件中,可以通过props属性接收组件传递过来的数据,并在模板中使用该数据。 ```vue <template> <div> <p>{{ message }}</p> <button @click="sendMessageToParent">Send Message to Parent</button> </div> </template> <script> export default { props: ['message'], methods: { sendMessageToParent() { this.$emit('custom-event', 'Message from child'); } } }; </script> ``` 在子组件中,可以使用`props`属性声明接收的属性名,然后在模板中直接使用即可。另外,如果需要向组件发送数据,可以使用`$emit`方法触发一个自定义事件,并传递需要发送的数据。 最后,在组件中,可以通过在子组件标签上监听自定义事件来接收子组件传递的数据。 ```vue <template> <div> <child-component :message="parentMessage" @custom-event="receiveMessageFromChild"></child-component> <p>Message received from child: {{ childMessage }}</p> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from parent', childMessage: '' }; }, methods: { receiveMessageFromChild(message) { this.childMessage = message; } } }; </script> ``` 这样,就完成了子组件组件传递数据的过程。当子组件中的按钮被点击时,将会触发`custom-event`事件,并将消息发送给组件组件接收到消息后,将其保存在`childMessage`变量中,并在模板中进行展示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值