VUE3基础

70 阅读4分钟

Vue3中组件通信

1.方式1:defineProps

defineProps通常用于在单文件组件中,父组件向子组件传递数据。

1.1 示例

父组件 blog.vue

// Blog.vue

子组件 Article.vue

//Article.vue

const props = defineProps({ title: String, ... })

而实际上,value还可以为一个对象,其中对props的相关信息进行了设定,包括:

  • type — props的类型,如果可能存在多个类型,则可以写成数组形式,例如:[String,Number]
  • default — 该props的默认值
  • require — 是否为必传项,默认为false。 

以上面的title为例,其实际上可以写成:

const props = defineProps({ title: { type: String, default: '111', require: false, } })

字符串数组形式声明时,数组的每一项字面量就为prop对应的名称。

const props = defineProps(['title', 'info', 'author']);

其次,关于props的使用

在 template 模版中,直接使用defineProps()中声明的名称。

在 setup 中,只需要直接props.xxx就可以获取到该props对应的值。

另外,还需要注意:

  1.props一般是单向的,所以在子组件中不应该对 props 进行修改。如果需要在子组件中对props进行处理,应当使用ref对props进行处理后,再进行修改。

      const formatTitle = ref(props.title)
//这样,子组件中后续对 formatTitle 的修改,就与原props.title 无关联了

  2.当父组件传递的为一个对象时,例如对于上面的例子:

   
<!-- 也可 →

  此时,子组件中的声明不需要改变,但是需要将该对象中将会用到的属性值通过defineProps声明出来。

  3.在向子组件传递数据时,注意组件上用v-bind绑定的值不要重复,也不要与组件本身的属性重名!

2.defineEmits

同样地,defineEmits也常用于单文件组件的组件间通信,但其多用于子组件向父组件传递数据。

2.1 示例

父组件

子组件

其效果实际上就是点击后,子组件中的value加一。

下面对该示例进行说明。

首先,在父组件中,向子组件传递了一个num的props用于展示数据。

同时,在父组件中定义了一个名为 increase 的监听事件以及事件触发后的处理函数(即把num加一)。

而在子组件中,添加了一个点击事件,在该事件的处理函数中,通过对象emit触发了父组件的 increase 监听事件,导致num加一。

2.2 具体用法

defineEmitsdefineProps一样,不需要引入,可以在 setup 函数中直接使用。

defineEmits可以用于声明对父组件上的一个或多个监听事件的触发,并返回一个触发函数对象emit

下面是声明方式:

const emits = defineEmits(['increase']); // 声明多个触发 const emits = defineEmits(['increase', 'emit2', 'emit3']);

如何使用触发?

// 要触发哪个监听事件,就传入对应的事件名 emits('increase'); emits('emit2');

2.3 说明

关于emits()的参数:

  • 第一个参数,是监听事件的字面量(即名称)。
  • 第二个参数为事件传递的参数。如果该事件有多个参数,第二个参数建议用对象的形式传递。

例如:

//子组件发送,传递两个参数 emits('increase', {params1:'1',params2:'2'}); ... //父组件监听事件的处理函数 const handleIncrease = (params) => { console.log(params.params1, params.params2);//{'1','2'} nums.value += datas; };

3. $ref + defineExpose
这种方法通常用于实现父子组件之间的通信。

在 vue2 中,有时候想访问refs绑定的组件的属性或者方法,我们会使用refs绑定的组件的属性或者方法,我们会使用 refs。

但在 vue3 中,由于在 setup 中无法访问到 this,所以这种方式是不适用的!那么为了能够使用 $refs,我们需要借助一个方法:getCurrentInstance()。该对象返回当前的实例对象,但在使用该方法时,需要注意:

  • 不要将该函数当作一个 optionsApi 来获取 this
  • 该方法仅在 setup生命周期函数中有效,在方法中是无效的。

3.1 实例
父组件

子组件

这里需要注意的是:在使用<script setup>语法糖时,组件是默认关闭的,即:在父组件中通过$refs来访问子组件中的值在子组件中通过$parents来访问父组件中的值时,都是取不到的!必须通过defineExpose暴露对应值后,才可以被访问到。

3.2 说明

实际上,在开发中,上面使用$refs的方式并不多见,因为其必须要依靠getCurrentInstance()方法。

使用较多的是下面这种方法:

或者可以这样:

即在<script setup>语法糖中,可以不用返回,因为其中的值为自动返回。

接下来就可以通过声明的响应式对象来使用对应组件中通过defineExpose暴露出来的属性了!

4.其它方法

vue3中除了以上三种组件间通信的方式,还有其它可以实现组件间通信的方法:

  • v-model
  • 依赖注入 provide / inject
  • eventBus
  • vuex

其中,v-model 并不能严格成为数据的传递方式,其实只是减少了代码量。

而关于 eventBus,虽然 vue3 中将其移除,但仍然可以通过第三方插件来使用。