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
相关推荐
随风一样自由9 小时前
【前端独角兽】刚进入前端领域的前端开发用jQuery还是Vue3?
前端·javascript·vue3·jquery
IMPYLH9 小时前
HTML 的 <data> 元素
前端·html
YHHLAI10 小时前
[特殊字符] 面试中的 Promise —— 从入门到精通
前端·javascript·面试
leoZ23111 小时前
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
vue.js·spring boot·架构
kyriewen12 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H12 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
陆枫Larry13 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端
退休倒计时14 小时前
【每日一题】LeetCode 437. 路径总和 III TypeScript
算法·leetcode·typescript
环境栈笔记15 小时前
多账号浏览器选型检查清单:Profile、权限、Session 和任务日志怎么评估
前端·人工智能·后端·自动化
前端炒粉15 小时前
手写promise
java·前端·javascript