agile-core
v3.0.13
Published
Agile Core - A powerful component based micro front-end framework
Downloads
22
Maintainers
Readme
Agile框架使用指南
概述
Agile框架结合Vite和VUE的技术栈+自定义组件模块(基于Web Component),形成一个组件式的微前端框架。该框架旨在实现跨框架调用的微前端组件定义和使用。
使用Agile框架创建的组件称为AUI组件,该组件可以在框架内使用,也可以打包后在任意框架中通过引入js的方式使用,包括任何标准的DOM操作方式调用和样式设置。
特性
🚀 跨框架兼容
- 原生DOM组件:基于Web Components标准,编译后的组件是原生HTMLElement扩展
- 多框架支持:可在Vue、React、Angular等任意框架中使用
- 标准DOM操作:支持
document.createElement、innerHTML等标准DOM操作方式 - 双模式调用:框架内可使用Vue组件语法和原生DOM方式,框架外使用原生DOM方式
💡 继承VITE+VUE开发体验
- Vue语法兼容:
.aui.vue文件格式,保持Vue开发习惯 - TypeScript支持:完整的类型定义和智能提示
- 热更新支持:基于Vite的现代化开发工具链
- 性能优化:基于Vue3的性能优化
🔧 企业级场景设计
- 全粒度开发:可以用于组件库、模块、插件、应用等任何粒度开发
- Hook扩展机制:为不同客户通过定制化组件实现差异功能
- 技术栈异构:主应用和子应用使用不同前端框架
- 独立部署:组件库独立发布,各应用按需引入
- 渐进式集成:现有微前端项目可逐步引入AUI组件
规范
- AUI组件必须以
.aui.vue作为文件后缀 - 组件名是唯一的,同一个组件名对应的实现只有一个,组件可以重复定义,但是后面定义的会覆盖前面的,其中有个名为
auix的prop属性用于扩展属性 - 组件名称必须是帕斯卡命名法(Pascal Case),即每个单词的首字母都是大写,单词之间没有分隔符
- 组件名一般显式的在组件中通过name来定义,否则将取当前文件名的名称作为组件名
接口
1. AUI初始化事件
当组件mounted结束会执行两个动作:
- 触发
aui-init事件,事件的detail为{code: 0}。(该事件作用在原生DOM上,所以框架内和外都可以监听) - 执行组件内部的
auiInit函数(如果存在),该函数与mounted同级。
2. 通用组件间函数调用
函数定义:async $call(name: string, ...args: any[]) : any 该函数是通用的组件间函数调用的定义,AUI原生DOM调用VUE组件函数或者VUE组件调用AUI原生DOM的函数都是使用这个方法。
其中,name可以是组件里暴露的函数名或者属性名(支持多级属性访问),前提是这些函数或属性要暴露,当为函数时为执行函数并返回结果;当为属性时,如果没有args则返回属性值,如果有args,将取args的第一个元素赋值给属性,返回null;当匹配不到任何函数和属性将返回一个Error对象。
- 原生DOM调用VUE组件,则组件内使用
this.$call调用,框架外使用el.$call。
// $call是原生DOM上的扩展函数,用于组件外部调用内部的函数或者取值/赋值之用
const el = document.querySelector('aui-my-com');
const value = await el.$call('echo', 111); // value 为111- VUE组件调用原生DOM,则组件内使用
this.$call调用
// $call也是VUE组件的扩展函数,用于组件内调用原生DOM的函数或者取值/赋值之用
export default {
...
methods: {
setDomStyle() {
this.$call('setAttribute', 'style', 'color: red;');
}
}
...
}3. MVVM使用
由于AUI组件本身是原生DOM,所以都是通过value值作为MVVM绑定的依据(注意区分通过setAttribute设置的value属性,非同一个意思)。
VUE组件扩展了两个重要的方法:$value和$anyToArray。
$value: 该方法用于获取或设置组件的原生DOM的value值,主要用于MVVM绑定值传递给原生DOM。
$anyToArray: 该方法用于将任意类型的值转换为数组类型,主要用于处理多选场景。
使用方式如下:
<aui-tradition-comp v-model="msg" />
<!-- 使用Vue方式引用时,注意要加v-model:value,而使用标签名时只需要写v-model -->
<TraditionComp v-model:value="msg" />在组件内部需要绑定一个额外的变量做内部的MVVM,并同时监听value值和该变量的变化,如下:
{
...
data() {
return {
localValue: ''
}
},
watch: {
value(v) {
// 当原生DOM的value值变化,同时更新内部变量
this.localValue = v;
},
localValue(v) {
// 当内部变量变化,同时设置原生DOM的value值
this.$value(v);
},
}
...
}注意:
- 如果绑定的是多选类型,比如checkbox或者multiple类型的select以及一些自定义的组件,则内部变量的值必须是数组,而其他的则为字符串
- value值默认是String类型,所以通过el.value获取到的值都是string类型,并且在设置value时也会被转为字符串,在多选场景下,如果希望直接获取到数组,可以在组件里为value添加prop,并设置type为Array即可
- 如果多选场景没有单独设置value的type为Array,则需要自行在watch监听value变化的时候将字符串转为数组。VUE的
methods上已经扩展里$anyToArray函数来转数组,比如:
{
...
watch: {
value(v) {
this.localArray = this.$anyToArray(v);
},
localArray(v) {
this.$value(v);
}
},
...
}
4. slot插槽使用
由于AUI组件是原生DOM,所以使用上跟VUE本身的插槽使用方式有所不同。类似于DIV等标签,理论上所有子节点都是默认插槽的内容,而没有具名插槽,为了扩展具名插槽,AUI组件内部使用了aui-slot元素来实现具名插槽。
使用规范:
aui-slot仅在通过原生DOM方式时使用,通过标准VUE组件则仍使用template。aui-slot元素使用for属性指定需要插入的插槽名称。aui-slot不支持VUE插槽的高级用法。
比如:
<!-- 使用原生DOM方式调用需要使用aui-slot包装 -->
<aui-my-comp>
<aui-slot for="header">
<div>这是header</div>
</aui-slot>
</aui-my-comp>
<!-- 使用VUE标准方式调用需要包使用template -->
<MyComp>
<template #header>
<div>这是header</div>
</template>
</MyComp>5. 其他
在框架内部调用组件,可以直接使用标签名(aui-comp-name)方式调用,也可以使用Vue风格的组件调用方式,如果是在框架外调用则只能通过标准的DOM操作方式调用,比如:
<!-- 该方式可以在框架内和框架外调用 -->
<aui-my-comp @aui-init="onInit" :my-msg="msg||'这是第一个AUI组件'"/>
<!-- 该方式只能在框架在调用 -->
<MyComp @aui-init="onInit" :my-msg="msg||'这是通过VUE组件方式引入的AUI组件'"/>// 通过标准创建原生DOM方式在框架内和框架外都可使用
const el = document.createElement('aui-my-comp');
document.body.append(el);
// 通过标准插入代码片段方式在框架内和框架外都可使用
document.body.innerHTML = '<aui-my-comp />'
使用
Agile3.0框架目前只支持在Vite项目中开发,但是编译后可以在任何框架中使用。
版本要求:
- node22+
- vite7+
- vue3+
第一步:安装模块
npm install agile-core安装完成会在当前工程的types目录生成必要的代码模块定义,如果没有生成,可以到已安装的模块的types目录下把所有d.ts文件拷贝到项目的types目录,并且设置项目自身的tsconfig.json文件,添加types目录到include节点下
第二步:在Vite.config.ts配置中添加aui插件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { getAuiConfig } from 'agile-core'
import { mergeConfig } from 'vite'
// 引入aui插件
const { userConfig, isCustomElement } = getAuiConfig();
const baseConfig = {
plugins: [vue({
template: {
compilerOptions: {
// 设置以aui开头的原生DOM为自定义元素
isCustomElement
}
}
})],
}
// https://vite.dev/config/
export default defineConfig(async () => {
// 合并aui配置到vite配置中
return mergeConfig(baseConfig, userConfig)
})
第三步:在项目中使用.aui.vue文件
所有aui组件都需要以.aui.vue文件的格式进行定义,ExampleComp.aui.vue文件:
<template>
<div>
<button>按钮</button>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
onMounted(() => {
console.log('aui组件渲染完毕');
});
defineOptions({
// 如果不想以文件名做组件名,可以显示指定name
name: 'ExampleComp',
})
</script>
<style>
aui-example-comp {
button {
background-color: red;
}
}
</style>组件内容与VUE组件规范一致,但是需要遵循前面提到的规范。
注:如果是在框架内使用,在import一个.aui.vue文件时可能会报错,需要添加类型定义,即在合适的d.ts文件中添加:
// vite-env.d.ts文件内容
/// <reference types="vite/client" />
declare module '*.aui.vue' {
import { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}插件
介绍
AUI组件可通过插件机制对原组件的定义进行修改,或者对组件重新进行定义。
需要注意的是,对组件更新只有在组件创建前有效,请注意时机。
// 引入AUI核心
import { default as auiCore, type Component } from 'agile-core';
组件HOOK
组件hook即对组件内部的行为进行变更,主要通过函数hookStructure(tagName: string, handle: HookHandler): void;实现
其中:
tagName是组件的完整标签名,比如:aui-my-comp
handle是一个函数,用于对组件内部的行为进行变更,函数的参数为组件的定义,返回值为变更后的组件定义,也可以不返回。
比如:
auiCore.hookStructure('aui-example-comp', function (structure: Component) {
const originMounted = structure.mounted;
structure.mounted = function () {
console.log('from hook aui-example-comp');
originMounted?.call(this);
}
console.log('hook aui-example-comp');
});
组件定义
组件定义即对AUI组件进行定义,主要通过函数define(v: Component, force?: boolean): Component;实现。
其中:
v为组件的定义
force为是否强制定义,默认值为false。仅在当组件已经被定义时生效,true则会覆盖定义,false则本次定义无效
比如:
auiCore.define({
name: 'ExampleComp',
props: {
myMsg: {
type: String,
default: ''
}
},
render() {
return h('div', { class: 'container' }, ['这是强制定义的组件', h('div', this.myMsg)]);
}
}, true);
