Vue组件通信

在开发中,我们经常会把一些复用率高的代码,封装成一个组件。但是封装组件里面的数据,不能写死,需要动态传入。但是由于在父组件发起的网络请求,所以需要用到组件之间的通信来传递数据。

父传子

首先在父组件里面注册子组件,父组件代码如下:

<template>
  <div id="app">
    <about></about>
  </div>
</template>


<script>
  //引入组件
  import about from './views/About'
  export default {
      data(){
          return {

          }
      },
      //注册组件
      components:{
          about,
      }
  }
</script>

<style lang="scss">

</style>

子组件代码:

<template>
    <div class="about">
        <h2>姓名:唐僧</h2>
        <h2>年龄:88</h2>
    </div>
</template>


<script>

    export default {
       
        data(){
            return {

            }
        },
        methods:{

        }
    }
</script>

效果图:

 在开发中我们经常会遇到,在父组件多次复用这个组件,这也是为什么要封装它的原因。假设父组件引用了三次这个组件。代码如下:

<template>
  <div id="app">
    <about></about>
    <br>
    <about></about>
    <br>
    <about></about>
  </div>
</template>


<script>
  //引入组件
  import about from './views/About'
  export default {
      data(){
          return {

          }
      },
      //注册组件
      components:{
          about,
      }
  }
</script>

<style lang="scss">

</style>

效果图:

 这时候,需求是每个组件里面的内容,需要根据父组件里面的数据来渲染子组件。这时候就需要用到通信。

首先说下父组件,需要在组件标签里面写一个标签属性,key、value的形式。这个key就是一会子组件用来接收的key,value就是所要传递的数据。

<template>
  <div id="app">
    <about :name="name1" :age="age1"></about>
    <br>
    <about :name="name2" :age="age2"></about>
    <br>
    <about :name="name3" :age="age3"></about>
  </div>
</template>


<script>
  //引入组件
  import about from './views/About'
  export default {
      data(){
          return {
              name1:'孙悟空',
              age1:66,
              name2:'唐僧',
              age2:88,
              name3:'沙和尚',
              age3:99,
          }
      },
      //注册组件
      components:{
          about,
      }
  }
</script>

<style lang="scss">

</style>

子组件需要用到props这个配置来接收,代码如下:

<template>
    <div class="about">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{age}}</h2>
    </div>
</template>


<script>
    export default {
       
        props:['name','age'],
        data(){
            return {

            }
        },
        methods:{

        }
    }
</script>

效果图:

需要注意的是,如果需要对父组件传递过来的数据进行修改的时候,最好不要直接对props里面的数据直接进行修改。先赋值给一个变量,在对这个变量进行修改。如下:

<template>
    <div class="about">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{userAge}}</h2>
        <button @click="addAge">++</button>
    </div>
</template>


<script>
    export default {
        props:['name','age'],
        data(){
            return {
                userAge:this.age
            }
        },
        methods:{
            addAge(){
                this.userAge++
            }
        }
    }
</script>

props还有其他两种写法:

1.可以限制父组件传递过来数据的类型做限制

2.限制类型的同时,可以限制父组件这个属性是否必传以及给一个默认值

代码如下:

<template>
    <div class="about">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{userAge}}</h2>
        <button @click="addAge">++</button>
    </div>
</template>


<script>
    export default {
        //第一种写法:简单的接收方式
        // props:['name','age'],

        //第二种写法:接收的同时对父组件传递的数据做类型限制
        // props:{
        //     name:String,//限制name为字符串类型
        //     age:Number//限制age为数字类型
        // },

        // 第三种写法
        props:{
            name:{
                type:String,//限制name为字符串类型
                required:true//限制name值必传
            },
            age:{
                type: Number,//限制age为数字类型
                default:100,//如果父组件未传值,则默认值为100
            }
        },
        data(){
            return {
                userAge:this.age
            }
        },
        methods:{
            addAge(){
                this.userAge++
            }
        }
    }
</script>

子传父

子组件传父组件有两种传值的方法:

第一种,通过父组件给子组件传递函数类型的props实现。

首先还是在组件标签上自定义属性,但是value值传的是一个函数。当子组件接收这个函数,并调用父组件这个函数并传入形参。这时候父组件就可以拿到子组件传递的参数。代码如下:

父组件:

<template>
  <div id="app">
    <h1>性别:{{sex1}}</h1>
    <!--sex的value是一个函数-->
    <about :name="name1" :age="age1" :getSex="getSex"></about>

    <br>
    <about :name="name2" :age="age2"></about>
    <br>
    <about :name="name3" :age="age3"></about>
  </div>
</template>


<script>
  //引入组件
  import about from './views/About'
  export default {
      data(){
          return {
              sex1:'',
              name1:'孙悟空',
              age1:66,
              name2:'唐僧',
              age2:88,
              name3:'沙和尚',
              age3:99,
          }
      },
      methods:{
          // 传递给子组件的函数
          getSex(val){
              //子组件调用这个函数,并传入形参。形参是就是子组件要传递过来的数据
              console.log(val)
              this.sex1 = val
          }
      },
      //注册组件
      components:{
          about,
      }
  }
</script>

<style lang="scss">

</style>

子组件:

<template>
    <div class="about">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{userAge}}</h2>
        <button @click="addAge">++</button>
        <br>
        <button @click="sendSex">点击给父组件传递性别</button>
    </div>
</template>


<script>
    export default {
        // getSex 父组件传递过来的函数
        props:['name','age','getSex'],
        data(){
            return {
                userAge:this.age,
                sex:'男'
            }
        },
        methods:{
            addAge(){
                this.userAge++
            },
            sendSex(){
                //调用父组件传过来的函数,并把要传递的参数写在函数的参数中
                this.getSex(this.sex)
            }
        }
    }
</script>

第二种方式就是通过自定义事件来进行传递。

自定义方法来通信的步骤大概是这样的:首先在按钮上面创建一个点击事件,通过这个点击事件来向父组件发射一个自定义事件。它是通过$emit()来发射事件的。

$enit的第一个参数是自定义事件名,第二个参数是向父组件传递的参数。

子组件代码:

<template>
    <div class="about">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{userAge}}</h2>
        <button @click="addAge">++</button>
        <br>
        <button @click="sendSex">点击给父组件传递性别</button>
    </div>
</template>


<script>
    export default {
        props:['name','age'],
        data(){
            return {
                userAge:this.age,
                sex:'男'
            }
        },
        methods:{
            addAge(){
                this.userAge++
            },
            sendSex(){
                //点击按钮,触发sendSex方法,利用$emit向父组件发射一个事件,$emit()第一个参数为事件名,第二个参数为要传递给父组件的值。
                this.$emit('getSex',this.sex)
            }
        }
    }
</script>

子组件通过$emit发射事件之后,父组件要接收。所以要在组件标签上面写一个自定义事件。这样当子组件使用$enit发射事件的时候,就会触发父组件里面这个自定义事件。

父组件代码:

<template>
  <div id="app">
    <h1>性别:{{sex1}}</h1>
    <!--自定义一个事件,这个事件名是getSex(必须和子组件发射的事件名一样),-->
    <!--当子组件$emit发射事件的时候,就会触发这个事件。触发这个事件就会调用addSex方法-->
    <about :name="name2" :age="age2" @getSex="addSex"></about>
  </div>
</template>


<script>
  //引入组件
  import about from './views/About'
  export default {
      data(){
          return {
              sex1:'',
              name1:'孙悟空',
              age1:66,
              name2:'唐僧',
              age2:88,
              name3:'沙和尚',
              age3:99,
          }
      },
      methods:{
          // 传递给子组件的函数
          addSex(val){
              //子组件触发自定义事件,调用这个函数,并传入形参。形参就是子组件要传递过来的数据
              console.log(val)
              this.sex1 = val
          }
      },
      //注册组件
      components:{
          about,
      }
  }
</script>

<style lang="scss">

</style>

以上就是子父组件通信的使用方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值