Vue 父传子,子传父,兄弟组件通信

Vue 常用的三种传值方式

1.父传子
2.子传父
3.非父子传值

父子组件的关系

首先,我们要使用Vue的组件传值,我们要知道组件之间的关系。
父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示
在这里插入图片描述

什么是Prop

要实现组件传值,我们要了解什么是prop。
Prop是用来传递数据的一种自定义属性。
Prop是单向数据流。所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

父传子

父组件的内容传递给子组件其实很简单
首先建立俩个Vue的组件,例father.vue,child.vue
在father.vue的组件写上

<template>
  <div>
    <span>父组件:</span>    
  </div>
</template>

记住,我们的template下,只能拥有一个标签
在child.vue的组件写上

<template>
  <div>
    <span>子组件:</span>
  </div>
</template>

我们把子组件的内容引入到父组件里
于是,我们在father.vue导入

 import child from './child.vue'   // 引入子组件

然后,我们开始注册自定义标签

  export default {
    name: "father",
    components:{
      child    //这个名字是上面我们引进来的child.vue,俩个名字需相同
    }
  }
<template>
  <div>
    <span>父组件:</span>
    <child></child>
  </div>
</template>

我们开始v-model绑定数据
在data数据里写上name

  export default {
    name: "father",
    data() {
      return {
        name: ''
      }
    },
    components:{
      child    //这个名字是上面我们引进来的child.vue,俩个名字需相同
    }
  }

data里的数据为什么要return出来呢?
1.不使用return 出来的数据会在项目的全局可见,会污染全局
2.使用return 出来的数据只能在当前组件中使用,不会影响其他组件

当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

我们在组件中绑定data数据的name,在自定义标签中传递要传递的值

<template>
  <div>
    <span>父组件:</span>
    <input type="text" v-model="name">
    <child :notice="name"></child>
  </div>
</template>

最后,在child.vue组件中利用props来接收传递来的参数

  export default {
    name: "child",
    data() {
      return {}
    },
    props: ['notice']
  }

在上面的模板中运用传递来的参数

<template>
  <div>
    <span>子组件:{{notice}}</span>
  </div>
</template>

父传子所有的代码
father.vue

<template>
  <div>
    <span>父组件:</span>
    <input type="text" v-model="name">
    <child :notice="name"></child>
  </div>
</template>

<script>
  import child from './child.vue'   // 引入子组件
  export default {
    name: "father",
    data() {
      return {
        name: ''
      }
    },
    components:{
      child    //这个名字是上面我们引进来的child.vue,俩个名字需相同
    }
  }
</script>

<style scoped>

</style>

child.vue的代码

<template>
  <div>
    <span>子组件:{{notice}}</span>
  </div>
</template>

<script>
  export default {
    name: "child",
    data() {
      return {}
    },
    props: ['notice']
  }
</script>

<style scoped>

</style>

子传父

首先,我们要点击一个按钮,使子组件的值传到父组件。
于是,我们在子组件,写点击事件。
(这里在input的标签上绑定数据,还是和之前的一样)

<template>
  <div>
    <span>子组件:</span>
    <input type="text" v-model="childvalue">    //双向绑定childvalue
    <input type="button" value="传值到父亲" @click="childclick"> //点击事件
  </div>
</template>
  export default {
    name: "child",
    props: ['notice'],   //接收父组件传递的值
    data() {
      return {
        childvalue:this.notice
      }
    },
    methods: {
      childclick() {
        this.$emit("childByvalue", this.childvalue)   // 利用$emit的方法把值传递给父组件
      }
    }
  }

我们在父组件中接收传递的值利用的是v-on:,简写用@

<child :notice="name" @childByvalue="childByvalue"></child>

在下面的methods写方法

   methods : {
      childByvalue (val) {
        this.name=val
      }
    },

这时候细心的同学会发现子传父可以了,但父传子不能用了。
这时候就用到了watch来监听了。
在父组件中监听传递过了的值。

  watch:{
      notice () {
        this.childvalue=this.notice
      }
    },

这样父子组件的通信就完成了。
父组件的完整代码

<template>
  <div>
    <span>父组件:</span>
    <input type="text" v-model="name">
    <child :notice="name" @childByvalue="childByvalue"></child>
  </div>
</template>

<script>
  import child from './child.vue'   // 引入子组件
  export default {
    name: "father",
    data() {
      return {
        name: ''
      }
    },
    methods : {
      childByvalue (val) {
        this.name=val
      }
    },
    components:{
      child    //这个名字是上面我们引进来的child.vue,俩个名字需相同
    }
  }
</script>

<style scoped>

</style>

子组件的完整代码

<template>
  <div>
    <span>子组件:</span>
    <input type="text" v-model="childvalue">
    <input type="button" value="传值到父亲" @click="childclick">
  </div>
</template>

<script>
  export default {
    name: "child",
    props: ['notice'],
    data() {
      return {
        childvalue:this.notice
      }
    },
    watch:{
      notice () {
        this.childvalue=this.notice
      }
    },
    methods: {
      childclick() {
        this.$emit("childByvalue", this.childvalue)
        // 利用$emit的方法把值传递给父组件
      }
    }
  }
</script>

<style scoped>

</style>

非父子传值(兄弟组件传参)

非父子传参,需要有共同的父组件。需要定义公共的公共实例文件,作为中间仓库。不然达不到传值效果。
创建bus.js做为公共的仓库文件
bus.js内容为

import Vue from 'Vue'
export default new Vue

创建child1.vue,child2.vue
child1.vue内容为

<template>
  <div>
    <span>child1</span>
    <span>{{msg}}</span>
    <button @click="childclick">点击</button>
  </div>
</template>

<script>
import bus from './bus.js'
  export default {
    name: "child1",
    data () {
      return {
        msg :'123'
      }
    },
    methods : {
      childclick () {
        bus.$emit('val',this.msg)
      }
    }
  }
</script>

<style scoped>

</style>

child2的内容为

<template>
  <div>
    <span>child2</span>
    <span>{{cmsg}}</span>
  </div>
</template>

<script>
  import bus from './bus.js'
  export default {
    name: "child2",
    data () {
      return {
        cmsg : ''
      }
    },
    mounted () {
      let that =this
      bus.$on('val',(data)=>{
        console.log(data);
        this.cmsg=data
      })
    }
  }
</script>

<style scoped>

</style>

在父组件中导入注册

 import child1 from './child1.vue'
  import child2 from './child2.vue'
  components:{
      child1,
      child2
    }
    <child1></child1>
    <child2></child2>

Vue 的三种传值方式介绍完毕。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值