vue组件通讯:父传子、子传父、事件发射详解

1、组件通讯

        每个组件有自己的数据, 提供在data中;每个组件数据独立, 组件数据无法互相直接访问 (合理的)

        但是如果需要跨组件访问数据,  怎么办呢?  =>   组件通信组件通信的方式有很多: 现在先关注两种,  父传子  子传父。

2、组件通信 - 父传子

 首先明确父和子是谁, 在父引入子 (被引入的是子)

父传子语法:

1. 父组件通过给子组件加属性传值

2. 子组件中, 通过props属性接收

(1)在父组件中通过给子组件加属性传值 

<template>
  <div>
    <div class="row">
      <div class="col-12 pt-3">
        <!-- 2、父组件通过给子组件加属性list传值,语法为冒号 :属性名="属性值。属性值的变量需在data中声明" -->    
        <subject-table :list="list" @remove="delSubject"></subject-table>
      </div>
    </div>
  </div>
</template>

<script>
import SubjectTable from './components/subject-table.vue'
export default {
  data () {
    return {
    //1、声明变量list,即要传递给子组件的属性名的属性值
      list: [
        {
          id: 100,
          subject: "语文",
          score: 99,
          time: new Date("2010-08-12"),
        },
        {
          id: 101,
          subject: "数学",
          score: 34,
          time: new Date("2020-09-01"),
        },
        {
          id: 102,
          subject: "英语",
          score: 25,
          time: new Date("2018-11-22"),
        },
        {
          id: 103,
          subject: "体育",
          score: 99,
          time: new Date("2010-08-12"),
        },
      ],
    }
  },
}
</script>

<style scoped></style>

 (2)子组件中, 通过props属性接收

<script>
import moment from "moment"
export default {
    //子组件通过props属性接收
    //props: ['list'],
    //或者属性值也可以写成对象,接收数据的同时还可以校验数据类型
      props: {
               list: Object
            },
    data () {
        return {
        }
    },
    methods: {
    }
</script>

3、组件通信 - 子传父 

在vue中需要遵循单向数据流原则:从父到子的单向数据流动, 叫单向数据流)。

1. 父组件的数据变化了,会自动向下流动影响到子组件。

2. 子组件不能直接修改父组件传递过来的 props props是只读的。

vue不提倡子组件直接修改父组件的数据,因为子组件太多会难以追溯是哪个组件修改了父组件数据,导致代码难以维护。vue提倡子组件通过发射事件给父组件,让父组件亲自修改父组件的数据,也就是子传父

 子传父的基本语法:

1. 子组件可以通过 `this.$emit('事件名', 参数1, 参数2, ...)`  触发事件的同时传参给父组件。

2. 父组件监听子组件发送的事件;且父组件要提供对应的函数接收参数,执行业务代码。

(1)子组件发射事件给父组件 

<template>
  <div class="">
    <table class="table table-bordered">
          <thead>
            <tr>
              <th scope="col">编号</th>
              <th scope="col">科目</th>
              <th scope="col">成绩</th>
              <th scope="col">考试时间</th>
              <th scope="col">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item,index) in list" :key="item.id">
              <th scope="row">{{index}}</th>
              <td>{{item.subject}}</td>
              <td>{{item.score}}</td>
              <td>{{timeFormat(item.time)}}</td>
              <td>
                <button type="button" class="btn btn-link"
<!-- 子组件通过触发事件将参数index传给父组件 --> 
@click="$emit('remove',index)">删除</button>  
              </td>
            </tr>
            <tr class="bg-light">
              <th scope="row">统计</th>
              <td colspan="2">总分:{{total}}</td>
              <td colspan="2">平均分:{{avg}}</td>
            </tr>
          </tbody>
          <tfoot style="display: none">
            <tr>
              <td class="text-center" colspan="5">暂无数据</td>
            </tr>
          </tfoot>
        </table>
  </div>
</template>

<script>
export default {
    props: ['list'],
  data () {
    return {
    }
  },
  methods: {
    remove(){
        this.$emit('remove',
        })
    }
  }
}
</script>

<style scoped></style>

tip: 子组件发射事件还有另一种写法

子组件标签中写@触发事件名="函数名";同时在子组件的method方法中定义要执行的函数:如下例子的写法

// 1、子组件标签中写@触发事件名="函数名"
<form class="row align-items-center" @submit.prevent="add">
      <div class="col-3">
        <input type="text" class="form-control" placeholder="请输入科目" v-model.trim="subject" />
      </div>

      <div class="col-3">
        <input type="text" class="form-control" placeholder="请输入分数" v-model.number="score"/>
      </div>

      <div class="col-3">
        <button type="submit" class="btn btn-primary">添加</button>
      </div>
    </form>




export default {
    props: ['list'],
  data () {
    return {
        subject: '',
        score: ''
    }
  },
  methods: {
//2、在子组件的method方法中定义要执行的函数
    add(){
        this.$emit('add',{
            subject:this.subject,
            score: this.score
        })
    }
  }
}



 (2)父组件监听子组件发送的事件,提供对应的函数接收参数,执行业务代码

//父组件监听事件,语法为@事件名=父组件methods函数,delSubject为在methods中定义的函数
<subject-table :list="list" @remove="delSubject"></subject-table>



//delSubject为父组件在methods中定义的函数
methods{
delSubject(index){
      this.list.splice(index,1)
    },}
    

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值