You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript实现普通对象混入类 适配Vue类组件mapState状态混入

实现方案

首先基于Vue基类封装泛型Mixin函数,同时兼顾运行时属性挂载和TS类型推导:

import Vue from 'vue'

/**
 * 接收普通对象,返回继承自Vue的类,实例同时包含Vue原生属性和传入对象的属性
 * @param obj 要混入的属性对象,可直接传入mapState返回的映射结果
 */
function ObjectMixin<T extends Record<string, any>>(obj: T): new () => Vue & T {
  return class extends Vue {
    constructor() {
      super()
      // 遍历属性做挂载适配
      Object.entries(obj).forEach(([key, value]) => {
        // 兼容mapState返回的取值函数,转成实例getter
        if (typeof value === 'function') {
          Object.defineProperty(this, key, {
            get: value.bind(this),
            enumerable: true
          })
          return
        }
        // 普通属性直接赋值
        this[key] = value
      })
    }
  } as any
}

使用示例

和预期的调用方式完全一致,同时支持Vue原生属性和混入属性的类型提示:

class MyComponent extends ObjectMixin(smartModule.mapState(['someState'])) {
  created() {
    // 访问映射状态无类型报错,有正确的类型提示
    console.log(this.someState)
    // Vue 原生属性/方法也可正常访问无报错
    console.log(this.$route, this.$emit)
  }
}

优化说明

  1. 解决了之前实现未继承Vue的问题,生成的类完全符合Vue类组件的继承要求
  2. 类型定义返回Vue & T的实例类型,同时覆盖Vue原生属性和混入对象的属性,无额外类型报错
  3. 兼容mapState返回的取值函数场景,自动转成实例计算属性,运行时取值逻辑符合预期
  4. 仅用一处类型断言替代多处@ts-ignore,写法更规范

注意事项

如果使用Vue3的类组件,只需将基类从Vue替换为vue-facing-decorator导出的基类即可,逻辑无需修改。如果你的smartModule.mapState返回的是普通值对象而非取值函数,可直接删除代码中的函数判断分支,用Object.assign(this, obj)简化赋值逻辑。

内容的提问来源于stack exchange,提问作者Alex l.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:27:03