类(class)
类的类型(implement)
对类的类型定义使用interface,然后类使用implements实现这个 interface:
interface Options {
el: string | HTMLElement;
}
interface VueCls {
options: Options;
init(): void;
}
class Vue implements VueCls {
options: Options;
constructor(options: Options) {
this.options = options;
}
init(): void {}
}
new Vue({
el: "#app",
});
类的继承类型(extends)
使用 extends 继承某个类,继承之后就可以用 this 访问到被继承的类里的对象或方法。
// ...(省略上面一些接口的定义)
interface VNode {
tag: string;
text?: string;
children?: VNode[];
}
class Dom {
// 创建节点的方法
createElement(el: string) {
return document.createElement(el);
}
// 填充文本的方法
setText(el: HTMLElement, text: string | null) {
el.textContent = text;
}
// 渲染函数
render(data: VNode) {
let root = this.createElement(data.tag);
if (data.children && Array.isArray(data.children)) {
data.children.forEach((item) => {
let child = this.render(item);
root.appendChild(child);
});
} else {
this.setText(root, data.text);
}
return root;
}
}
class Vue extends Dom implements VueCls {
options: Options;
constructor(options: Options) {
super(); // 继承类需要写 @1
this.options = options;
this.init();
}
init(): void {
// 虚拟dom,通过js去渲染真实dom
let data: VNode = {
tag: "div",
children: [
{
tag: "section",
text: "我是子节点",
},
{
tag: "section",
text: "我是子节点2",
},
],
};
let app =
typeof this.options.el == "string"
? document.querySelector(this.oprions.el)
: this.oprions.el;
app.appendChild(this.render(data));
}
}
new Vue({
el: "#app",
});
@1:
super()指向的是父类,相当于调用了父类的 prototype.constructor.call。它可以向父类传参。
readonly
只能添加在属性上,让属性只可读,不可以被修改。
class Vue extends Dom implements VueCls {
readonly options: Options;
...
}
private
添加在属性和方法上,被添加的属性和方法只能在其内部访问(不可在其子(继承类)或实例上访问)。
class Dom {
// 创建节点的方法
private createElement (el: string) {
return document.createElement(el);
}
...
}
protected
添加在属性和方法上,被添加的属性和方法只能在其内部或其子类内部访问(不可在其实例上访问)。
class Dom {
// 创建节点的方法
protected createElement (el: string) {
return document.createElement(el);
}
...
}
public
添加在属性和方法上,所有都能访问到。
所有属性和方法的默认值。
static
添加在属性和方法上,被添加的属性和方法只能访问到同 static 的属性和方法,只能在其实例上访问。
get 和 set
通过 get 和 set 来实现一个拦截器。
- get:获取某个值时对其进行操作。
- set:设置某个值时对其进行操作。
class Ref {
_value: any;
constructor(value: any) {
this._value = value;
}
get value() {
return this._value + "aaa";
}
set value(newVal) {
this._value = newVal + "bbb";
}
}
const ref = new Ref("哈哈");
console.log(ref.value); // 哈哈aaa
ref.value = "ccc";
console.log(ref.value); // cccbbbaaa
抽象类(abstract)
用abstract定义的类为抽象类,abstract定义的方法为抽象方法。
- 抽象类无法被实例化。
- 抽象方法只能被描述,不能进行实现。
abstract class Vue {
name: string;
constructor(name?: string) {
this.name = name;
}
getName(): string {
return this.name;
}
abstract init(name: string): void; // 只能描述
}
抽象类如果要使用,可以使用extends继承,继承的类叫做派生类。派生类如果要继承抽象类,需要将抽象类里的抽象方法都实现:
class React extends Vue {
constructor() {
super();
}
init(name: string) {} // 抽象方法必须实现
setName(name: string) {
this.name = name;
}
}
派生类可以被实例化:
const react = new React();
react.setName("名字");
console.log(react.getName()); // 名字