kingdee-cosmic-clikingdee-cosmic-cli
首页
指南
  • 金蝶云苍穹社区
  • 资源市集
  • KDesign
  • CHATUI X
作者博客
首页
指南
  • 金蝶云苍穹社区
  • 资源市集
  • KDesign
  • CHATUI X
作者博客
  • 起步
    • 介绍
    • 安装与创建
    • 卸载与升级
  • 全局配置
  • 开发事项
    • 介绍
    • 苍穹预览模式
    • RAM模式
  • 生产与产物分析事项
  • 资源拉取策略分析
  • 数据请求策略
    • 策略设计
    • Mock服务
  • React18 起步工程
    • 介绍
    • 接口请求书写
    • 状态管理
    • 国际化
  • Vue3 起步工程
    • 介绍
    • 接口请求书写
    • 状态管理
    • 国际化
  • 主题色切换
  • 图标方案
  • 规范与温馨提示
    • Eslint
    • 工程与编码规范
    • 温馨提示
  • 未来计划与感谢 📅

背景

使用 composition-api 的 ref 简单做了个状态管理类 (src/utils/store.ts),这是为了解决 update 数据推送监听的问题。

状态管理实例化方式

因为前面提到过的变量隔离问题,所以状态管理必须也在类的声明中实例化。

import { ModelType, ReturnDataType } from "./types/model";
import appConfig from "../app.config";
import changeTheme from "@utils/change-theme";
import { createApp } from "vue";
import StateManager from "@utils/store";
const { APP_NAME } = appConfig;
// 创建一个全局变量来存储root
const inCosmic = window.KDApi !== undefined; // 是否在苍穹环境中

declare global {
  interface Window {
    KDApi: KDApiType;
  }
}
type KDApiType = {
  register: (a: string, b: typeof InitComponent) => void;
};

export class InitComponent {
  model: ModelType;
  store: any;
  constructor(model: ModelType) {
    this.model = model;
    const that = this;
    import("./App.vue").then((AppModule) => {
      const AppGlobal = AppModule.default;
      const App = createApp(AppGlobal);
      that.store = new StateManager(); // 必须在类中new才能做到变量隔离
      App.config.globalProperties.$stateManager = that.store;
      App.provide("model", model);
      App.provide("store", that.store);
      if (inCosmic) {
        App.mount(this.model.dom as HTMLElement);
      } else {
        // ram模式下没有window.KDApi
        App.mount("#app");
      }
      changeTheme(); // 主题色初始化
    });
  }
  init(props: ReturnDataType) {
    console.log("-----init", this.model, props);
    this.store && this.store.triggerAction("setAjaxData", props);
  }
  update(props: ReturnDataType) {
    console.log("-----update", this.model, props);
    this.store && this.store.triggerAction("setAjaxData", props);
  }
  destoryed() {
    console.log("-----destroyed", this.model);
  }
}

const init = (KDApi: KDApiType) => {
  KDApi.register(APP_NAME, InitComponent);
};

// 初始化应用程序
if (inCosmic) {
  init(window.KDApi);
} else {
  // ...
}

使用

幸运的是,由于 Vue 的设计,让我们可以在组件和 .ts 文件中都能访问到 store 的实例,所以都可以访问到状态和方法。

import { watch, getCurrentInstance } from "vue";

export default function useInvokeAsync() {
  const instance = getCurrentInstance();
  const proxy = instance?.proxy as any;
  const state = proxy.$stateManager?.getState();
  watch(state, () => {
    console.log("update触发了", state);
  });
}

当然你也可以把这个简单的 store 换成 Pinia。

最近更新:: 2024/5/29 13:55
Contributors: 庞囧
Prev
接口请求书写
Next
国际化