【TypeScript】ts在vue中的使用
目录
一、Vue 3 + TypeScript
1. 项目创建与配置
项目创建
关键配置文件
2.完整项目结构示例
3. 组件 Props 类型定义
4. 响应式数据与 Ref
5. Composition 函数复用
二、组件开发
1.组合式API(Composition API)
2.选项式API(Options API)
三、Vue 2 + TypeScript
1. 安装依赖
2. 类组件(Vue Class Component)
3.Vuex类型安全
四、状态管理(Pinia + TypeScript)
1. 定义 Store
2. 在组件中使用
五、高级类型操作
1.全局属性扩展
2. 为无类型库添加声明
3.泛型组件
4.使用 Vue Router
六、最佳实践
严格类型检查:
类型导入:
避免 any:
性能优化
七、常见问题
Q1:模板中的类型检查
Q2:处理$refs类型
Q3:动态路由类型(Vue Router)
Q2: 如何处理模板中的类型检查?
八、学习资源
一、Vue 3 + TypeScript
Vue 3 原生支持 TypeScript,推荐使用 <script setup> 语法糖和 Composition API。
1. 项目创建与配置
项目创建
使用 Vue CLI 或 Vite 创建支持 TypeScript 的 Vue 项目:
# 使用 Vite 创建 Vue + TS 项目(推荐)
npm create vite@latest my-vue-app -- --template vue-ts# 进入项目并运行
cd my-vue-app
npm install
npm run dev# 使用 Vue CLI(需全局安装 @vue/cli)
vue create my-vue-app
# 选择 "Manually select features" → 勾选 TypeScript
关键配置文件
tsconfig.json
{"compilerOptions": {"target": "ESNext","module": "ESNext","strict": true, // 启用严格模式"jsx": "preserve", // 支持 JSX(可选)"moduleResolution": "node","baseUrl": "./","paths": {"@/*": ["src/*"] // 路径别名},"types": ["vite/client"] // Vite 环境类型},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
}
vite.config.ts(vite项目)
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';export default defineConfig({plugins: [vue()],resolve: {alias: {'@': '/src' // 路径别名}}
});
2.完整项目结构示例
src/components/Button.vue // 基础组件GenericList.vue // 泛型组件stores/counter.ts // Pinia Storetypes/global.d.ts // 全局类型扩展api.d.ts // API 响应类型views/Home.vueApp.vuemain.tsvite-env.d.ts
3. 组件 Props 类型定义
<script setup lang="ts">
// 定义 Props 类型
interface Props {title: string;count?: number; // 可选参数isActive: boolean;
}// 声明 Props(withDefaults 设置默认值)
const props = withDefaults(defineProps<Props>(), {count: 0,isActive: false
});// 使用 Props
console.log(props.title);
</script><template><div :class="{ active: props.isActive }">{{ title }} - {{ count }}</div>
</template>
4. 响应式数据与 Ref
<script setup lang="ts">
import { ref, computed } from 'vue';// 定义响应式数据(自动推断类型)
const count = ref(0); // 类型为 Ref<number>// 显式指定复杂类型
interface User {name: string;age: number;
}
const user = ref<User>({ name: 'Alice', age: 30 });// 计算属性
const doubleCount = computed(() => count.value * 2);// 函数
const increment = () => {count.value++;
};
</script>
5. Composition 函数复用
// composables/useCounter.ts
import { ref } from 'vue';export default function useCounter(initialValue: number = 0) {const count = ref(initialValue);const increment = () => {count.value++;};return {count,increment};
}// 在组件中使用
<script setup lang="ts">
import useCounter from '@/composables/useCounter';const { count, increment } = useCounter(10);
</script>
二、组件开发
1.组合式API(Composition API)
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';// Props 类型定义
interface Props {title: string;initialCount?: number;
}
const props = withDefaults(defineProps<Props>(), {initialCount: 0
});// 响应式数据
const count = ref(props.initialCount);
const doubleCount = computed(() => count.value * 2);// 事件触发
const emit = defineEmits<{(e: 'count-change', newCount: number): void;
}>();// 方法
const increment = () => {count.value++;emit('count-change', count.value);
};// 生命周期
onMounted(() => {console.log('Component mounted');
});
</script><template><div><h2>{{ title }}</h2><p>Count: {{ count }}, Double: {{ doubleCount }}</p><button @click="increment">+1</button></div>
</template>
2.选项式API(Options API)
<script lang="ts">
import { defineComponent } from 'vue';interface State {message: string;count: number;
}export default defineComponent({props: {title: {type: String,required: true}},data(): State {return {message: 'Hello Vue!',count: 0};},computed: {reversedMessage(): string {return this.message.split('').reverse().join('');}},methods: {increment() {this.count++;}}
});
</script>
三、Vue 2 + TypeScript
Vue 2 需通过 vue-class-component 或 vue-property-decorator 增强类型支持。
1. 安装依赖
npm install vue-class-component vue-property-decorator --save
2. 类组件(Vue Class Component)
<template><div><p>{{ message }}</p><button @click="increment">Count: {{ count }}</button></div>
</template><script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';@Component
export default class MyComponent extends Vue {// Props@Prop({ type: String, required: true }) readonly title!: string;@Prop({ default: 0 }) readonly initialCount!: number;// 数据private count: number = this.initialCount;// 计算属性get message(): string {return `${this.title}: ${this.count}`;}// 方法increment() {this.count++;}
}
</script>
3.Vuex类型安全
// store/modules/user.ts
import { Module } from 'vuex';interface UserState {name: string;age: number;
}const userModule: Module<UserState, RootState> = {namespaced: true,state: () => ({name: 'Alice',age: 30}),mutations: {SET_NAME(state, payload: string) {state.name = payload;}},actions: {updateName({ commit }, newName: string) {commit('SET_NAME', newName);}},getters: {fullInfo: (state) => `${state.name} (${state.age})`}
};
四、状态管理(Pinia + TypeScript)
Pinia 是 Vue 官方推荐的状态管理库,天然支持 TypeScript。
1. 定义 Store
// stores/counter.ts
import { defineStore } from 'pinia';interface CounterState {count: number;lastUpdated?: Date;
}export const useCounterStore = defineStore('counter', {state: (): CounterState => ({count: 0,lastUpdated: undefined}),actions: {increment() {this.count++;this.lastUpdated = new Date();}},getters: {doubleCount: (state) => state.count * 2}
});
2. 在组件中使用
<script setup lang="ts">
import { useCounterStore } from '@/stores/counter';const counterStore = useCounterStore();// 直接修改状态
counterStore.count++;// 通过 action 修改
counterStore.increment();// 使用 getter
console.log(counterStore.doubleCount);
</script>
五、高级类型操作
1.全局属性扩展
// src/types/global.d.ts
import { ComponentCustomProperties } from 'vue';declare module '@vue/runtime-core' {interface ComponentCustomProperties {$formatDate: (date: Date) => string; // 全局方法$api: typeof import('./api').default; // 全局 API 实例}
}// main.ts 中注入
app.config.globalProperties.$formatDate = (date: Date) => date.toLocaleString();
2. 为无类型库添加声明
创建 src/types/shims.d.ts:
declare module 'untyped-vue-library' {export function doSomething(config: any): void;
}
3.泛型组件
<script setup lang="ts" generic="T">
import { ref } from 'vue';interface GenericListProps<T> {items: T[];keyField: keyof T;
}const props = defineProps<GenericListProps<T>>();const selectedItem = ref<T>();
</script><template><ul><li v-for="item in items" :key="item[keyField]"@click="selectedItem = item">{{ item }}</li></ul>
</template>
4.使用 Vue Router
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';const routes: Array<RouteRecordRaw> = [{path: '/',name: 'Home',component: () => import('@/views/Home.vue')}
];const router = createRouter({history: createWebHistory(),routes
});export default router;
六、最佳实践
严格类型检查:
在 tsconfig.json 中启用严格模式
{"compilerOptions": {"strict": true,"noImplicitAny": false // 可逐步开启}
}
类型导入:
优先使用 TypeScript 类型导入:
import type { Router } from 'vue-router';
避免 any:
尽量使用精确类型,仅在紧急情况下使用 any。
性能优化
1.类型安全的异步组件
// 显式定义加载的组件类型
const AsyncModal = defineAsyncComponent({loader: () => import('./Modal.vue'),loadingComponent: LoadingSpinner,delay: 200
});
2.避免不必要的类型断言
// Bad: 过度使用 as
const data = response.data as User[];// Good: 使用类型守卫
function isUserArray(data: any): data is User[] {return Array.isArray(data) && data.every(item => 'id' in item);
}
if (isUserArray(response.data)) {// 安全使用 response.data
}
七、常见问题
Q1:模板中的类型检查
安装Volar VS Code插件
禁用Vetur(避免冲突)
Q2:处理$refs类型
// main.ts
import { createApp } from 'vue';declare module '@vue/runtime-core' {interface ComponentCustomProperties {$myGlobal: string;}
}const app = createApp(App);
app.config.globalProperties.$myGlobal = 'hello';
Q3:动态路由类型(Vue Router)
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';declare module 'vue-router' {interface RouteMeta {requiresAuth?: boolean;}
}const routes: RouteRecordRaw[] = [{path: '/user/:id',component: () => import('@/views/User.vue'),props: (route) => ({ id: Number(route.params.id) }) // 类型转换}
];
Q3: 如何为全局属性添加类型?
在 Vue 3 中:
// main.ts
import { createApp } from 'vue';declare module '@vue/runtime-core' {interface ComponentCustomProperties {$myGlobal: string;}
}const app = createApp(App);
app.config.globalProperties.$myGlobal = 'hello';
Q2: 如何处理模板中的类型检查?
Vue 3 的 Volar 插件(替代 Vetur)提供模板内类型检查,需在 VS Code 中安装。
八、学习资源
-
Vue 3 + TypeScript 官方指南
-
Pinia 官方文档
-
Vue 3 TypeScript 示例项目
本文有待更新,暂时不为最终版本
码字不易,各位大佬点点赞
相关文章:
【TypeScript】ts在vue中的使用
目录 一、Vue 3 TypeScript 1. 项目创建与配置 项目创建 关键配置文件 2.完整项目结构示例 3. 组件 Props 类型定义 4. 响应式数据与 Ref 5. Composition 函数复用 二、组件开发 1.组合式API(Composition API) 2.选项式API(Options…...
2025前端框架最新组件解析与实战技巧:Vue与React的革新之路
作者:飞天大河豚 引言 2025年的前端开发领域,Vue与React依然是开发者最青睐的框架。随着Vue 3的全面普及和React 18的持续优化,两大框架在组件化开发、性能优化、工程化支持等方面均有显著突破。本文将从最新组件特性、使用场景和编码技巧三…...
Elasticsearch 的分布式架构原理:通俗易懂版
Elasticsearch 的分布式架构原理:通俗易懂版 Lucene 和 Elasticsearch 的前世今生 Lucene 是一个功能强大的搜索库,提供了高效的全文检索能力。然而,直接基于 Lucene 开发非常复杂,即使是简单的功能也需要编写大量的 Java 代码&…...
【DeepSeek】【GPT-Academic】:DeepSeek集成到GPT-Academic(官方+第三方)
目录 1 官方deepseek 1.1 拉取学术GPT项目 1.2 安装依赖 1.3 修改配置文件中的DEEPSEEK_API_KEY 2 第三方API 2.1 修改DEEPSEEK_API_KEY 2.2 修改CUSTOM_API_KEY_PATTERM 2.3 地址重定向 2.4 修改模型参数 2.5 成功调用 2.6 尝试添加一个deepseek-r1参数 3 使用千帆…...
2.部署kafka:9092
官方文档:http://kafka.apache.org/documentation.html (虽然kafka中集成了zookeeper,但还是建议使用独立的zk集群) Kafka3台集群搭建环境: 操作系统: centos7 防火墙:全关 3台zookeeper集群内的机器,1台logstash 软件版本: …...
学习路之PHP --TP6异步执行功能 (无需安装任何框架)
学习路之PHP --异步执行功能 (无需安装任何框架) 简介一、工具类二、调用三、异步任务的操作四、效果: 简介 执行异步任务是一种很常见的需求,如批量发邮箱,短信等等执行耗时任务时,需要程序异步执行&…...
Uniapp 小程序复制、粘贴功能实现
在开发 Uniapp 小程序的过程中,复制和粘贴功能是非常实用且常见的交互需求。今天,我就来和大家详细分享如何在 Uniapp 中实现这两个功能。 复制功能:uni.setClipboardData方法 goResult() {uni.setClipboardData({data: this.copyContent, /…...
seacmsv9注入管理员账号密码+orderby+limit
一、seacmsv9 SQL注入漏洞 查看源码 <?php session_start(); require_once("include/common.php"); //前置跳转start $cs$_SERVER["REQUEST_URI"]; if($GLOBALS[cfg_mskin]3 AND $GLOBALS[isMobile]1){header("location:$cfg_mhost$cs");}…...
多通道数据采集和信号生成的模块化仪器如何重构飞机电子可靠性测试体系?
飞机的核心电子系统包括发电与配电系统,飞机内部所有设备和系统之间的内部数据通信系统,以及用于外部通信的射频设备。其他所有航空电子元件都依赖这些关键总线进行电力传输或数据通信。在本文中,我们将了解模块化仪器(无论是PCIe…...
天润融通分析DeepSeek如何一键完成从PR接入,到真正的业务接入
DeepSeek出圈之后,市场上很快掀起了一波DeepSeek接入潮。 在客户服务领域,许多企业见识到DeepSeek的超强能力后,也迅速接入DeepSeek并获得了不错的效果。 比如在客户接待服务场景,有企业将DeepSeek应用到智能问答助手࿰…...
免费PDF工具
Smallpdf.com - A Free Solution to all your PDF Problems Smallpdf - the platform that makes it super easy to convert and edit all your PDF files. Solving all your PDF problems in one place - and yes, free. https://smallpdf.com/#rappSmallpdf.com-解决您所有PD…...
PyTorch 源码学习:GPU 内存管理之它山之石——TensorFlow BFC 算法
TensorFlow 和 PyTorch 都是常用的深度学习框架,各自有一套独特但又相似的 GPU 内存管理机制(BFC 算法)。它山之石可以攻玉。了解 TensorFlow 的 BFC 算法有助于学习 PyTorch 管理 GPU 内存的精妙之处。本文重点关注 TensorFlow BFC 算法的核…...
【学写LibreCAD】1 LibreCAD主程序
一、源码 头文件: #ifndef MAIN_H #define MAIN_H#include<QStringList>#define STR(x) #x #define XSTR(x) STR(x)/*** brief handleArgs* param argc cli argument counter from main()* param argv cli arguments from main()* param argClean a list…...
Android Studio超级详细讲解下载、安装配置教程(建议收藏)
博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有…...
CDN与群联云防护的技术差异在哪?
CDN(内容分发网络)与群联云防护是两种常用于提升网站性能和安全的解决方案,但两者的核心目标和技术实现存在显著差异。本文将从防御机制、技术架构、适用场景和代码实现等方面详细对比两者的区别,并提供可直接运行的代码示例。 一…...
故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断
故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断 目录 故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断分类效果基本介绍模型描述DBO-BP-Bagging蜣螂算法优化多特征分类预测一、引言1.1、研究背景和意义1.2、研究现状1.3、研究目的与方法 二…...
Linux-SaltStack配置
文章目录 SaltStack配置 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2025年02月24日20点51分 SaltStack配置 SaltStack 中既支持SSH协议也支持我们的一个客户端 #获取公钥(…...
内网渗透测试-Vulnerable Docker靶场
靶场来源: Vulnerable Docker: 1 ~ VulnHub 描述:Down By The Docker 有没有想过在容器中玩 docker 错误配置、权限提升等? 下载此 VM,拿出您的渗透测试帽并开始使用 我们有 2 种模式: - HARD:这需要您将 d…...
云计算如何解决延迟问题?
在云计算中,延迟(latency)指的是从请求发出到收到响应之间的时间间隔。延迟过高可能会严重影响用户体验,特别是在需要实时响应的应用中,如在线游戏、视频流、金融交易等。云计算服务如何解决延迟问题,通常依…...
飞书webhook监控业务系统端口
钉钉告警没有额度了,替代方案使用企业微信或者是飞书,以下脚本是飞书为例 监控ping也就是活动主机 #!/bin/bash # IP Ping 监控脚本 date$(date "%Y-%m-%d %H:%M:%S") # 根据实际情况修改飞书 Webhook 地址 webhook"https://open.feish…...
保姆级教程:用Mission Planner分析Pixhawk飞行日志,快速定位炸机元凶
无人机飞行日志分析实战:从炸机残骸中还原真相 每次炸机后,面对飞控里那一堆密密麻麻的日志文件,就像拿到一份没有翻译的古代卷轴——数据都在那里,却读不懂它讲述的故事。作为一位经历过数十次炸机的老飞手,我想分享一…...
Audio Pixel Studio开源实践:基于app.py二次开发添加情感标签合成功能
Audio Pixel Studio开源实践:基于app.py二次开发添加情感标签合成功能 1. 项目背景与核心价值 Audio Pixel Studio作为一款轻量级音频处理工具,已经为开发者提供了语音合成和人声分离两大核心功能。但在实际应用中,我们发现语音合成的情感表…...
Redis 缓存雪崩的防护策略
Redis缓存雪崩防护策略解析 在高并发系统中,Redis作为核心缓存组件,一旦发生缓存雪崩,可能导致数据库瞬时压力激增甚至服务瘫痪。缓存雪崩通常指大量缓存数据同时过期或Redis宕机,引发请求直接穿透到数据库。如何有效防护这一问题…...
AI Agent Harness Engineering 的商业化困局:按 Token 计费与按结果付费的博弈
从零破解AI Agent Harness商业化生死门:Token计费惯性与结果付费终局的双向奔赴与博弈深度 副标题:从代码层面解构Agent开发成本模型,从商业落地剖析价值定价逻辑,构建兼顾技术可行性、客户信任度与ROI的可持续盈利体系 第一部分:引言与基础 (Introduction & Foundati…...
为什么92%的AI语音项目在2026年前将被淘汰?奇点大会首席科学家亲授原生语音迁移倒计时路线图
第一章:AI语音项目淘汰潮的底层归因与奇点临界点判定 2026奇点智能技术大会(https://ml-summit.org) 近年来,全球范围内超63%的中早期AI语音项目在V1.2–V2.0迭代阶段主动终止或被并购清退。这一现象并非源于技术失效,而是由三重结构性张力共…...
Transformer面试通关指南:从Attention到KV Cache的深度剖析
1. Transformer核心原理:从Attention机制说起 我第一次接触Transformer时,被它的Attention机制深深吸引。想象一下,你在阅读这篇文章时,眼睛会不自觉地聚焦在关键词上,这就是人类注意力的自然体现。Transformer的Self-…...
AI原生A/B测试框架设计实战(从LLM服务灰度到多模态策略归因):Meta/Netflix/阿里内部验证的7层隔离架构首次公开
第一章:AI原生A/B测试框架的核心范式演进 2026奇点智能技术大会(https://ml-summit.org) 传统A/B测试以静态页面与确定性分流为基石,而AI原生框架将实验设计、流量分配、指标归因与模型反馈深度耦合,形成闭环自适应系统。其核心范式从“假设…...
统计学核心分布解析:从理论到Python实战
1. 统计学分布:数据世界的语言密码 第一次接触统计学分布时,我盯着那条完美的钟形曲线发呆了半小时。当时怎么也想不明白,为什么自然界中那么多现象都会乖乖服从这个规律。直到后来用Python模拟了上万次抛硬币实验,看着直方图逐渐…...
手把手教你定制Ubuntu安装镜像:集成autoinstall配置,打造开箱即用的系统U盘
深度定制Ubuntu安装镜像:从autoinstall集成到U盘封装实战指南 当我们需要为实验室批量部署开发环境、为企业客户预装专用系统,或是为嵌入式设备打造专属镜像时,传统的手动安装方式显然效率低下。本文将带您深入探索如何将Ubuntu的autoinstall…...
避坑指南:PaviaU数据集预处理中,你的标准化和样本切片方法可能都错了
高光谱数据处理进阶:PaviaU数据集预处理的三大优化策略 1. 标准化方法的深度选择:全局与逐波段的博弈 高光谱数据的标准化处理远非简单调用StandardScaler()就能解决。PaviaU数据集包含103个波段,每个波段的光谱响应特性差异显著。全局标准化…...
