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
相关推荐
Pedantic8 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘9 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆9 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师10 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆10 小时前
VSCode自动格式化三要素
前端
爱勇宝11 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen11 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user205855615181313 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode13 小时前
Redis 在生产项目的使用
前端·后端