TS 的 class 看起来和 ES6 的 Class 有点像,基本上差别不大,除了 可以继承(实现)接口、私有成员、只读等之外。

参考:https://typescript.bootcss.com/classes.html

基本用法

我们可以定义一个 class,设置几个属性,然后设置一个方法,封装 Object.assign 简化reactive 的赋值操作。

  • 创建自己的对象基类
  import type { InjectionKey } from 'vue'

  class BaseObject {
$id: string | symbol | InjectionKey<string>
name: string
age: number constructor (id: string, name: string, age: number) {
this.$id = id
this.name = name
this.age = age
} set $state(value: any) {
Object.assign(this, value)
}
}
  • 使用
  import { reactive, defineComponent } from 'vue'

  const _state = new BaseObject('007', 'jyk')
const state = reactive(_state) state.$state = {
name: '直接赋值'
}

看着是不是眼熟?你猜对了!这里参考 Pinia 设置 $state ,实现给 reactive 直接赋值的功能。

reactive 哪都好,只是整体赋值的时候有点郁闷,这里简单封装了一下,实现直接赋值的功能。

类的继承

上面的方法只是封装了对象,那么数组怎么办呢?这里就需要用到“继承” extends 的用法。

  • 继承 js 的 Array 创建自己的数组类
  class BaseArray extends Array  {
$id: string | symbol | InjectionKey<string> constructor () {
// 调用父类的 constructor()
super()
this.$id = 'array'
} set $state(value: any) {
this.length = 0
if (Array.isArray(value)) {
this.push(...value)
} else {
this.push(value)
}
}
}
  • 使用
const _state2 = new BaseArray()
const state2 = reactive(_state2) state2.$state = [
{
name: '008'
},
{
name: '009'
}
]

这样数组形式的 reactive ,也可以直接赋值了,是不是方便很多?

继承的是原生数组,所以拥有了数组的所有功能。

另外,子类的constructor里面,需要调用 super() 才会有 this。

实现接口

观察上面的两个 class,会发现拥有相同的成员:$id 和 $state。那么要不要约束一下?

如果想要实现约束功能的话,可以定义一个 interface 来实现。

  • 定义接口
  interface IState {
$id: string | symbol | InjectionKey<string>
set $state(value: any)
}
  • 实现接口
  class BaseObject implements IState {

} class BaseArray extends Array implements IState {

}

这样设置之后,类的成员就要复合接口的定义,不符合的话会出现提示。

私有成员、只读成员

虽然可以使用 private、readonly 标识私有成员和只读成员,只是嘛,到目前为止有点鸡肋。因为只是在 TS 的范畴内给出错误提示,但是完全不影响运行。

那么能不能变相实现一下呢?可以的,只是有点绕圈圈,另外似乎不太正规。

我们把 $id 改为只读、伪隐藏成员。

  • 修改一下接口,使用访问器(get)设置 $id
  interface IState {
get $id(): string | symbol | InjectionKey<string>
set $state(value: any)
}
  • 修改一下对象基类,使用 get 访问器
  class BaseObject implements IState {
get $id(): string | symbol | InjectionKey<string>

}
  • 创建对象实例的函数
  function createState(id: string, name: string, age: number) {
// 继承 BaseObject 再定义一个class
class myState extends BaseObject {
constructor (name: string, age: number) {
// 调用父类的 constructor()
super(name, age)
}
// 使用 override 覆盖父类 $id
override get $id() {
return id
}
} const _state = new myState(name, age)
const state = reactive(_state) return state
}
  • 使用
  const state3 = createState('010', 'jyk0013', 29)
console.log(state3)
console.log('state3 - keys', Object.keys(state3))
for (const key in state3) {
console.log(key, state3[key])
}
  • 效果

  • 分析

把 $id 改为 get 访问器的方式,可以实现 readonly 的效果。

$id 放在 class (myState) 的“原型”上面,可以避免被遍历出来,这样就实现了伪隐藏的效果。

当然 使用 state.$id 的方式还是可以访问到的,所以是伪隐藏。

完整项目代码

https://gitee.com/naturefw-code/nf-rollup-state

被迫开始学习Typescript —— class的更多相关文章

  1. 被迫开始学习Typescript —— interface

    一开始以为,需要使用 class 来定义呢,学习之后才发现,一般都是使用 interface 来定义的. 这个嘛,倒是挺适合 js 环境的. 参考:https://typescript.bootcss ...

  2. 被迫开始学习Typescript —— vue3的 props 与 interface

    vue3 的 props Vue3 的 props ,分为 composition API 的方式以及 option API 的方式,可以实现运行时判断类型,验证属性值是否符合要求,以及提供默认值等功 ...

  3. 在WisOne平台上学习TypeScript

    TypeScript是微软公司推出的开源的类型化脚本语言,目的是用于为弱类型的javaScript提供强类型的识别和感知功能,同时它提供了类.接口.继承等相关在javaScript中不容易实现的功能, ...

  4. 学习TypeScript,笔记一:TypeScript的简介与数据类型

    该文章用于督促自己学习TypeScript,作为学笔记进行保存,如果有错误的地方欢迎指正 2019-03-27  16:50:03 一.什么是TypeScript? TypeScript是javasc ...

  5. 学习typescript(二)

    学习typescript(二) ts 与 js 交互 ts 调用 js module使用 分为两种情况: ts 调用自己写的 js ts 调用别人写的 js 也就通过 npm 安装的 第一种情况处理如 ...

  6. 「非软文」零基础学习TypeScript(源码开源)

    今天,这篇文章篇幅很短,主要开放我最近学习整理TypeScript源码. 源码地址 https://github.com/maomincoding/typeScript_study 更多内容请见原文, ...

  7. 跟着Vam一起学习Typescript(第一期)

    一.安装环境与配置1.命令行安装 npm i -g typescript 2.快捷打开Vs Code编辑器 创建一个项目文件夹,在该文件夹下打开命令行工具,使用code .命令快速打开编辑器(如果计算 ...

  8. 学习typescript(一)

    环境 必装软件 node,推荐 node 8.0 npm,推荐 npm 5.0 git, 最新版 vscode, 编绎器 必装包 tsc: npm install -g typescript typi ...

  9. 学习TypeScript 笔记

    TypeScript 什么是TypeScript TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准. TypeScript 由微软开发的自由和开源的编程 ...

随机推荐

  1. MySQL索引如何优化?二十条铁则

    索引的相信大家都听说过,但是真正会用的又有几人?平时工作中写SQL真的会考虑到这条SQL如何能够用上索引,如何能够提升执行效率?  前言 索引的相信大家都听说过,但是真正会用的又有几人?平时工作中写S ...

  2. 树莓派安装ros

    之前电脑安装过ros感觉还好,没成想这次在树莓派上安装费老劲了,出现了很多错误,装了卸,卸了装废了半天劲下面将一些安装的错误和问题做个总结方便以后的安装也希望给别人一个参考 ros安装(对照自己的版本 ...

  3. Altium Designer 开始一个项目

    通常一个嵌入式开发都需要一个开发板,这就涉及到原理图设计和PCB设计等流程.目前比较主流的设计软件当属Altium Designer了,于是便向写一个关于这方面的专题,也好总结一下,省得以后忘记. A ...

  4. 用jq实现移动端滑动轮播以及定时轮播效果

    Html的代码: <div class="carousel_img"> <div class="car_img" style="ba ...

  5. .Net Core:Docker无法拉取mcr.microsoft.com相关镜像解决办法

    今天在教同事Docker简单部署Asp.Net Core项目,pull镜像时突然出现下图中的错误: 因为微软在 2018 年五月之后,只会将相关镜像打包发布到 MCR 上.但是 MCR 对国内用户不太 ...

  6. 每日所学之自学习大数据的Linux环境的配置

    今天开始配置环境,因为下载镜像文件需要很长时间,加上训练,所以Linux环境之配置了一半 VMware下载及安装教程(Window) 在安装虚拟机时需要下载镜像文件 下面是我下载的镜像文件的地址 Ce ...

  7. fetch和axios区别,摘自Stack Overflow网站答案

    fetch 请求let url = 'https://someurl.com'; let options = { method: 'POST', mode: 'cors', headers: { 'A ...

  8. Java类型转换详解

    Java类型转换详解 最近有同学问:自动类型转换老是记不住,到底是大转小,还是小转大 其实这个不用死记硬背,很好理解,我们拿 int 和 short 来举例: int 是 4 字节,也就是 32 bi ...

  9. IDEA出现Error during artifact deployment. See server log for details.

    第一步查看配置 然后点击Web Application Exploded->from Module, 如果以上问题都不存在,则要检查lib下是否缺少相应的jar包,是否导入,是否jar包过多产生 ...

  10. 痞子衡嵌入式:大话双核i.MXRT1170之单独在线调试从核工程的方法(IAR篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170下单独在线调试从核工程的方法(基于IAR). 两年前痞子衡写过一篇<双核i.MXRT1170之Cortex-M ...