Vue 3 TypeScript 接口Interface使用示例详解

 更新时间:2025年07月18日 10:47:21   作者:m0_61618849  
Vue3中TypeScript的接口用于定义组件props、数据模型、事件等类型结构,提升代码可读性与维护性,常见场景包括props类型、响应式数据、状态对象、事件类型等,本文给大家介绍Vue 3 TypeScript接口Interface使用示例,感兴趣的朋友一起看看吧

在 Vue 3 中使用 TypeScript 时,接口(Interface)是定义类型的重要工具。接口可以帮助我们明确组件 props、数据模型、函数签名等内容的类型结构,提高代码可读性和可维护性。

接口在 Vue 3 中的常见应用场景

1. 定义组件 Props 类型

// 用户信息接口
interface User {
  id: number;
  name: string;
  email: string;
  age?: number; // 可选属性
}
// 在组件中使用
export default defineComponent({
  props: {
    // 使用接口定义props类型
    user: {
      type: Object as () => User, // 类型断言
      required: true
    },
    // 简单类型
    isActive: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    // 现在可以安全访问props.user的属性
    const userName = computed(() => props.user.name);
    return { userName };
  }
});

2. 定义响应式数据模型

// 待办事项接口
interface TodoItem {
  id: number;
  title: string;
  completed: boolean;
  createdAt: Date;
}
export default defineComponent({
  setup() {
    // 使用接口定义响应式数据
    const todos = ref<TodoItem[]>([
      {
        id: 1,
        title: '学习 Vue 3',
        completed: false,
        createdAt: new Date()
      }
    ]);
    // 添加新待办事项的函数
    const addTodo = (title: string) => {
      const newTodo: TodoItem = {
        id: Date.now(),
        title,
        completed: false,
        createdAt: new Date()
      };
      todos.value.push(newTodo);
    };
    return { todos, addTodo };
  }
});

3. 定义复杂的状态对象

// 应用状态接口
interface AppState {
  isLoading: boolean;
  error: string | null;
  data: any[];
  page: number;
}
export default defineComponent({
  setup() {
    // 使用接口定义状态对象
    const state = reactive<AppState>({
      isLoading: false,
      error: null,
      data: [],
      page: 1
    });
    // 获取数据的方法
    const fetchData = async () => {
      state.isLoading = true;
      state.error = null;
      try {
        const response = await fetch(`/api/data?page=${state.page}`);
        state.data = await response.json();
      } catch (err) {
        state.error = '获取数据失败';
      } finally {
        state.isLoading = false;
      }
    };
    return { state, fetchData };
  }
});

4. 定义事件发射类型

// 自定义事件接口
interface CustomEvents {
  (e: 'update:name', value: string): void;
  (e: 'delete', id: number): void;
}
export default defineComponent({
  emits: ['update:name', 'delete'] as unknown as CustomEvents,
  setup(props, { emit }) {
    const updateName = (newName: string) => {
      // 类型安全的事件发射
      emit('update:name', newName);
    };
    const deleteItem = (id: number) => {
      // 类型安全的事件发射
      emit('delete', id);
    };
    return { updateName, deleteItem };
  }
});

5. 定义组合函数类型

// 计数器组合函数接口
interface Counter {
  count: Ref<number>;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}
// 创建计数器的组合函数
export function useCounter(initialValue = 0): Counter {
  const count = ref(initialValue);
  const increment = () => count.value++;
  const decrement = () => count.value--;
  const reset = () => count.value = initialValue;
  return { count, increment, decrement, reset };
}

6. 定义 API 响应类型

// API 响应接口
interface ApiResponse<T> {
  status: 'success' | 'error';
  message: string;
  data: T;
  timestamp: Date;
}
// 用户数据接口
interface UserData {
  id: number;
  name: string;
  email: string;
}
// 在组件中使用
export default defineComponent({
  setup() {
    const userData = ref<UserData | null>(null);
    const fetchUser = async (id: number) => {
      const response = await fetch(`/api/users/${id}`);
      const result: ApiResponse<UserData> = await response.json();
      if (result.status === 'success') {
        userData.value = result.data;
      }
    };
    return { userData, fetchUser };
  }
});

接口高级用法

1. 接口继承

// 基础实体接口
interface BaseEntity {
  id: number;
  createdAt: Date;
  updatedAt: Date;
}
// 用户接口继承基础实体
interface User extends BaseEntity {
  name: string;
  email: string;
  role: 'admin' | 'user';
}
// 产品接口继承基础实体
interface Product extends BaseEntity {
  name: string;
  price: number;
  description: string;
  category: string;
}

2. 索引签名

// 字典接口
interface Dictionary<T> {
  [key: string]: T;
}
// 在组件中使用
const colors: Dictionary<string> = {
  primary: '#3498db',
  secondary: '#2ecc71',
  danger: '#e74c3c'
};
const permissions: Dictionary<boolean> = {
  canEdit: true,
  canDelete: false,
  canCreate: true
};

3. 函数类型接口

// 比较函数接口
interface Comparator<T> {
  (a: T, b: T): number;
}
// 在组件中使用
const sortUsers = (users: User[], comparator: Comparator<User>) => {
  return [...users].sort(comparator);
};
// 创建比较器
const byName: Comparator<User> = (a, b) => a.name.localeCompare(b.name);
const byDate: Comparator<User> = (a, b) => 
  a.createdAt.getTime() - b.createdAt.getTime();

完整示例:使用接口的 Vue 3 组件

<template>
  <div class="user-profile">
    <h2>{{ user.name }}</h2>
    <p>邮箱: {{ user.email }}</p>
    <p v-if="user.age">年龄: {{ user.age }}</p>
    <div class="stats">
      <div class="stat-item">
        <span class="stat-label">文章数:</span>
        <span class="stat-value">{{ stats.postCount }}</span>
      </div>
      <div class="stat-item">
        <span class="stat-label">关注者:</span>
        <span class="stat-value">{{ stats.followerCount }}</span>
      </div>
    </div>
    <button @click="updateName">更新用户名</button>
  </div>
</template>
<script lang="ts">
import { defineComponent, PropType, reactive } from 'vue';
// 定义用户接口
interface User {
  id: number;
  name: string;
  email: string;
  age?: number;
}
// 定义用户统计数据接口
interface UserStats {
  postCount: number;
  followerCount: number;
  followingCount: number;
}
export default defineComponent({
  props: {
    user: {
      type: Object as PropType<User>,
      required: true
    }
  },
  setup(props, { emit }) {
    // 使用接口定义响应式状态
    const stats = reactive<UserStats>({
      postCount: 24,
      followerCount: 128,
      followingCount: 56
    });
    // 更新用户名的函数
    const updateName = () => {
      const newName = prompt('请输入新的用户名:');
      if (newName) {
        // 发射自定义事件
        emit('update:name', newName);
      }
    };
    return { stats, updateName };
  }
});
</script>
<style scoped>
.user-profile {
  max-width: 400px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #e1e1e1;
  border-radius: 8px;
  background-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h2 {
  color: #2c3e50;
  margin-bottom: 10px;
}
p {
  color: #7f8c8d;
  margin: 5px 0;
}
.stats {
  display: flex;
  margin: 20px 0;
  border-top: 1px solid #eee;
  padding-top: 15px;
}
.stat-item {
  flex: 1;
  text-align: center;
}
.stat-label {
  display: block;
  color: #95a5a6;
  font-size: 0.9rem;
}
.stat-value {
  display: block;
  font-size: 1.5rem;
  font-weight: bold;
  color: #3498db;
}
button {
  background-color: #3498db;
  color: white;
  border: none;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: background-color 0.3s;
}
button:hover {
  background-color: #2980b9;
}
</style>

到此这篇关于Vue 3 TypeScript 接口(Interface)使用的文章就介绍到这了,更多相关Vue TypeScript 接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue后台中优雅书写状态标签的方法实例

    Vue后台中优雅书写状态标签的方法实例

    在Vue中,我们可以非常便捷地通过标签实现状态的保存,这篇文章主要给大家介绍了关于Vue后台中如何优雅的书写状态标签的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08
  • Vue3中watchEffect和watch的基础应用详解

    Vue3中watchEffect和watch的基础应用详解

    watch是一个侦听器,默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数,watchEffect是会自动收集函数里面变量的响应式依赖,本文主要来讲讲二者的区别,感兴趣的可以了解一下
    2023-07-07
  • vue项目中使用rimraf dev启动时删除dist目录方式

    vue项目中使用rimraf dev启动时删除dist目录方式

    这篇文章主要介绍了vue项目中使用rimraf dev启动时删除dist目录方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue3+Element采用递归调用封装导航栏实现

    vue3+Element采用递归调用封装导航栏实现

    本文主要介绍了vue3+Element采用递归调用封装导航栏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 利用vite创建vue3项目的全过程及一个小BUG详解

    利用vite创建vue3项目的全过程及一个小BUG详解

    Vite作为一个构建工具,提供了一种快速的方法来构建Vue应用,而Vue3 则是一个前端框架,提供了强大的功能来构建和管理前端项目,下面这篇文章主要给大家介绍了关于利用vite创建vue3项目的全过程及一个小BUG的相关资料,需要的朋友可以参考下
    2023-04-04
  • vue如何跳转到其他页面

    vue如何跳转到其他页面

    跳转到指定URL,向history栈添加一个新的纪录,点击后退会返回至上一个页面,这篇文章给大家介绍vue如何跳转到其他页面,包括无参跳转和带参跳转,本文结合实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • vue 实现在函数中触发路由跳转的示例

    vue 实现在函数中触发路由跳转的示例

    今天小编就为大家分享一篇vue 实现在函数中触发路由跳转的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue中的局部组件介绍

    Vue中的局部组件介绍

    这篇文章主要介绍了Vue中的局部组件,文章围绕Vue局部组件得相关资料展开内容,需要的的小孩伙伴请参考下面文章的具体介绍,希望对你有所帮助
    2021-12-12
  • 一文详解vue3 watchEffect监听的各种姿势用法

    一文详解vue3 watchEffect监听的各种姿势用法

    watchEffect 会自动追踪在其回调函数中使用的所有响应式依赖,无需显式指定数据源,本文将为大家总结一下vue3 watchEffect监听的各种用法,有需要的可以了解下
    2026-03-03
  • Vue.js路由实现选项卡简单实例

    Vue.js路由实现选项卡简单实例

    这篇文章主要为大家详细介绍了Vue.js路由实现选项卡简单实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07

最新评论