news 2026/3/27 17:06:56

Vue3中JS与TS写法全对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3中JS与TS写法全对比

文章目录

      • 一、基础环境配置差异
        • 1.1 项目创建对比
        • 1.2 TS专属配置:tsconfig.json核心参数
      • 二、组件定义核心语法差异
        • 2.1 <script setup>语法对比
          • JavaScript写法(简洁无类型)
          • TypeScript写法(类型明确)
        • 2.2 选项式API对比(传统风格)
          • JavaScript写法
          • TypeScript写法(需defineComponent)
      • 三、响应式API写法差异
        • 3.1 ref API对比(基础类型/对象类型)
        • 3.2 reactive API对比(复杂对象)
          • JavaScript写法
          • TypeScript写法
        • 3.3 computed API对比(计算属性)
          • JavaScript写法
          • TypeScript写法
      • 四、Props/Emits类型约束差异
        • 4.1 Props定义对比
          • JavaScript写法(运行时校验)
          • TypeScript写法(编译时校验)
        • 4.2 Emits定义对比
          • JavaScript写法(仅声明事件名)
          • TypeScript写法(事件参数类型约束)
      • 五、生命周期钩子用法差异
        • 5.1 基础生命周期对比
          • JavaScript写法
          • TypeScript写法
        • 5.2 自定义Hook中的生命周期
          • JavaScript写法(useTimer.js)
          • TypeScript写法(useTimer.ts)
      • 六、Vue Router集成差异
        • 6.1 路由配置对比
          • JavaScript写法(router/index.js)
          • TypeScript写法(router/index.ts)
        • 6.2 组件内路由使用对比
          • JavaScript写法
          • TypeScript写法(带类型推导)
      • 七、Pinia状态管理差异
        • 7.1 Store定义对比
          • JavaScript写法(useUserStore.js)
          • TypeScript写法(useUserStore.ts)
        • 7.2 Store使用对比
          • JavaScript写法
          • TypeScript写法
      • 八、自定义Hook封装差异
        • 8.1 数据请求Hook对比(useRequest)
          • JavaScript写法(useRequest.js)
          • TypeScript写法(useRequest.ts)
      • 九、异步请求与事件处理差异
        • 9.1 异步请求对比(Axios)
          • JavaScript写法
          • TypeScript写法
        • 9.2 DOM事件处理对比
          • JavaScript写法
          • TypeScript写法
      • 十、TS专属类型工具与语法
        • 10.1 基础类型工具
        • 10.2 Vue3开发高频TS语法
      • 十一、核心差异总结表

一、基础环境配置差异

Vue3项目中JS与TS的环境差异体现在项目创建、配置文件、依赖包三个层面,TS需要额外的类型配置来实现语法校验。

1.1 项目创建对比
配置项JavaScript写法TypeScript写法
创建命令npm create vue@latest→ 取消勾选“TypeScript”npm create vue@latest→ 勾选“TypeScript”
核心文件组件后缀:.vue;配置文件:vite.config.js组件后缀:.vue(内部指定lang="ts");配置文件:vite.config.tstsconfig.json
依赖包仅需Vue核心依赖:vue@vitejs/plugin-vue额外依赖:typescript@vue/tsconfigvue-tsc(类型检查)
1.2 TS专属配置:tsconfig.json核心参数

TS项目必须通过tsconfig.json指定类型规则,核心配置如下(基于Vue官方推荐模板):

{"compilerOptions":{"target":"ES2020",// 编译目标ES版本"strict":true,// 开启严格类型校验(核心)"module":"ESNext","moduleResolution":"Node","isolatedModules":true,// 适配Vite单文件转译"jsx":"preserve",// 支持TSX"sourceMap":true,"paths":{"@/*":["./src/*"]},// 路径别名(与Vite同步)"lib":["ES2020","DOM"],// 引入浏览器环境类型"skipLibCheck":true},"include":["src/**/*.ts","src/**/*.vue"],// 类型检查范围"references":[{"path":"./tsconfig.node.json"}]}

关键说明:strict: true是TS类型安全的核心,会强制校验this指向、空值判断等,避免隐式any类型。

二、组件定义核心语法差异

Vue3组件定义分为<script setup>(推荐)和选项式API两种风格,TS与JS的差异集中在类型声明语法约束上,模板部分完全一致。

2.1 <script setup>语法对比
JavaScript写法(简洁无类型)
<template><divclass="user-card"><h3>{{user.name}}</h3><button @click="handleEdit">编辑</button></div></template><script setup>// 无类型约束,直接声明变量constuser={name:'张三',age:24};// 函数参数与返回值无类型consthandleEdit=(newName)=>{user.name=newName||user.name;};// 导入组件无需类型处理importAvatarfrom'./Avatar.vue';</script>
TypeScript写法(类型明确)
<template><divclass="user-card"><h3>{{user.name}}</h3><button @click="handleEdit('李四')">编辑</button></div></template><script setup lang="ts">// 1. 接口定义复杂类型(TS专属)interfaceUser{name:string;age:number;gender?:string;// 可选属性}// 2. 变量显式类型约束constuser:User={name:'张三',age:24};// 3. 函数参数与返回值类型声明consthandleEdit=(newName:string):void=>{user.name=newName;};// 4. 组件类型获取(TS专属)importAvatarfrom'./Avatar.vue';importtype{ComponentPublicInstance}from'vue';typeAvatarInstance=ComponentPublicInstance&lt;typeofAvatar&gt;;// 组件实例类型&lt;/script&gt;
2.2 选项式API对比(传统风格)
JavaScript写法
<script>exportdefault{name:'UserCard',data(){return{user:{name:'张三',age:24}};},methods:{handleEdit(newName){this.user.name=newName;}}};</script>
TypeScript写法(需defineComponent)
<script lang="ts">import{defineComponent}from'vue';interfaceUser{name:string;age:number;}exportdefaultdefineComponent({name:'UserCard',// TS自动推导data返回值类型data(){return{user:{name:'张三',age:24}asUser// 类型断言};},methods:{// 方法参数与返回值类型约束handleEdit(newName:string):void{this.user.name=newName;// this指向被TS正确推导}}});</script>

关键差异:TS的defineComponent函数是类型推断的核心,能自动解析组件选项中的this类型,避免JS中this隐式为any的问题。

三、响应式API写法差异

Vue3的响应式API(ref、reactive、computed)是开发核心,TS通过泛型接口实现类型约束,而JS仅依赖运行时校验。

3.1 ref API对比(基础类型/对象类型)
场景JavaScript写法TypeScript写法
基础类型(数字/字符串)`import { ref } from ‘vue’;
const count = ref(0);
count.value = 10; // 直接赋值,无类型校验``import { ref } from ‘vue’;
// 方式1:自动推导类型(Ref)
const count = ref(0);
// 方式2:显式泛型声明(推荐)
const name = ref(‘张三’);
// 方式3:联合类型
const status = ref<‘loading’‘success’‘error’>(‘loading’);
count.value = ‘10’; // TS编译报错(类型不匹配)`
对象类型`import { ref } from ‘vue’;
const user = ref({
name: ‘张三’,
age: 24
});
user.value.age = ‘24’; // 运行时错误,JS无法拦截``import { ref } from ‘vue’;
// 接口约束对象结构
interface User {
name: string;
age: number;
}
// 泛型指定类型
const user = ref({
name: ‘张三’,
age: 24
});
user.value.age = ‘24’; // TS编译报错(数字≠字符串)
user.value.gender = ‘男’; // TS编译报错(无该属性)`
3.2 reactive API对比(复杂对象)

核心差异:reactive返回的是响应式代理对象,TS必须通过泛型指定类型,不能用类型注解(会导致类型不匹配)。

JavaScript写法
import{reactive}from'vue';// 无类型约束,属性可随意添加constform=reactive({username:'',password:''});form.remember=true;// 随意添加属性,JS不拦截
TypeScript写法
import{reactive,readonly}from'vue';// 1. 接口定义表单结构interfaceLoginForm{username:string;password:string;remember?:boolean;// 可选属性}// 2. 泛型指定类型(必须用泛型,不能用类型注解)constform=reactive<LoginForm>({username:'',password:''});// 3. 只读响应式(TS+Vue专属)constreadonlyForm=readonly(form);readonlyForm.username='test';// TS编译报错(只读)// 错误写法示例constwrongForm:LoginForm=reactive({});// 报错:响应式代理无法赋值给原始类型
3.3 computed API对比(计算属性)
JavaScript写法
import{ref,computed}from'vue';constcount=ref(0);// 无返回值类型约束constdoubleCount=computed(()=>{returncount.value*2;});// 可写计算属性constfullName=computed({get(){return`${firstName.value}${lastName.value}`;},set(val){const[first,last]=val.split(' ');firstName.value=first;lastName.value=last;}});
TypeScript写法
import{ref,computed}from'vue';constcount=ref<number>(0);// 1. 自动推导返回类型(ComputedRef<number>)constdoubleCount=computed(()=>{returncount.value*2;});// 2. 显式声明返回类型constdoubleCount2=computed<number>(()=>{returncount.value*2;});// 3. 可写计算属性类型约束constfirstName=ref<string>('张');constlastName=ref<string>('三');constfullName=computed<string>({get():string{return`${firstName.value}${lastName.value}`;},set(val:string){const[first,last]=val.split(' ')||['',''];firstName.value=first;lastName.value=last;}});

四、Props/Emits类型约束差异

Props和Emits是组件通信的核心,JS仅支持运行时校验(如type: String),而TS能实现编译时类型校验,提前规避传参错误。

4.1 Props定义对比
JavaScript写法(运行时校验)
<script setup>import{defineProps}from'vue';// 仅指定类型和默认值,无编译时校验constprops=defineProps({id:{type:Number,required:true},name:{type:String,default:'匿名用户'},tags:{type:Array,default:()=>[]}});// 使用props时无类型提示console.log(props.id,props.name);</script>
TypeScript写法(编译时校验)
<script setup lang="ts">import{defineProps,withDefaults}from'vue';// 1. 接口定义Props结构(TS专属)interfaceProps{id:number;// 必传属性name?:string;// 可选属性tags:string[];// 数组类型user:{// 嵌套对象类型name:string;age:number;};}// 2. 基础类型约束(无默认值)constprops1=defineProps<Props>();// 3. 带默认值的Props(withDefaults)constprops=withDefaults(defineProps<Props>(),{name:'匿名用户',tags:()=>['default'],// 嵌套对象默认值需返回函数user:()=>({name:'默认用户',age:18})});// 使用props时有完整类型提示console.log(props.id);// 鼠标悬浮显示number类型props.id=10;// TS编译报错(props只读)</script>
4.2 Emits定义对比
JavaScript写法(仅声明事件名)
<script setup>import{defineEmits}from'vue';// 仅声明事件名,无参数类型约束constemit=defineEmits(['change','submit']);// 触发事件时参数随意传递,JS不拦截consthandleSubmit=()=>{emit('submit',{username:'张三',password:123456});// 密码应为字符串};</script>
TypeScript写法(事件参数类型约束)
<script setup lang="ts">import{defineEmits}from'vue';// 方式1:类型字面量(推荐)constemit=defineEmits<{// 事件名:(参数类型) => 返回值(通常为void)change:(id:number)=>void;submit:(form:{username:string;password:string})=>void;}>();// 方式2:接口约束interfaceEmits{(e:'change',id:number):void;(e:'submit',form:{username:string;password:string}):void;}constemit2=defineEmits<Emits>();// 触发事件时参数类型不匹配则报错consthandleSubmit=()=>{emit('submit',{username:'张三',password:'123456'});// 正确emit('submit',{username:'张三',password:123456});// TS编译报错};</script>

五、生命周期钩子用法差异

两者生命周期钩子的调用时机完全一致,差异仅体现在TS对参数类型DOM元素类型的约束上。

5.1 基础生命周期对比
JavaScript写法
import{onMounted,onUpdated,ref}from'vue';consttitle=ref('初始标题');onMounted(()=>{// 操作DOM无类型提示,可能出现null错误constel=document.getElementById('title');el.style.color='red';// 若el为null,运行时报错});onUpdated(()=>{console.log('组件更新',title.value);});
TypeScript写法
import{onMounted,onUpdated,ref}from'vue';consttitle=ref<string>('初始标题');onMounted(()=>{// 1. 类型断言(明确DOM元素类型)constel=document.getElementById('title')asHTMLDivElement;el.style.color='red';// 有完整CSS属性提示// 2. 类型守卫(避免null错误)constel2=document.getElementById('title');if(el2){// 自动缩小类型为HTMLDivElementel2.style.fontSize='16px';}});onUpdated(()=>{console.log('组件更新',title.value);// title类型明确为string});
5.2 自定义Hook中的生命周期
JavaScript写法(useTimer.js)
import{ref,onMounted,onUnmounted}from'vue';// 无参数类型和返回值类型约束exportconstuseTimer=(initialValue=0)=>{constcount=ref(initialValue);lettimer=null;onMounted(()=>{timer=setInterval(()=>{count.value++;},1000);});onUnmounted(()=>{clearInterval(timer);});return{count};};
TypeScript写法(useTimer.ts)
import{ref,onMounted,onUnmounted,typeRef}from'vue';// 1. 泛型约束入参类型,支持多种数字类型exportconstuseTimer=<Textendsnumber>(initialValue:T=0asT):{count:Ref<T>}=>{constcount=ref<T>(initialValue);// 2. 显式声明定时器类型lettimer:NodeJS.Timeout|null=null;onMounted(()=>{timer=setInterval(()=>{count.value=(count.value+1)asT;},1000);});onUnmounted(()=>{if(timer)clearInterval(timer);// 类型守卫});// 3. 明确返回值类型return{count};};

TS优势:通过泛型让Hook支持多类型入参,同时显式声明定时器类型,避免JS中timer隐式为any的问题。

六、Vue Router集成差异

Vue Router 4+对TS有深度支持,TS能通过类型推导实现路由参数、导航守卫的类型安全,而JS仅依赖手动校验。

6.1 路由配置对比
JavaScript写法(router/index.js)
import{createRouter,createWebHistory}from'vue-router';importHomefrom'../views/Home.vue';importUserfrom'../views/User.vue';// 无类型约束,路由参数全靠手动记忆constroutes=[{path:'/',name:'Home',component:Home},{path:'/user/:id',name:'User',component:User,props:true// 直接传递params参数}];constrouter=createRouter({history:createWebHistory(import.meta.env.BASE_URL),routes});exportdefaultrouter;
TypeScript写法(router/index.ts)
import{createRouter,createWebHistory,typeRouteRecordRaw}from'vue-router';importHomefrom'../views/Home.vue';importUserfrom'../views/User.vue';// 1. 类型约束路由配置(RouteRecordRaw)constroutes:RouteRecordRaw[]=[{path:'/',name:'Home',component:Home},{path:'/user/:id',name:'User',component:User,props:true}];constrouter=createRouter({history:createWebHistory(import.meta.env.BASE_URL),routes});// 2. 路由守卫类型约束(TS专属)router.beforeEach((to,from,next)=>{// to/from均为RouteLocationNormalized类型,有完整参数提示if(to.name==='User'&&!to.params.id){next('/');}else{next();}});exportdefaultrouter;// 3. 路由参数类型声明(全局类型增强)declaremodule'vue-router'{interfaceRouteParams{id?:string;// 声明/user/:id的id参数类型}}
6.2 组件内路由使用对比
JavaScript写法
<script setup>import{useRouter,useRoute}from'vue-router';constrouter=useRouter();constroute=useRoute();// 无参数类型提示,容易传错constgoUser=(id)=>{router.push({name:'User',params:{id}});};// 路由参数类型未知,需手动转换constuserId=route.params.id;// 可能为string或undefinedconstuserIdNum=Number(userId);// 手动转数字</script>
TypeScript写法(带类型推导)
<script setup lang="ts">import{useRouter,useRoute}from'vue-router';importtype{RouteLocationNamedRaw}from'vue-router';// 1. 路由实例类型明确constrouter=useRouter();constroute=useRoute();// 2. 路由跳转参数类型约束constgoUser=(id:number)=>{constto:RouteLocationNamedRaw={name:'User',params:{id:id.toString()}// 明确params类型为string};router.push(to);};// 3. 路由参数类型安全获取constuserId=route.params.id;// TS自动推导为string | undefinedif(userId){constuserIdNum=Number(userId);// 类型守卫后安全转换}// 4. 路由查询参数类型约束constpage=route.query.page?Number(route.query.page):1;</script>

进阶技巧:Vue Router 4.4+支持通过unplugin-vue-router插件自动生成路由类型,无需手动声明路由参数。

七、Pinia状态管理差异

Pinia作为Vue3官方状态管理库,原生支持TS,其与JS的差异体现在状态类型推导Action/Getter类型约束上。

7.1 Store定义对比
JavaScript写法(useUserStore.js)
import{defineStore}from'pinia';// 无类型约束,状态属性可随意修改exportconstuseUserStore=defineStore('user',{state:()=>({name:'张三',age:24,roles:[]}),getters:{// 无返回值类型约束fullName(){return`用户:${this.name}`;}},actions:{// 无参数类型约束setAge(age){this.age=age;// 若传入字符串,运行时出错},// 异步Action无返回值类型asyncfetchUser(){constres=awaitfetch('/api/user');constdata=awaitres.json();this.$patch(data);}}});
TypeScript写法(useUserStore.ts)
import{defineStore}from'pinia';// 1. 接口定义状态类型(TS专属)interfaceUserState{name:string;age:number;roles:string[];}// 2. 选项式Store(带类型约束)exportconstuseUserStore=defineStore('user',{// 显式声明state返回值类型state:():UserState=>({name:'张三',age:24,roles:[]}),getters:{// 3. Getter返回值类型约束fullName:(state):string=>{return`用户:${state.name}`;// state类型自动推导}},actions:{// 4. Action参数类型约束setAge(age:number):void{this.age=age;// 传入非数字则编译报错},// 5. 异步Action返回值类型(Promise)asyncfetchUser():Promise<UserState>{constres=awaitfetch('/api/user');constdata=awaitres.json()asUserState;// 类型断言this.$patch(data);returndata;}}});// 3. 组合式Store(更灵活的类型控制)exportconstuseCounterStore=defineStore('counter',()=>{constcount=ref<number>(0);// 显式类型constincrement=(step:number=1):void=>{count.value+=step;};return{count,increment};});
7.2 Store使用对比
JavaScript写法
<script setup>import{useUserStore}from'@/stores/useUserStore';constuserStore=useUserStore();// 无类型提示,容易调用错误方法userStore.setAge('25');// 运行时错误console.log(userStore.fullName);// 无返回值类型提示</script>
TypeScript写法
<script setup lang="ts">import{useUserStore}from'@/stores/useUserStore';constuserStore=useUserStore();// 1. 调用Action时有参数类型提示userStore.setAge(25);// 正确userStore.setAge('25');// TS编译报错// 2. 获取Getter时有明确类型constfullName:string=userStore.fullName;// 类型匹配// 3. 异步Action类型约束constfetchData=async()=>{constuserData=awaituserStore.fetchUser();// userData类型为UserState};</script>

关键优势:Pinia在TS环境下会自动推导Store实例的类型,无需手动声明,且支持通过接口严格约束状态结构。

八、自定义Hook封装差异

自定义Hook是Vue3组合式API的核心复用方式,TS通过泛型类型导出让Hook更通用、更安全。

8.1 数据请求Hook对比(useRequest)
JavaScript写法(useRequest.js)
import{ref}from'vue';// 无类型约束,返回值类型混乱exportconstuseRequest=(requestFn)=>{constdata=ref(null);constloading=ref(false);consterror=ref(null);constfetchData=async(...args)=>{loading.value=true;try{constres=awaitrequestFn(...args);data.value=res.data;returnres.data;}catch(err){error.value=err;throwerr;}finally{loading.value=false;}};return{data,loading,error,fetchData};};
TypeScript写法(useRequest.ts)
import{ref,typeRef}from'vue';// 1. 泛型定义响应数据类型(支持任意接口返回格式)exportconstuseRequest=<T,Pextendsany[]=[]>(requestFn:(...args:P)=>Promise<{data:T}>)=>{// 2. 状态类型明确constdata:Ref<T|null>=ref(null);constloading:Ref<boolean>=ref(false);consterror:Ref<Error|null>=ref(null);// 3. 函数参数与返回值类型约束constfetchData=async(...args:P):Promise<T>=>{loading.value=true;try{constres=awaitrequestFn(...args);data.value=res.data;returnres.data;}catch(err){error.value=errasError;// 类型断言throwerr;}finally{loading.value=false;}};// 4. 明确返回值类型return{data,loading,error,fetchData};};// 接口定义API返回类型(TS专属)interfaceUserData{id:number;name:string;}// 使用示例:指定泛型类型为UserDataconst{data,fetchData}=useRequest<UserData,[number]>((id)=>fetch(`/api/user/${id}`).then(res=>res.json()));

TS优势:通过泛型让Hook支持任意请求参数和响应类型,复用性更强,且能自动推导返回值类型。

九、异步请求与事件处理差异

异步请求和DOM事件处理是前端开发高频场景,TS通过类型约束避免回调函数参数类型错误。

9.1 异步请求对比(Axios)
JavaScript写法
importaxiosfrom'axios';// 无响应数据类型约束,需手动判断属性constfetchUser=async(id)=>{try{constres=awaitaxios.get(`/api/user/${id}`);// 无类型提示,可能访问不存在的属性console.log(res.data.user.name,res.data.user.age);returnres.data;}catch(err){console.error('请求失败',err);}};
TypeScript写法
importaxiosfrom'axios';// 1. 接口定义响应数据类型interfaceUserResponse{code:number;data:{user:{name:string;age:number;};};message:string;}// 2. 泛型指定响应类型constfetchUser=async(id:number):Promise<UserResponse['data']>=>{try{// 3. Axios泛型参数指定响应类型constres=awaitaxios.get<UserResponse>(`/api/user/${id}`);// 有完整属性提示,避免访问不存在的字段console.log(res.data.user.name,res.data.user.age);returnres.data;}catch(err){// 4. 错误类型处理if(axios.isAxiosError(err)){console.error('请求失败',err.response?.data.message);}else{console.error('未知错误',err);}throwerr;}};
9.2 DOM事件处理对比
JavaScript写法
<template><input type="text"@input="handleInput"/><button @click="handleClick">点击</button></template><script setup>consthandleInput=(e)=>{// 无事件对象类型提示,需手动记忆属性console.log('输入内容',e.target.value);};consthandleClick=(e)=>{// 可能误写属性名e.preventDefault();};</script>
TypeScript写法
<template><inputtype="text"@input="handleInput"/><button @click="handleClick">点击</button></template><script setup lang="ts">// 1. 明确事件对象类型consthandleInput=(e:Event)=>{// 2. 类型断言为HTMLInputElementconstinputEl=e.targetasHTMLInputElement;console.log('输入内容',inputEl.value);// 有value属性提示};// 3. 鼠标事件类型consthandleClick=(e:MouseEvent)=>{e.preventDefault();// 有完整方法提示};</script>

十、TS专属类型工具与语法

以下语法为TS专属,JS完全不支持,是TS类型安全的核心保障,需重点掌握。

10.1 基础类型工具
import{ref,reactive}from'vue';// 1. 接口(Interface):定义对象结构interfaceUser{name:string;age:number;gender?:string;// 可选属性readonlyid:number;// 只读属性}// 2. 类型别名(Type):定义任意类型typeStatus='loading'|'success'|'error';// 联合类型typeUserList=User[];// 数组类型typeNullable<T>=T|null;// 泛型类型别名// 3. 泛型(Generic):实现通用类型constcreateArray=<T>(length:number,value:T):T[]=>{returnArray(length).fill(value);};constnumberArray=createArray<number>(3,0);// [0,0,0]conststringArray=createArray<string>(3,'a');// ['a','a','a']// 4. 交叉类型(Intersection):合并多个类型typeAdmin=User&{role:'admin'};constadmin:Admin={id:1,name:'管理员',age:30,role:'admin'};// 5. 工具类型(Utility Types):Vue开发高频使用// Partial:将属性变为可选constupdateUser=(user:User,updates:Partial<User>)=>{return{...user,...updates};};updateUser(admin,{age:31});// 仅更新age属性// Pick:筛选属性typeUserName=Pick<User,'name'|'id'>;// 仅包含name和id// Omit:排除属性typeUserWithoutId=Omit<User,'id'>;// 排除id属性// Exclude:排除联合类型中的部分类型typeNonLoadingStatus=Exclude<Status,'loading'>;// 'success' | 'error'
10.2 Vue3开发高频TS语法
  • 类型断言const el = e.target as HTMLInputElement,明确变量类型;

  • 类型守卫if (typeof value === 'number'),缩小变量类型范围;

  • 空值合并const name = user.name ?? '匿名',处理null/undefined;

  • 可选链const age = user?.age,安全访问嵌套属性;

  • 类型导入import type { User } from './types',仅导入类型(不生成代码)。

十一、核心差异总结表

对比维度JavaScript写法特点TypeScript写法特点
类型约束无显式类型,依赖运行时校验编译时类型校验,支持接口、泛型
组件定义简洁无类型,this隐式为anylang="ts"defineComponent推导类型
响应式API直接使用,无类型约束ref/reactive需泛型,computed指定返回值类型
Props/Emits运行时校验(type: String接口约束Props,类型字面量约束Emits参数
路由集成无参数类型提示,手动转换
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/24 18:26:29

三《数据链路层》

目录 3.1有线局域网&#xff08;IEEE 802.3&#xff09; 3.1.1以太网数据帧格式 3.1.2MAC地址 3.1.3二层交换机 3.2无线局域网&#xff08;IEEE 802.11&#xff09; 3.2.1IEEE802.11数据帧的数据帧格式 3.2.2无线局域网终端联网的步骤 3.2.3无线局域网的类型 3.2.4无线…

作者头像 李华
网站建设 2026/3/25 2:32:34

ArcObjects SDK 10.8:从零开始的GIS开发实战指南

ArcObjects SDK 10.8&#xff1a;从零开始的GIS开发实战指南 【免费下载链接】arcobjects-sdk-community-samples This repo contains the source code samples (.Net c#, .Net vb, and C) that demonstrate the usage of the ArcObject SDK. 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/3/24 20:58:40

Windows Server 2016 中文版、英文版下载 (2025 年 12 月更新)

Windows Server 2016 中文版、英文版下载 (2025 年 12 月更新) Windows Server 2016 x64 Version 1607 (updated Dec 2025) 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2016/ 查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a…

作者头像 李华
网站建设 2026/3/16 17:05:47

pycharm下新建一个项目并加入svn

因为要计划要经常新建工程&#xff0c;不再是都放在一个工程里面搞应用实现&#xff0c;另外还要加入svn版本库管理&#xff0c;所以稍微整理了一下新建的过程&#xff0c;供参考。 1、python版本 C:\Users\yegang>python -V Python 3.11.02、安装django并升级pip C:\Users\…

作者头像 李华
网站建设 2026/3/24 8:14:52

用于电力系统瞬态稳定性评估的机器学习。 从数据挖掘和机器学习的角度来解决电力系统的稳定性

用于电力系统瞬态稳定性评估的机器学习。 从数据挖掘和机器学习的角度来解决电力系统的稳定性&#xff0c;该模型由去噪堆叠自编码器和投票集成分类器构建。 集成由来自支持向量机和随机森林的池化预测组成。 报告并讨论了分类器在电力系统测试用例中的应用结果。 TSA问题的ML应…

作者头像 李华
网站建设 2026/3/24 11:03:32

三小时前刚调通的新鲜案例还在冒热气。ZYNQ这玩意儿玩TCP传输,核心就三件事:怎么把PL数据塞进DDR、怎么让LWIP别偷懒、怎么让DMA别堵车。直接上干货

ZYNQ平台基于LwIP实现TCP数据通信&#xff0c;PL端产生数据传递到PS端的DDR3&#xff0c;再利用LwIP通过TCP传输到PC端。 实测数据吞吐量能到达到500Mbps左右&#xff0c;最高能到700M 长达一小时的视频&#xff0c;从硬件设计的注意事项&#xff0c;到软件设计的思路都包含了。…

作者头像 李华