vue3接口数据赋值对象,渲染报错问题及解决

  • Post category:http

Vue3 接口数据赋值对象、渲染报错问题及解决

在Vue3中,我们通常使用 constlet 声明变量,将从接口(API)获取的数据赋值给对象进行渲染。但是,在应用程序开发中,当从API获取的数据不符合预期格式或不存在时,就可能会出现一些问题。在这篇文章中,我们将探讨这些问题,以及如何避免和解决它们。

问题描述

当我们从API获取到的数据不能完全符合我们的期望格式时,就可能会发生以下问题:

渲染报错:在模板中使用不存在的数据属性、从未定义的变量或未处理的空值可能会导致渲染错误。

未定义错误:尝试访问不存在的属性或方法时,将导致未定义的错误。

类型错误:类型错误通常是由于将错误类型的数据分配给对象而引起的。在Vue3中,此类错误的根本原因是因为类型检查严格执行了。

解决方案

为杜绝出现以上问题,我们应该在获取API数据之前明确期望的数据格式,对API的返回进行格式校验。

使用 interface 对返回数据进行格式校验

在TypeScript中,我们可以使用 interface 来定义对象的格式,进而进行数据校验。例如,假设我们有一个API:

interface ApiResponse {
  id: number;
  name: string;
  age: number;
}

API返回的数据应该与 ApiResponse 接口一致,以避免后续的数据校验问题。

在具体的代码实现中,我们往往通过使用异步函数获取接口数据,如下:

async function fetchData() {
  const response = await fetch('/api/data');
  const data = await response.json();

  // 校验获取的数据格式是否符合约定格式
  if (!!data && !!data.id && !!data.name && !!data.age) {
    // 数据符合格式,赋值给变量
    const myData: ApiResponse = data;

    // 将赋值后的对象传递给Vue组件进行渲染
    createApp(App, { myData }).mount('#app');
  } else {
    // 如果数据格式不符合预期,我们就可以定义一个默认值并赋值给变量
    const myData: ApiResponse = { id: 0, name: 'default', age: 0 };

    // 将默认值传递给Vue组件进行渲染
    createApp(App, { myData }).mount('#app');
  }
}

在上述代码中,我们先通过 fetch 获取API数据,接着对数据进行格式校验,如果数据符合要求,则将数据赋值给 myData 对象并传递给Vue组件进行渲染。如果数据不符合我们的要求,则定义一个默认值(在这里值为 { id: 0, name: 'default', age: 0 }),并将其传递给Vue组件进行渲染。

使用 try-catch 处理未定义错误

当我们尝试访问不存在的属性时,会出现未定义错误,这时我们可以使用 try-catch 语句来捕获该错误并处理它。例如:

try {
  console.log(myData.noSuchProperty);
} catch (e) {
  console.log('Property does not exist.');
}

在上述代码中,我们将尝试访问 myData 对象中不存在的属性 noSuchProperty,如果访问失败,则 catch 捕获该错误并打印错误信息。

使用三元运算符解决类型错误

在Vue3中,类型检查严格执行了,当一个变量被分配为错误类型的数据时,将引发类型错误。为了解决这个问题,我们通常使用三元运算符。例如:

const myAge: number = typeof myData.age === 'number' ? myData.age : 0;

在上述代码中,我们先使用 typeof 判断 myData.age 是否是数字类型,如果是,则将其值分配给 myAge;如果不是,则将 0 赋值给 myAge

示例说明

假设我们有一个API获取用户的数据,数据接口示例如下:

interface ApiResponse {
  id: number;
  name: string;
  age: number;
}

示例1

首先,我们编写一个异步函数 fetchUserData,用于获取API数据,并校验其格式是否正确。

async function fetchUserData(id: number) {
  const response = await fetch(`/api/user/${id}`);
  const data = await response.json();

  if (!!data && !!data.id && !!data.name && !!data.age) {
    return data;
  } else {
    return { id: 0, name: 'default', age: 0 };
  }
}

在上述代码中,我们先通过 fetch 获取API数据,接着对数据进行格式校验,如果数据符合要求,则返回数据,否则返回 { id: 0, name: 'default', age: 0 }

接下来,我们创建一个Vue组件,用于将获取的数据进行展示:

<template>
  <div>
    <h2>{{ user.name }}</h2>
    <p>Age: {{ user.age }}</p>
  </div>
</template>

<script>
import { defineComponent, ref, watchEffect } from 'vue';

export default defineComponent({
  props: {
    userId: {
      type: Number,
      required: true,
    },
  },
  setup(props) {
    const user = ref<ApiResponse>({ id: 0, name: '', age: 0 });
    watchEffect(async () => {
      const data = await fetchUserData(props.userId);
      user.value = data;
    });
    return {
      user,
    };
  },
});
</script>

在上述代码中,我们通过 defineComponent 定义了一个Vue组件,该组件有一个 userId 属性,用于传递用户id。在 setup 函数中,我们定义了 user 变量,用于存储从API获取的用户数据。使用 watchEffect 监听 props.userId,在该值发生变化时获取新的用户数据并更新 user 变量。

最后,我们将该组件渲染到页面中:

<template>
  <div id="app">
    <my-component :userId="3" />
  </div>
</template>

<script>
import { createApp } from 'vue';
import MyComponent from './MyComponent.vue';

const app = createApp({});
app.component('my-component', MyComponent);
app.mount('#app');
</script>

在上述代码中,我们创建了一个Vue实例,并将组件 MyComponent 注册到该实例,然后将其挂载到DOM节点 #app 中。

示例2

在示例1中,我们仅仅是将非法数据替换为默认值,如果我们需要处理更为严重的错误,例如当API的返回状态码为 404 或 500 时,我们需要使用Catch语句来处理这些错误情况。修改 fetchUserData 函数,增加异常捕获处理:

async function fetchUserData(id: number) {
  try {
    const response = await fetch(`/api/user/${id}`);
    if (!response.ok) {
      throw new Error('API Error');
    }
    const data = await response.json();
    if (!!data && !!data.id && !!data.name && !!data.age) {
      return data;
    } else {
      throw new Error('Data Error');
    }
  } catch (e) {
    console.error(e);
    return { id: 0, name: 'default', age: 0 };
  }
}

在上述代码中,我们使用 try-catch 语句捕获可能出现的异常,例如返回状态码非 200 的情况或数据格式不正确的情况。如果出现异常,则将错误信息打印到控制台,并返回默认值 { id: 0, name: 'default', age: 0 }

总结

在Vue3应用程序中,我们应该在获取API数据之前明确期望的数据格式,并对数据进行格式校验。如果数据不符合我们的要求,我们可以定义默认值或捕获异常来避免问题的出现。这些方法能够帮助我们在Vue3开发中规避类型检查的问题,提高代码的可读性和可维护性。