WU / 文档通用微前端
中文
WU FRAMEWORK + WU CLI / 组合

连接的应用.

在 React 中生成命令。Vue 接收事件并观察同一状态。

运行时4.0.0版本与分发 ↗
02 / 状态 · 事件 · 生命周期通信指南 ↗
ReactWU · store + 事件Vue

计数器和事件使用真实的 WU API。 卸载 会释放应用资源,共享状态在本次会话中保留。复制命令后,在自己的终端执行。 wu create 参考 →

从控件到代码

刚使用的两个应用的源码。

了解 store、事件和订阅如何连接

这些片段提取自链接的源码。两个模块注册生命周期时都使用 wu.define 并接收 mount(container, {wu: scoped}): scoped 是该应用的 facade。 COUNTER 是 docs.lab.counter 和 LAST_COMMAND, docs.lab.lastCommand.

React:写入并显示共享值

从 React +1 执行控件处理函数中的这些代码。写入更新共享数据,事件则向检查器添加记录。

const next=(scoped.store.get(COUNTER)??0)+1;
scoped.store.set(COUNTER,next);
scoped.emit('docs:lab:counter',{value:next,source:'React'});

React 首先读取一次,使用 useState ,并连接 store.on ,所在位置为 useLayoutEffect。每次通知都会调用 setCounter。React root 卸载时,effect 清理执行 dispose(). alive 防止更新已移除实例的消息; diagnostics 统计其监听器。

const [counter,setCounter]=useState(()=>scoped.store.get(COUNTER)??0);

useLayoutEffect(()=>{
  alive.current=true;
  const dispose=scoped.store.on(COUNTER,value=>setCounter(value??0));
  diagnostics.listeners+=1;
  return ()=>{alive.current=false;dispose();diagnostics.listeners-=1;};
},[scoped]);

发布到总线 保存命令并发出事件。 result 来自 buildCommand,即此应用的文本生成器; draft 包含表单。

scoped.store.set(LAST_COMMAND,result.command);
const accepted=scoped.emit('docs:lab:command',{command:result.command,framework:draft.framework,operation:draft.operation});
setStatus(accepted?tr("Comando publicado. Runtime Lab recibe el evento."):tr("El host no concedió permiso para publicar el evento."));

Vue:观察、暂停与重新读取

Vue 创建 state ,使用 reactive. connectLeaves() 注册两项 store 订阅和三项总线订阅; track 保存每个取消订阅函数。回调修改 state.counter 和 state.lastCommand; receive 将事件 envelope 转换为历史记录中的一行。

const connectLeaves=()=>{
  if(disposers.length)return;
  try {
    const track=dispose=>{disposers.push(dispose);diagnostics.listeners+=1;};
    track(scoped.store.on(COUNTER,value=>{state.counter=value??0;}));
    track(scoped.store.on(LAST_COMMAND,value=>{state.lastCommand=value??'';}));
    for(const name of ['docs:lab:command','docs:lab:counter','docs:lab:lifecycle'])track(scoped.on(name,receive));
    state.counter=scoped.store.get(COUNTER)??0;state.lastCommand=scoped.store.get(LAST_COMMAND)??'';state.connected=true;sync();
  }catch(error){disconnect();throw error;}
};

store.on 不会自动提供初始值:读取操作 get 在连接时也会取回暂停期间发生的变更。store 通知通过 microtask 到达;写入已经可以通过以下方式读取: get.

暂停订阅 和 unmount 调用 disconnect(),遍历保存的取消订阅函数; sync() 将诊断计数器复制到 Vue 状态。卸载还会移除 DOM 监听器并执行 app.unmount().

disconnect=()=>{
  const pending=disposers;disposers=[];
  for(const dispose of pending){dispose();diagnostics.listeners-=1;diagnostics.cleanups+=1;}
  state.connected=false;sync();
};

连接到自己的界面

选择自己的路径和事件,保留初始读取,并将每个取消订阅函数关联到消费方生命周期。在 manifest 中声明申请,在 shell 中声明 grants: React manifest, Vue manifest 和 如何授予权限。 独立 React 宿主 和 Vue 展示应用注册、初始化和挂载。

本示例中,React 和 Vue 将状态适配到属性 model ,该属性属于 Lit 控件;并接收其 DOM 事件 wu-command-intent 和 wu-runtime-intent。可以阅读 生产方控件、 消费方控件 以及其 共享样式,也可以将相同的 WU 操作连接到自己的控件。源码保留门户项目的 import 和结构。

继续阅读 store 规则与 wildcard 模式 和 事件总线契约.

一起完善 WU

发现了问题?有新的想法?

你的使用体验能让 WU 变得更好。告诉我们遇到的问题,或支持项目的持续开发。