Vue3组件间通信的多种方式

在「接口测试平台」专栏的《13 接口自动化 接口管理模块开发(二)》中接口管理页面布局使用了很多子组件,组件间关系如下:

那么这些组件间要如何通信呢?本章将几种通信方式整理如下:

  • 父组件的信息传递给子组件
  • 子组件的信息传递给父组件
  • 父组件获取子组件的信息

父组件信息传递给子组件

拿上图的ApiListViewApiListContent举例。父组件是ApiListView,子组件是ApiListContent

子组件定义prop变量用来接收父组件传递的信息。

const props = defineProps({
    
    
  category_id: {
    
    
    type: String,
    default: "",
  },
  initData: {
    
    
    type: Object,
  },
});

父组件在引用子组件时,通过:子组件定义变量名的方式进行赋值。

<api-list-content
  v-if="!show"
  :category_id="category_id"
  :initData="apiDetail"
></api-list-content>

子组件信息传递给父组件

拿上图的ApiListViewApiListSider举例。父组件是ApiListView,子组件是ApiListSider

子组件定义emit方法用来调用父组件的方法将传递的信息作为方法参数。

const emits = defineEmits(["showDefault"]);

const showApiContent = (id) => {
    
    
  emits("showDefault", id, false);
};

父组件中定义自己的方法,然后在引用子组件时,通过@子组件定义方法名的方式进行赋值。

<template>
  <div class="api">
    <a-layout>
      <a-layout-sider>
        <api-list-sider
          @showDefault="showApiContent"
        ></api-list-sider>
      </a-layout-sider>
...
    </a-layout>
  </div>
</template>

<script setup>
import ApiListSider from "@/components/apis/ApiListSider.vue";
import {
      
       ref } from "vue";

const show = ref(true);
const category_id = ref("");

const showApiContent = (id, defaultShow) => {
      
      
  show.value = defaultShow;
  category_id.value = id;
};
</script>

父组件主动获取子组件信息

除上面说到的两种情况外,还存在父组件想要主动获取子组件的变量和方法的情况。拿上图的ApiListContentApiParams举例。父组件是ApiListContent,子组件是ApiParams

子组件中定义自己的变量和方法,然后通过defineExpose将方法或者变量暴露出去。

...
const data = ref("");

const getData = () => {
    
    
  return data.value;
};
defineExpose({
    
    
  getData,
});

父组件在引用子组件的地方定义子组件的ref属性,然后定义一个同名的变量,然后就可以通过这个ref变量访问子组件暴露出来的方法了。

<template>
  ...
  <a-tab-pane key="1" tab="请求参数">
    <api-params ref="apiParam" :initData="formState.params"></api-params>
  </a-tab-pane>
  ...
</template>
<script>
const apiParam = ref();

const saveApi = () => {
      
      
  ...
  // 获取请求参数
  if (apiParam.value) {
      
      
    formState.value.params = JSON.stringify(apiParam.value.getData());
  }
  ...
};
</script>

其他方案

以上就是几种组件间的通信方式了,但是当页面子组件嵌套层级很深时,或者是一个父组件引用了两个子组件,这两个子组件通信需要通过父组件传递信息时,一层一层的转递信息是很容易出错的,因此可以使用状态管理器,即将变量作为全局变量进行使用,任何组件都可以更新,任何组件都可以获取,就不再需要在组件间进行数据传递。

Vue框架提供了两种状态管理器,一个是Vuex,一个是Pinia,目前Vue3版本官方推荐使用的是后者,「接口测试平台」专栏中也是使用的后者,感兴趣的可以去了解下。

但是状态是保存在内存中的,如果刷新页面状态就会重新初始化,如果想要保存的画,就可以使用SessionStorageLocalStorage将数据进行保存,SessionStorage保存的数据用于浏览器的一次会话(session),当会话结束(通常是窗口关闭),数据就会被清空;LocalStorage保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。

除此之外,还可以使用Cookie,它在过期时间内也都可用的,并且会自动携带到请求头当中,当然还有一些别的特性,本章主要是将组件间的通信方式,大家感兴趣可以深入了解下。

猜你喜欢

转载自blog.csdn.net/ahu965/article/details/127177509