Vue2 使用 typescript 教程

Vue2 + TypeScript 核心是用装饰器(class 语法)Vue.extend 写组件,配合vue-class-componentvue-property-decorator提供类型与装饰器支持Vue.js。下面从环境搭建→组件写法→Props / 生命周期→Vuex / 路由→常见坑,给你一套完整可落地教程。

一、环境搭建

1:Vue CLI 直接创建
bash 复制代码
# 安装/更新 CLI
npm install -g @vue/cli

# 创建项目
vue create vue2-ts-demo
# 选择:Manually select features → 勾选 TypeScript → 选择 Vue 2.x
# 后续可默认,创建完成后进入目录
cd vue2-ts-demo
npm run serve

生成关键文件:

  • tsconfig.json:TS 编译配置
  • src/shims-vue.d.ts:让 TS 识别 .vue 文件
  • src/shims-tsx.d.ts:支持 TSX 语法
2:现有 Vue2 项目接入 TS

安装依赖

bash 复制代码
npm install typescript ts-loader --save-dev
npm install vue-class-component vue-property-decorator --save

配置 tsconfig.json(根目录)

bash 复制代码
{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "strict": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

配置 vue.config.js(支持 TS 加载)

bash 复制代码
module.exports = {
  chainWebpack: config => {
    config.resolve.extensions.add('.ts').add('.tsx')
    config.module
      .rule('ts')
      .test(/\.(ts|tsx)$/)
      .use('ts-loader')
      .loader('ts-loader')
      .options({ appendTsSuffixTo: [/\.vue$/] })
  }
}

类型声明文件

bash 复制代码
// src/shims-vue.d.ts
declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}

二、组件写法(Class + 装饰器(@Component/@Prop/@Computed))

1. 基础组件(@Component
bash 复制代码
<!-- src/components/Hello.ts -->
<template>
  <div>
    <h1>{{ msg }}</h1>
    <button @click="sayHello">点击</button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Hello extends Vue {
  // 数据:直接声明类型+初始值
  msg: string = 'Hello Vue2 + TS'

  // 方法:直接写,自动绑定 this
  sayHello(): void {
    alert(this.msg)
  }
}
</script>
  1. Props 类型(@Prop
bash 复制代码
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import { Prop } from 'vue-property-decorator'

@Component
export default class User extends Vue {
  // 基础类型
  @Prop() id: number
  // 带默认值
  @Prop({ default: '匿名' }) name: string
  // 必传+校验
  @Prop({ type: String, required: true }) gender!: string
}
</script>
  1. 计算属性(@Computed
bash 复制代码
import { Computed } from 'vue-property-decorator'

@Component
export default class User extends Vue {
  firstName: string = '张'
  lastName: string = '三'

  @Computed()
  get fullName(): string {
    return this.firstName + this.lastName
  }
}
4. 生命周期(直接写方法)
bash 复制代码
@Component
export default class Hello extends Vue {
  created(): void {
    console.log('组件创建')
  }
  mounted(): void {
    console.log('组件挂载')
  }
}

三、Vue.extend 写法(无装饰器)

适合不想用装饰器的场景:

bash 复制代码
import Vue from 'vue'

export default Vue.extend({
  data() {
    return { msg: 'Hello' as string }
  },
  methods: {
    greet(name: string): string {
      return `Hi ${name}`
    }
  }
})

四、Vuex 与 TypeScript

1. 定义 State
bash 复制代码
// src/store/index.ts
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

interface State {
  count: number
  user: { name: string; age: number }
}

export default new Vuex.Store<State>({
  state: {
    count: 0,
    user: { name: '李四', age: 20 }
  },
  mutations: {
    ADD_COUNT(state) {
      state.count++
    }
  }
})
  1. 组件中使用 Vuex
bash 复制代码
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import { mapState, mapMutations } from 'vuex'

@Component({
  computed: { ...mapState(['count', 'user']) },
  methods: { ...mapMutations(['ADD_COUNT']) }
})
export default class Counter extends Vue {
  // 直接使用 this.count / this.user
}
</script>

五、路由与 TypeScript

bash 复制代码
// src/router/index.ts
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      meta: { title: '首页' } // 可扩展类型
    }
  ]
})

六、常见问题与避坑

  1. this 隐式 anytsconfig.json 开启 strict: trueVue.js
  2. 找不到 .vue 模块 :检查 shims-vue.d.ts 是否正确声明
  3. 装饰器报错 :确保 experimentalDecorators: true
  4. Props 类型不生效 :使用 @Prop 装饰器而非原生写法Vue.js
相关推荐
CharlesYu019 小时前
前端性能优化的第一性原理,是不断缩短“用户发起意图 → 获得可用结果”之间的时间
前端
Bs_MoneyMagnet9 小时前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
平头哥技术团队10 小时前
Day 21 _ 页内锚点_给每段起个 id,目录写 href=_#id_,点一下页面就滚到那一段
前端·html·html5
子兮曰11 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
人民广场吃泡面11 小时前
什么是AI Agent?它又能给前端带来哪些效率提升?
前端·人工智能
中科三方11 小时前
两家域名注册商资质被ICANN终止:企业域名资产安全再受关注
前端·网络·安全·域名
bug总结12 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app
华无丽言12 小时前
如何在宜搭中实现获取子表中的字段值赋值到父表中?
前端·javascript·低代码
IT_陈寒13 小时前
Vue的computed属性竟然坑了我一把
前端·人工智能·后端
威斯软科的老司机13 小时前
通俗讲解 CNN 图像识别、向量 Embedding、Softmax 概率计算这三块的简化原理
前端·人工智能·ui·数字孪生