不知道小伙伴们还记不记得在用 Vue 构建 TodoList 案例的博客中,我们有涉及到要从子组件中把数据传递给父组件,当时我用的方法是,让父组件给子组件传递一个函数,然后子组件把要传过来的数据放在那个函数中,这样父组件就可以拿到数据了。当然方法不止这一种,这不,博主又学到新方法了,迫不及待给你们分享。

一种组件间通信的方式,适用于:子组件 ===> 父组件

使用场景:A 是父组件,B 是子组件,B 想给 A 传数据,那么就要在 A 中给 B 绑定自定义事件(事件的回调在 A 中

组件自定义事件_绑定:

第一种方式:

在父组件中:

<Student @getDate="getStudentName" /> 或 <Student v-on:getDate="getStudentName"/>

在父组件中通过 @ 或 v-on 方式给要提交数据的组件(即这里的 Student 组件)绑定一个名 getDate  的自定义事件,当这个自定义事件被触发的时候就会执行 getStudentName 方法,该方法定义在父组件中,子组件触发该 getDate 自定义事件的方式是:this.$emit("getDate", 数据) 通过 $emit 方式,第一个参数是要触发的事件名,第二个参数是要传过去的数据,当然后面还可以继续写多个数据,都会被一并传过去

App.vue(父组件)

<template>
  <div class="box">
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用 @ 或 v-on) -->
    <Student v-on:getDate="getStudentName"></Student>
  </div>
</template>

<script>
//引入 Student 组件
import Student from "./components/Student";

export default {
  name: "App",
  },
  components: {
    Student,
  },
  methods: {
    getStudentName(value, ...a) {
      //把除第一个数据之外的,其余数据以数组的形式放到 a 中
      console.log("我拿到了学生的名字", value, a);
    },
  },
};
</script>

<style>
/*base*/
.box {
  background: #ccc;
}
</style>

Student.vue(子组件)

<template>
  <div class="student">
    <h1>{{ msg }}</h1>
    <h2>学生姓名: {{ myName }}</h2>
    <h2>学生性别: {{ mySex }}</h2>
    <button @click="sendStudentName">点我提交数据</button>
    <!--通过点击事件,触发 sendStudentName 方法-->
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
      msg: "我是一个大三的学生",
      myName: "张三",
      mySex: "男",
    };
  },
  methods: {
    sendStudentName() {
      // 在该方法中通过原型对象触发 getDate 自定义事件,传入多个数据
      this.$emit("getDate", this.myName, 6666,87778);
    },
  },
};
</script>

<style lang="less" scoped>
.student {
  border: 2px solid pink;
}
</style>

第二种方式:

在父组件中:

<Student ref="demo" /> ......

mounted(){

    this.$refs.demo.$on('getDate',this.getStudentName)

}

这种方式,通过 ref 来获取到 Student 的组件实例对象,并将其放到 demo 中,要使用的时候通过 this.$refs.demo ,打印输出来的就是 Student 的组件实例对象,然后我们在其上面绑定一个自定义事件 getDate,当这个事件触发的时候,就调用后面的方法(如果该方法在父组件中定义好了,那就通过 this.xxx 来获取,或者直接将其写成箭头函数) ,触发该事件的方法写在子组件中,跟方法一同理,this.$emit("getDate", 数据)

App.vue(父组件)

<template>
  <div class="box">
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用 ref) -->
    <Student ref="demo" /> 
  </div>
</template>

<script>
import Student from "./components/Student";

export default {
  name: "App",
  components: {
    Student,
  },
  methods: {
    getStudentName(value, ...a) {
      console.log("我拿到了学生的名字", value, a);
    },
  },
  mounted() {
    setTimeout(() => {
      //通过获取到 student 组件给它绑定一个 getDate 事件,当触发这个事件的时候调用 getStudentName 方法
      this.$refs.demo.$on("getDate", this.getStudentName);
      // 让这个方法只执行一次
      // this.$refs.demo.$once("getDate", this.getStudentName);
    }, 3000);
  },
};
</script>

<style>
/*base*/
.box {
  background: #ccc;
}
</style>

(Student 子组件中的代码和方法一中的一样,所以这里就不再放了)

其中若想让自定义事件只能触发一次,可以使用 once 修饰符,或 $once 方法

方法二与方法一相比,虽然方法二代码要多一些,但是灵活性也更高,因为它可以配合定时器使用,实现延迟几秒后再绑定

组件自定义事件_解绑:

this.$off('demo') //解绑一个自定义事件
this.$off(['demo1','demo2'])  //解绑多个自定义事件
this.$off(); //解绑全部事件


Logo

前往低代码交流专区

更多推荐