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
相关推荐
光影少年1 小时前
Redux Toolkit 用法、解决原生Redux 冗余问题
开发语言·前端·javascript·react.js·中间件·前端框架·ecmascript
云水一下1 小时前
JavaScript 从零基础到精通系列:DOM 操作与事件驱动编程
前端·javascript
abigale031 小时前
LangChain 多轮对话记忆:基于 session_id 实现多会话隔离
typescript·langchain·uuid·session_id
GISHUB1 小时前
Express + TypeScript + ESM 后端服务搭建教程
javascript·typescript·express
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_32:(Web字体深度解析与实践指南)
前端·javascript·css·ui·html
砍材农夫2 小时前
物联网 基于netty核心实战-安全tls
java·开发语言·前端·物联网·安全
SEO_juper2 小时前
JavaScript 渲染:AI 智能体无法读取,直接影响收录
开发语言·前端·javascript·aigc·seo·跨境电商·geo
i220818 Faiz Ul2 小时前
在线预约导游|基于SSM+vue的在线预约导游系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·在线预约导游系统