vue2使用ts vue-class-component

news2024/12/29 8:56:43

目前,对于Vue3来说,TypeScript的支持已经相当成熟,但公司的老项目一直处于迭代和维护无法从v2重构成v3,并且重构的成本也是很大的一个问题,所以记录一下vue2如何去搭配TypeScript。

目录

一、脚手架创建项目

二、vue-property-decorator

(1)变量 

(2)方法

  (3) watch

(4)计算属性

(5)生命周期

   (6) 组件

(1)注册组件

  (2) 父传子

(3)子传父 

 (7)ref引用

三、vuex-class

(1)全局使用 

(2)模块化

四、mixin


一、脚手架创建项目

通过vue-cli进行安装

vue create v2ts

以下是脚手架的配置,仅供参考

二、vue-property-decorator

vue-property-decorator 是一个 Vue.js 的装饰器库,它提供了一些装饰器来让你在 Vue 组件中定义属性、计算属性、方法、事件等。使用这些装饰器可以让 Vue 组件的代码更加清晰简洁,同时也提高了代码的可读性和可维护性。

tip:引入Component是将类组件转换成Vue组件。

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component
export default class HomeView extends Vue {
 
}
</script>

(1)变量 

由于使用的class-component,所以定义变量也是比较简单,只需要把变量写在class里,使用private和public可以更好的区分私有还是共有。

<template>
  <div id="app">
    {{ a }}
    {{ b }}
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-property-decorator'
export default class HomeView extends Vue {
  private a = 1
  public b = 2
}
</script>

tip:注意 不要初始化不赋值或赋值为undefined,否则会识别不到这个变量,如果你只想定义这个变量也可以采取data函数的形式。

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component
export default class HomeView extends Vue {
  data () {
    return {
      d: undefined
    }
  }
}

(2)方法

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class HomeView extends Vue {
  private a = 1
  private add () {
    console.log(this.a)
    this.a++
  }
}
</script>

(3) watch

语法:

  @Watch('监听属性', { immediate, deep })
  private 方法名 (新值,旧值) {
    console.log(v)
  }

示例: 

<template>
  <div id="app">
    {{ obj.a }}
    <button @click="add">+1</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'

@Component
export default class HomeView extends Vue {
  private obj = { a: 1 };
  private add () {
    this.obj.a++
  }

  @Watch('obj', { immediate: true, deep: true })
  private updateA (v: { a: number }) {
    console.log(v)
  }
}
</script>

(4)计算属性

计算属性 在方法名前 加一个get就好了

<template>
  <div id="app">
    {{ obj.a }}
    <button @click="add">+1</button>
    {{ doubleA }}
  </div>
</template>  

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component
export default class HomeView extends Vue {
  private obj = { a: 1 };

  private add () {
    this.obj.a++
  }

  get doubleA () {
    return this.obj.a * 2
  }
}
</script>

(5)生命周期

和之前区别不大 使用对应的函数名称

<script lang="ts">
@Component
export default class HomeView extends Vue {
 
  created () {
    console.log(123)
  }

  mounted () {
    console.log(456)
  }
}
</script>

(6) 组件

(1)注册组件

<template>
  <div id="app">
    <Son />
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import Son from '@/components/Son.vue'

@Component({
  components: {
    Son
  }
})
</script>

(2) 父传子

<Son text="哈哈" />

子 

<template>
    <div>{{ text }}</div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'

@Component
export default class Son extends Vue {
    @Prop({ type: String, default: '' }) text!:string
}

</script>

(3)子传父 

<template>
    <div>
        <button @click="emit">子传父</button>
    </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component
export default class Son extends Vue {
    emit () {
      this.$emit('update', 123)
    }
}

</script>

<template>
  <div id="app">
    <Son @update="updateHandler"/>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import Son from '@/components/Son.vue'

@Component({
  components: {
    Son
  }
})
export default class HomeView extends Vue {
  updateHandler (val:number) {
    console.log(val, '接受了')
  }
}
</script>

也可以通过vue-property-decorator的形式 导出Emit 调用emit的方法即可

<template>
  <div class="hello">
    <button @click="send">传值</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Emit } from 'vue-property-decorator'

@Component
export default class HelloWorld extends Vue {
  @Emit()
  send ():number {
    return 20
  }
}
</script>

 (7)ref引用

<template>
  <div id="app">
    {{ a }}
    <Son ref="son" />
  </div>
</template>

<script lang="ts">
import Son from '@/components/Son.vue'
import { Component, Vue } from 'vue-property-decorator'

interface SonComponent extends Vue {
  logHello: ()=>void
}

@Component({
  components: { Son }
})
export default class App extends Vue {
  a = 1;

  mounted () {
    (this.$refs.son as SonComponent).logHello()
  }
}
</script>

三、vuex-class

为了更好的搭配vue-class-component 在使用vuex的时候可以安装 vuex-class 插件 帮助我们更好的使用装饰器开发

npm i vuex-class

(1)全局使用 

store.ts 

import Vue from 'vue'
import Vuex, { Commit } from 'vuex'

Vue.use(Vuex)

interface state {
  username: string
}

export default new Vuex.Store({
  state: {
    username: 'default'
  },
  getters: {
    getUserName (state: state) {
      return '姓名' + state.username
    }
  },
  mutations: {
    SET_USERNAME (state: state, val: string) {
      state.username = val
    }
  },
  actions: {
    async requestUserName (context: { commit: Commit }, id: number) {
      const users = [
        { id: 1, name: 'Ulrtraman' },
        { id: 2, name: 'Monsters' }
      ]
      return new Promise((resolve) => {
        setTimeout(() => {
          const username = users.find(it => it.id === id)?.name
          context.commit('SET_USERNAME', username)
          resolve(username)
        }, 1000);
      })
    }
  },
  modules: {
   
  }
})

组件调用:

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { State, Mutation, Action, Getter } from "vuex-class";

@Component
export default class Sister extends Vue {
  @State("username")
  private username!:string;

  @Mutation("SET_USERNAME")
  private setUserName!:(name:string) => void

  @Action("requestUserName")
  private requestUserName!:(id:number) => void

  @Getter("getUserName")
  private getUserName!:string

  async created () {
    // 获取state的username
    console.log(this.username);
    // 调用mutation的方法
    this.setUserName('abcd')
    // 调用actions的方法
    this.requestUserName(2)
    // 获取getter
    console.log(this.getUserName);
  }
}
</script>

四个模块的导入使用大致相同 

@模块("模块的属性命名")
  private 新名字!:类型; 

(2)模块化

在开发中模块vuex的场景还是比较多的 达到 清晰 易维护。

store/user/user.ts

import { Commit } from 'vuex';

interface state {
    username: string
}

const state: state = {
    username: 'default'
}

const mutations = {
    SET_USERNAME (state: state, val: string) {
        state.username = val
    }
}

const getters = {
    getUserName (state: state) {
        return '姓名' + state.username
    }
}

const actions = {
    async requestUserName (context: { commit: Commit }, id: number) {
        const users = [
            { id: 1, name: 'Ulrtraman' },
            { id: 2, name: 'Monsters' }
        ]
        return new Promise((resolve) => {
            setTimeout(() => {
                const username = users.find(it => it.id === id)?.name
                context.commit('SET_USERNAME', username)
                resolve(username)
            }, 1000);
        })
    }
}

export default {
    state, getters, mutations, actions, namespaced: true
}

tip: 要加namespace 命名空间 

store/index.ts

import Vue from 'vue'
import Vuex from 'vuex'
import user from './user/user'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    user
  }
})

组件调用:

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { namespace } from 'vuex-class';

const user = namespace('user');

@Component({
  components: { Son, Sister }
})
export default class App extends Vue {
  @user.State
  private username!: number;

  @user.Mutation
  private SET_USERNAME!: (name:string) => void;

  @user.Action
  private requestUserName!: (id:number) => void;

  @user.Getter
  private getUserName!: number;


  async beforeMount () {
    // state
    console.log('state:', this.username);
    // getter
    console.log('getter:', this.getUserName);
    // mutation
    this.SET_USERNAME('helloworld')
    // action
    await this.requestUserName(1);
  }
}
</script>

 使用方法:

import { namespace } from 'vuex-class';
const 变量 = namespace('文件名');

..

  @变量.模块
  private 新名字!: 类型;

四、mixin

src/mixins/mixin.ts


import { Component, Vue } from 'vue-property-decorator'

@Component
export default class HelloWorld extends Vue {
    created () {
        console.log('mixin的created');
    }
}

使用mixin

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator'
import mixin from '@/mixins/mixin'

@Component
export default class HelloWorld extends Mixins(mixin) {
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1260742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树的递归套路(2)

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 最大二叉搜索树 &#x1f48e;总结 最大二叉搜索树 题目 给定一颗二叉树的头节点head&#xff0c;返回这颗二叉树中最大的二叉搜索子树的节点数量 搜索二叉树&#xff1a;整棵树上没有重复值&#xff0c;左树的值都…

解决ansible批量加入新IP涉及known_hosts报错的问题

我们把一批新的IP加入到ansible的hosts文件&#xff0c;比如/etc/ansible/hosts&#xff0c;往往会有这样的提示&#xff0c; 因为本机的~/.ssh/known_hosts文件中并有fingerprint key串&#xff0c;使用ssh连接目标主机时&#xff0c;一般会提示是否将key字符串加入到~/.ssh/…

【密码学引论】分组密码

第三章 分组密码 DES、IDEA、AES、SM4 1、分组密码定义&#xff08;按照五个组成部分答&#xff09; 密钥空间&#xff1a;属于对称加密算法kekd明密文空间&#xff1a;将明文划分为m比特的组&#xff0c;每一块依次进行加密加解密算法&#xff1a;由key决定一个明文到密文的…

Redis多机数据库

文章目录 Redis多机数据库一、主从复制1、旧版复制功能的实现a、同步b、命令传播 2、旧版复制功能的缺陷3、新版复制功能的实现a、部分同步功能b、复制实现步骤 4、心跳检测 二、哨兵1、Sentinel概念2、Sentinel初始化流程3、故障转移过程 三、集群1、几个概念2、集群创建流程a…

西南科技大学(数据结构A)期末自测练习一

一、填空题(每空0.5分,共5分) 1、数据结构是指( A )。 A、数据元素的组织形式 B、数据类型 C、数据存储结构 D、数据定义 2、数据结构被形式地定义为(D,R),其中D是( B )的有限集合,R是D上( D )的有限集合。 (1)A.算法B.数据元素C.数据操作D.逻辑结构 (2)A.操作B.…

springboot启动Table ‘xxx‘ already exists

jpa.generate-ddl和jpa.hibernate.ddl-auto都可以控制是否执行datasource.schema脚本&#xff0c;来初始化数据库结构&#xff0c;只要有一个为可执行状态就会执行&#xff0c;比如jpa.generate-ddl:true或jpa.generate-ddl:update&#xff0c;并没有相互制约上下级的关系。 要…

使用com组件编辑word

一个普通的窗体应用&#xff0c;6个button using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; u…

Kafka 如何保证消息消费的全局顺序性

哈喽大家好&#xff0c;我是咸鱼 今天我们继续来讲一讲 Kafka 当有消息被生产出来的时候&#xff0c;如果没有指定分区或者指定 key &#xff0c;那么消费会按照【轮询】的方式均匀地分配到所有可用分区中&#xff0c;但不一定按照分区顺序来分配 我们知道&#xff0c;在 Kaf…

【操作宝典】SQL Server Management

目录 ⛳️【SQL Server Management】 ⛳️1. 启动登录 ⛳️2. 忘记密码 ⛳️3. 操作数据库和表 3.1 新建数据库text 3.2 新建表 3.3 编辑表 3.4 编写脚本 ⛳️【SQL Server Management】 ⛳️1. 启动登录 需要开启服务 ⛳️2. 忘记密码 登录windows--> 安全性 -->…

优雅使用docker-compose部署Skywalking

Skywalking使用docker-compose部署 version: 3.1 services: // 部署elasetic search 用于存储获取的应用信息与日志elasticsearch:image: elasticsearch:7.13.3container_name: elasticsearchprivileged: trueenvironment:- "cluster.nameelasticsearch" #设置集群名…

Vue3使用kkFileView预览文件pdf

kkFileView - 在线文件预览kkFileView官网 - kkFileView使用Spring Boot搭建&#xff0c;易上手和部署&#xff0c;基本支持主流办公文档的在线预览&#xff0c;如doc,docx,Excel,pdf,txt,zip,rar,图片等等https://kkfileview.keking.cn/zh-cn/docs/usage.html业务场景&#xf…

powershell获取微软o365 21v日志

0x00 背景 o365 21v为o365的大陆版本&#xff0c;主要给国内用户使用。微软提供了powershell工具和接口获取云上日志。微软o365国内的代理目前是世纪互联。本文介绍如何用powershell和配置证书拉取云上日志。 0x01 实践 第一步&#xff0c;ip权限开通&#xff1a; 由世纪互联…

生命科学领域 - 新药从研发到上市全流程

新药是指新研制的、临床尚未应用的药物&#xff0c;其化学本质应为新的化合物或称新化学实体、 新 分子实体、新活性实体。新药研发的根本目的是治疗疑难危重疾病&#xff0c;研制出来的药物即使是全新的化学结构&#xff0c;但是疗效或安全性却不及现有的药物便失去新药价值&a…

JAVAEE 初阶 多线程基础(三)

启动,中断,等待基础 一.如何创建线程二.启动线程 start()1.1 调用两次start方法1.2 创建新对象解决多个start问题2.1 经典面试题 run和start的区别 三.中止线程3.1 引入标志位3.2 高级写法3.3高级写法的错误之处3.4问题的解决3.5 将标志位放在main的局部变量中是否可行 四.等待…

Android 单元测试初体验(二)-断言

[TOC](Android 单元测试初体验(二)-断言) 前言 当初在学校学安卓的时候&#xff0c;老师敢教学进度&#xff0c;翻到单元测试这一章节的时候提了两句&#xff0c;没有把单元测试当重点讲&#xff0c;只是说我们工作中几乎不会用到&#xff0c;果真在之前的几年工作当中我真的没…

flutter布局详解及代码示例(上)

布局 基本布局 Row&#xff08;水平布局&#xff09;&#xff1a;在水平&#xff08;X轴&#xff09;方向上排列子widget的列表。Column&#xff08;垂直布局&#xff09;&#xff1a;在垂直&#xff08;Y轴&#xff09;方向上排列子widget的列表。Stack&#xff08;可重叠布…

【九章斩题录】Leetcode:面试题 01.03. URL化(C/C++)

精品题解 &#x1f525; 《九章斩题录》 &#x1f448; 猛戳订阅 面试题 01.03. URL化 &#x1f4da; 题目&#xff1a;URL化。编写一种方法&#xff0c;将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符&#xff0c;并且知道字符串的“真实”长度。…

本地训练,立等可取,30秒音频素材复刻霉霉讲中文音色基于Bert-VITS2V2.0.2

之前我们使用Bert-VITS2V2.0.2版本对现有的原神数据集进行了本地训练&#xff0c;但如果克隆对象脱离了原神角色&#xff0c;我们就需要自己构建数据集了&#xff0c;事实上&#xff0c;深度学习模型的性能和泛化能力都依托于所使用的数据集的质量和多样性&#xff0c;本次我们…

使用最小花费爬楼梯(力扣LeetCode)动态规划

使用最小花费爬楼梯 题目描述 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶…

Springboot日志-logback

logback-spring.xml的配置项 共有一个父标签、两种属性、三个节点: 一个父标签&#xff1a;configuration 两种属性&#xff1a;contextName和property 三个节点&#xff1a;appender、root、logger 日志级别 日志级别从低到高分为TRACE < DEBUG < INFO < WARN &…