zoukankan      html  css  js  c++  java
  • Vue 在 typeScript 中写mixins。

    前言

    有个项目,需要使用 mixins 来管理一些通用方法。同时该项目使用 Typescript。

    问题

    编译器报错,提示组件中没有该 mixin 中的内容。具体看一下代码。

    MixinA:

    export const MixinA = {
        method: {
            sayHello() {
                // ...
            }
        }
    }
    

    component:

    export default Vue.extend({
        mixins: [MixinA],
        create() {
            this.sayHello();   // <- 报错位置.
        }
    })
    

    报错:

    Property 'sayHello' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.Vetur(2339)
    

    根据报错信息,可以看到是 Vetur 这个插件报的错。
    究其原因,还是因为 TypeScript 不够聪明,没法知道 Mixin 到底是什么样的。

    解决方案

    这里有许许多多种,我收集整理一下。

    1. 简单粗暴法 (as 强制转换) 极度不推荐

      跟着上面的内容:

      (this as any).sayHello();
      

      报错消失,但是这样会让代码很脏,组件阅读性差的同时,还要写很多 as 转换,同时,转换 any 让 typeScript 的意义荡然无存,还不如不用。

    2. 继承 mixins (只适合当个 mixin)

      mixinA:

      export const MixinA = Vue.extend({
          method: {
              sayHello() {
                  // ...
              }
          }
      })
      

      components:

      export default MixinA.extend({
          mixins: [MixinA],
          create() {
              this.sayHello();
          }
      })
      

      也不报错了,通过继承 mixinA 的方式,让编译器知道里面有什么东西。

      缺点:违背 mixins 的设计初衷,mixins 本身就支持多 mixin 混入。

      优点:简单粗暴。

    3. 使用 vue-typed-mixins

      import Vue from 'vue'
      import mixins from 'vue-typed-mixins'
      
      const mixinsA = Vue.extend({
      data() {
          return {
          foo: 'test'
          }
      }
      })
      
      const mixinsB = Vue.extend({
      data() {
          return {
          bar: 123
          }
      }
      })
      
      const App = mixins(mixinsA, mixinsB).extend({
      data() {
          return {
          value: true
          }
      },
      
      computed: {
          concat(): string {
          return `${this.foo} ${this.bar} ${this.value}`
          }
      }
      })
      

      优点:可以混合,多个 mixin
      缺点:使用习惯的修改。 还是比较支持的。

    4. 升级为 Vue3。
      Vue 官方在 3 后,有为 mixin 做的处理。(具体没有了解过,虽然很吐槽这种升级的方式)

    5. 遵循 Vue 和 TS 原则的一种解决方式.

      mixinA :

      
      // mixinA.vue
      导出默认 Vue.extend({…})
      

      mixinB:

      // mixinB.vue
      导出默认 Vue.extend({…})
      

      那么使用这两个的组件可以定义为:

      export default (Vue as VueConstructor<Vue & InstanceType<typeof MixinA>& InstanceType<typeof
      MixinB>>).extend({
      mixins: [MixinA, MixinB],
      
      
    6. 自己写接口

      interface mixinState {
      sayHello: () => {}
      }
      
      export default (Vue as VueConstructor<Vue & mixinState>).extend({
      name: 'Home',
      create() {
          this.sayHello();
      }
      })
      
      

      本质上与 第 5 种 是一样的。
      缺点:要写许多接口。

    7. 使用 vue-property-decorator 等。

      使用类型注解的方式。没研究,不喜欢这种写法。

    以梦为马
  • 相关阅读:
    Photoshop
    你会为了钱出售自己的个人资料吗?
    [ElasticSearch] 空间搜索 (一)
    hdu1584 A strange lift (电梯最短路径问题)
    Android API Guides---OpenGL ES
    Qt 推断一个IP地址是否有效
    bzoj1670【Usaco2006 Oct】Building the Moat 护城河的挖掘
    集成学习1-Boosting
    微信开发模式之自己定义菜单实现
    人件札记:开放式的办公室环境
  • 原文地址:https://www.cnblogs.com/lsAxy/p/14914053.html
Copyright © 2011-2022 走看看