Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 与 TypeScript 的深度整合

与 TypeScript 的深度整合

TypeScript 作为 JavaScript 的超集,为 Vue 3 项目提供了类型安全和更好的开发体验。Vue 3 从底层设计上优化了对 TypeScript 的支持,尤其在 Composition API 和生态工具(如 Vite、Pinia)的配合下,实现了深度整合。本节将详细讲解如何在 Vue 3 中使用 TypeScript,涵盖配置、组件编写和状态管理,并通过示例展示其实际应用,帮助你打造类型安全的现代应用。

为什么使用 TypeScript?

  • 类型安全:捕获潜在错误,提升代码可靠性。
  • 开发效率:智能提示和自动补全加速编码。
  • 团队协作:类型定义作为文档,减少沟通成本。
  • 生态支持:Vue 3 核心及主流库(如 Pinia、Vue Router)原生支持。

配置 TypeScript

初始化项目

使用 Vite 创建带 TypeScript 的 Vue 项目:

npm create vite@latest my-ts-app --template vue-ts
cd my-ts-app
npm install

项目结构

my-ts-app/
├── src/
│   ├── main.ts         # TS 入口文件
│   ├── App.vue        # 根组件
│   ├── vite-env.d.ts  # 环境声明
│   └── shims-vue.d.ts # Vue 文件类型声明(可选)
├── tsconfig.json      # TypeScript 配置
├── vite.config.ts     # Vite 配置
└── package.json

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*", "vite.config.ts"],
  "exclude": ["node_modules", "dist"]
}

vite.config.ts

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

组件中的 TypeScript

基本用法

App.vue

<template>
  <h1>{{ title }}</h1>
  <Counter :initial="10" />
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import Counter from './Counter.vue';

export default defineComponent({
  components: { Counter },
  setup() {
    const title = ref<string>('Vue 3 with TypeScript');
    return { title };
  }
});
</script>

Counter.vue

<template>
  <div>
    <p>计数: {{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';

export default defineComponent({
  props: {
    initial: {
      type: Number,
      default: 0
    }
  },
  setup(props) {
    const count = ref<number>(props.initial);
    const increment = () => count.value++;
    return { count, increment };
  }
});
</script>
  • 效果:显示标题和计数器,点击增加计数。
  • 解析:
    • lang="ts":启用 TypeScript。
    • defineComponent:提供类型推导支持。
    • 类型注解(如 string、number)增强安全性。

类型定义

Props 类型

<script lang="ts">
import { defineComponent, PropType } from 'vue';

interface User {
  id: number;
  name: string;
}

export default defineComponent({
  props: {
    user: {
      type: Object as PropType<User>,
      required: true
    }
  },
  setup(props) {
    return { userName: props.user.name };
  }
});
</script>
  • 效果:接收 User 类型对象,访问属性有类型提示。

自定义事件

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  emits: {
    'update:value': (value: number) => typeof value === 'number'
  },
  setup(props, { emit }) {
    const increment = () => emit('update:value', 42);
    return { increment };
  }
});
</script>
  • 效果:确保事件参数类型正确。

与 Pinia 的整合

Store 定义

// src/stores/counter.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref<number>(0);
  const increment = () => count.value++;
  return { count, increment };
});

使用

<template>
  <p>计数: {{ store.count }}</p>
  <button @click="store.increment">增加</button>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { useCounterStore } from '@/stores/counter';

export default defineComponent({
  setup() {
    const store = useCounterStore();
    return { store };
  }
});
</script>
  • 效果:类型安全的 Store 操作。

与 Vue Router 的整合

路由配置

// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';

const routes: RouteRecordRaw[] = [
  { path: '/', component: () => import('@/views/Home.vue') },
  { path: '/about', component: () => import('@/views/About.vue') }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

使用

<script lang="ts">
import { defineComponent } from 'vue';
import { useRouter, useRoute } from 'vue-router';

export default defineComponent({
  setup() {
    const router = useRouter();
    const route = useRoute();

    const goToAbout = () => router.push('/about');

    return { path: route.path, goToAbout };
  }
});
</script>
  • 效果:类型化的路由操作。

高级用法

1. 类型推导增强

自定义 Hook

// src/hooks/useCounter.ts
import { ref, Ref } from 'vue';

export function useCounter(initial: number): { count: Ref<number>, increment: () => void } {
  const count = ref(initial);
  const increment = () => count.value++;
  return { count, increment };
}
<script lang="ts">
import { defineComponent } from 'vue';
import { useCounter } from '@/hooks/useCounter';

export default defineComponent({
  setup() {
    const { count, increment } = useCounter(0);
    return { count, increment };
  }
});
</script>

2. 类型声明文件

shims-vue.d.ts(可选)

declare module '*.vue' {
  import { DefineComponent } from 'vue';
  const component: DefineComponent<{}, {}, any>;
  export default component;
}
  • 作用:为 .vue 文件提供类型支持。

实践:完整示例

组件与 Store

// src/stores/user.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';

interface User {
  id: number;
  name: string;
}

export const useUserStore = defineStore('user', () => {
  const users = ref<User[]>([]);
  const addUser = (user: User) => users.value.push(user);
  return { users, addUser };
});
<!-- src/App.vue -->
<template>
  <div>
    <input v-model="newUser" @keyup.enter="addUser" placeholder="输入用户名" />
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { useUserStore } from '@/stores/user';

export default defineComponent({
  setup() {
    const userStore = useUserStore();
    const newUser = ref<string>('');

    const addUser = () => {
      if (newUser.value.trim()) {
        userStore.addUser({ id: Date.now(), name: newUser.value });
        newUser.value = '';
      }
    };

    return { users: userStore.users, newUser, addUser };
  }
});
</script>
  • 效果:类型安全的用户列表管理。

注意事项

  1. 严格模式:
    • strict: true 可能增加类型检查负担,初期可关闭部分选项。
  2. Props 复杂类型:
    • 使用 PropType 处理对象或数组。
  3. IDE 支持:
    • 使用 VS Code + Volar 插件优化体验。

总结

Vue 3 与 TypeScript 的深度整合通过 Composition API 和生态工具实现了类型安全和高效率。无论是组件 Props、Pinia Store 还是 Vue Router,都能享受类型推导和智能提示的好处。本节的实践为你提供了完整的 TypeScript 配置和使用方法,下一章将探讨性能优化,进一步提升你的 Vue 3 技能!

Last Updated:: 2/24/25, 2:55 PM