德胜云资讯,添加一些关于程序相关的内容,仅供大家学习交流(https://www.wxclwl.com)

网站地图

搜索
德胜云咨询
前端分类 javascript CSS 正则表达式 html 前端框架 typescript Ajax
热门标签:
最新标签:

typescript编译成class被迫开始学习Typescript——classtypescript编译成js后出现语法错误越早知道越好,

日期:2023/03/24 19:41作者:蔡依婷人气:

导读:上一篇:被迫开始学习Typescript——interface。TS 的 class 看起来和 ES6 的 Class 有点像,基本上差别不大,...

上一篇:被迫开始学习Typescript——interface

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

参考:类(class) - TypeScript 中文手册

基本用法

我们可以定义一个 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 的方式还是可以访问到的,所以是伪隐藏。

完整项目代码

nf-state-轻量级状态管理: vite + vue3 做一个轻量级的状态管理。

排行

网站地图

Copyright © 2002-2022 香港德胜云网络 版权所有 | 备案号:蜀ICP备2023007363号-5

声明: 本站内容全部来自互联网,非盈利性网站仅供学习交流