创建组件

最近更新时间:2019-06-21 20:09:36

操作场景

组件是指页面上的按钮、文本框、输入框、下拉框等,每个组件需要维护组件 ID、点击事件、渲染、销毁等功能。本文档指导您如何实现按钮 Button 组件和文本框 MsgBox 组件。

操作步骤

创建组件基类

  1. 在根目录新建两个文件夹,分别命名为 component 和 view,并在 component 中创建一个 BaseComponent.js 文件,在 view 中创建一个 BaseView.js 文件。如下图所示:
    页面与组件文件夹

    • BaseComponent.js 文件:作为 Button 和 MsgBox 的基类。
    • BaseView.js 文件:作为页面的基类。
  2. 在 BaseComponent.js 中添加以下代码:

     // 组件基类
     import * as Util from "../Util.js";
    
     export default class BaseComponent {
    
         id;
         // 组件区域
         area = [0, 0, 0, 0];
    
         constructor() {
             // 为组件生成 ID
             this.id = Math.ceil(Math.random() * 10000) + "_" + Date.now();
         }
    
         // 子类实现具体绘制方法
         render() { }
    
         // 记录组件区域
         setArea(x, y, w, h) {
             this.area[0] = x;
             this.area[1] = y;
             this.area[2] = x + w;
             this.area[3] = y + h;
         }
    
         // 注册点击事件
         onClick(callback) {
             this.offClick();
             Util.onClick(this.id, this.area, callback);
         }
    
         // 取消点击事件
         offClick() {
             Util.offClick(this.id);
         }
    
         // 销毁
         onDestroy() {
             this.offClick();
         }
     }

实现按钮 Button

在 component 文件下,新建一个 Button.js 文件,用于实现一个基于 BaseComponent 的 Button 类。其 Button 类包含 render、setText 两个方法。
示例代码如下所示:

import * as Util from "../Util.js";
import BaseComponent from "./BaseComponent.js";

export default class Button extends BaseComponent {
    x;
    y;
    text;

    constructor(x, y, text) {
        super();

        this.x = x;
        this.y = y;
        this.text = text;
    }

    // 绘制
    render() {
        // 清除原图像
        Util.ctx.lineWidth = 2;
        Util.ctx.fillStyle = "white";

        const x1 = this.area[0] - Util.ctx.lineWidth / 2;
        const y1 = this.area[1] - Util.ctx.lineWidth / 2;
        const x2 = this.area[2] + this.area[0] + Util.ctx.lineWidth / 2;
        const y2 = this.area[3] + this.area[1] + Util.ctx.lineWidth / 2;
        Util.ctx.fillRect(x1, y1, x2, y2);

        // 绘制图形
        Util.ctx.strokeStyle = "black";
        Util.ctx.fillStyle = "black";
        Util.ctx.font = "20px Arial";

        const padding = 5;
        const width = Util.ctx.measureText(this.text).width + padding * 2;
        const height = 20 + padding * 2;

        Util.ctx.strokeRect(this.x, this.y, width, height);
        Util.ctx.fillText(this.text, this.x + padding, this.y + height - padding - 3);

        // 记录按钮区域
        this.setArea(this.x, this.y, width, height);
    }

    // 设置文本内容
    setText(text) {
        this.text = text;
        this.render();
    }
}

实现文本框 MsgBox

  1. 在 component 文件夹下,新建一个 MsgBox.js 文件,用于实现一个基于 BaseComponent 的 MsgBox 类。MsgBox 类包含 render、setText 两个方法。
    示例代码如下所示:

     import * as Util from "../Util.js";
     import BaseComponent from "./BaseComponent.js";
    
     export default class MsgBox extends BaseComponent {
         x;
         y;
         text;
    
         constructor(x, y, text) {
             super();
    
             this.x = x;
             this.y = y;
             this.text = text;
         }
    
         // 绘制
         render() {
             const width = Util.width - 2 * this.x;
             const height = 300;
             const padding = 5;
    
             // 清除原图形
             Util.ctx.strokeStyle = "black";
             Util.ctx.fillStyle = "white";
    
             Util.ctx.fillRect(this.x, this.y, width, height);
             Util.ctx.strokeRect(this.x, this.y, width, height);
    
             // 绘制图形
             Util.ctx.strokeStyle = "black";
             Util.ctx.fillStyle = "black";
             Util.ctx.font = "15px Arial";
    
             const texts = this.text.split("\n");
    
             texts.forEach((t, i) => Util.ctx.fillText(t, this.x + padding, this.y + padding + (i + 1) * (15 + padding), width - padding * 2));
    
             // 记录文本框区域
             this.setArea(this.x, this.y, width, height);
         }
    
         // 设置文本内容
         setText(text) {
             this.text = text;
             this.render();
         }
     }
  2. 在 component 文件夹中,创建一个 index.js 文件,用于导出 Button.js、MsgBox.js 两个文件。
    示例代码如下:

     import Button from "./Button.js";
     import MsgBox from "./MsgBox.js";
    
     export default {
         Button,
         MsgBox
     };

    组件