Vite中使用import-metadata

346 阅读1分钟

创建Vite工程

如何创建vite工程

首先修改tsconfig.json中的"useDefineForClassFields"属性为"false"

防止因为构造函数的define提案,导致new 类时出现某些问题

{
  "compilerOptions": {
  // ...
    "useDefineForClassFields": false,
    }
}

一个使用案例

GUI使用的是 dat.gui

container使用的是 tsyringe 库封装的一个单例函数,大家可以自己写个单例即可

需求描述:我想通过类的装饰器来自动创建gui文件夹和对某些属性进行gui调整

import 'reflect-metadata';
import { container } from 'tsyringe';
import GUI from '../../package/gui';

const Types = {
  GuiProp: Symbol('GuiProp'),
  FolderName: Symbol('FolderName'),
};
const guiCache = new Map();
export const GuiFolderable = (GuiFolder: string) => {
  const folderName = GuiFolder;
  log('folderName', folderName);
  // 添加文件夹
  const folder = container.resolve(GUI).target.addFolder(folderName);
  guiCache.set(folderName, folder);
  return (target: any) => {
    const folder = guiCache.get(folderName);
    Object.getOwnPropertyNames(target).forEach((name) => {
      try {
        const folderFn = Reflect.getMetadata(Types.FolderName, target, name);
        folderFn && folderFn(folder);
      } catch (error) {
        console.error(error);
      }
    });
    return target;
  };
};

export const InjectGuiStaticProp = (
  min: number,
  max: number,
  step: number
): PropertyDecorator => {
  return (target: any, key: string | symbol) => {
    Reflect.defineMetadata(
      Types.FolderName,
      (guifolder: any) => {
        guifolder.add(target, key).min(min).max(max).step(step).listen();
      },
      target,
      key
    );
  };
};

使用案例

我将对一个车模型进行一些参数配置与封装

/**
 * 轿车
 */
@GuiFolderable('CarObj Controller')
export default class CarObj extends RosObj {
  constructor(options: Partial<ObjOptions> = {}) {
    super('car_model', options);
  }
  @InjectGuiStaticProp(0, 360, 1)
  static rotateX: number = 90;
  @InjectGuiStaticProp(0, 360, 1)
  static rotateY: number = 0;
  @InjectGuiStaticProp(0, 360, 1)
  static rotateZ: number = 180;
}

// ...

new CarObj();

界面显示截图

image.png

后续扩展

有了这个方案后,我可以对车颜色、属性checkout勾选,属性options进行更多的封装与调试.