低代码平台umd + Vue.use支持用户自开发物料组件

1,370 阅读3分钟

低代码平台已经遍地走的今天,你指定遇到过客户想要的功能无法通过配置实现的情况

解法之一便是支持用户自开发物料组件

下面是在低代码平台中实现这一目标的一个方式(文末附完整代码)

为什么要支持用户自开发物料组件?

低代码平台的主要优势之一是其开箱即用的高效性,每个项目的需求都有所不同,标准组件往往难以完全覆盖所有业务场景。因此支持用户自行开发物料组件,不仅可以拓展平台的适用性,还能提供更加个性化的服务,更好地满足甲方的具体需求

思路

由于使用的是vue,那么在开发过程中最终的自开发物料组件也是基于vue的。如果需要在工程代码运行时动态加载组件,那么可以使用Vue.component方法。这样,我们可以在低代码平台上通过用户输入的方式,动态生成组件代码,然后通过Vue.component方法注册组件,从而实现用户自开发物料组件的功能。

但是要如何在低代码平台上实现这一功能呢??注册组件是需要组件的代码,而组件代码必定是由开发者提编写提供的

因此,我们需要一个平台来支持用户上传组件代码,并且在运行时动态加载这些组件,自开发的物料组件就像是一个cdn资源一样,可以通过一个url地址来加载

加载之后,通过Vue.component方法注册组件,从而实现用户自开发物料组件的功能

那么就需要

将自开发资源打包为一个js文件,然后通过url地址来加载这个js文件, 暴露一个全局变量

当前有另一个api更加的合适,那就是Vue.use方法,这个方法可以接受一个对象,这个对象必须有一个install方法,这个install方法的参数位置就是Vue对象,这样就可以在install方法中注册组件,从而实现用户自开发物料组件的功能,并且函数式的也便于开发者拓展

通过Vue.use方法注册组件

demo

效果如图:

img_2024_08_20_14_08_15.png

两步走: 第一步:配置一个可以打包自定义资源为umd的工程

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

const args = process.argv.slice(2);
const nameArgIndex = args.indexOf("--name");
const componentName =
  nameArgIndex !== -1 ? args[nameArgIndex + 1] : "MyCustomComponent";

export default defineConfig({
  plugins: [vue()],
  build: {
    lib: {
      entry: "./src/custom/index.js",
      name: componentName,
      formats: ["umd"],
      fileName: (format) => `${componentName}.${format}.js`,
    },
    rollupOptions: {
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue",
        },
      },
    },
  },
});

第二步:在低代码主工程加载注册插件资源

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>low code My Custom Component</title>
    <link
      rel="stylesheet"
      href="//cdn.jsdelivr.net/npm/element-plus/dist/index.css"
    />
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="./dist/MyCustomComponent.umd.js"></script>
    <script src="//cdn.jsdelivr.net/npm/element-plus"></script>
  </head>
  <body>
    <div id="app"></div>
    <script>
      const app = Vue.createApp({
        template: `
          <div>
            <h1>Low Code Main Instance</h1>
            <el-button type="primary" @click="reloadComponent">Primary</el-button>
            <h2>My Custom Component</h2>
            <CustomCalendar :key="componentKey" />
          </div>
        `,
        setup() {
          const componentKey = Vue.ref(0);
          const isComponentRegistered = Vue.ref(false);
          function reloadComponent() {
            componentKey.value += 1;
          }

          return { componentKey, isComponentRegistered, reloadComponent };
        },
      });
      app.use(ElementPlus);
      app.use(MyCustomComponent);
      window.MyCustomComponent = null;
      delete window.MyCustomComponent;
      app.mount("#app");
    </script>
  </body>
</html>

结语

上面低代码自开发组件的资源加载demo简单表明了核心的逻辑,真正在项目使用中也是通过Vue.use方法注册一个 vue 插件,从而实现用户自开发物料组件的功能,其中区别是用的vue-cli进行打包

大家也可以看出上面的打包方式会外置vue,使得window上必须有Vue对象,才可以正常运行

但是在window上挂一个全局Vue对象,不是我想要的

当前未有想到合适的解决方案,有待进一步研究,希望各位指点一二

源码地址:

github.com/Aoyia/self-…

参考文献:

juejin.cn/post/716810… 模拟commonjs环境加载组件,里面没有说明是如何打包的,会不会有依赖问题