A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/vuejs/vue-class-component/issues/291 below:

When Vue has some other global mixins, 'mixins' helper could be dangerous · Issue #291 · vuejs/vue-class-component · GitHub

I have added a minimal demo in test/test.ts

it('mixins should be safe with VueContructor and global mixins', function () {
    let counter = 0
    /**
     * dangerous global mixin
     */
    Vue.mixin({
        created() {
          counter++
        }
    })
    @Component
    class MixinA extends Vue {
    }
    @Component
    class MixinB extends Vue {
    }
    @Component
    class MyComp extends mixins(MixinA, MixinB) {
      test() {}
    }
    const vm = new MyComp()
    vm.test() // just to avoid 'noUnusedLocals' error
    expect(counter).to.equal(1)  // error, actual 3
})

Global mixin is very common in Vue plugins and real-world projects. With current implementation of 'mixins' helper( or of Vue.extend({ mixins: VueConstructor<any>[] })), there might be some subtle unexpected results.

For example, I have found a vue-i18n caused memory leak in work project

src/mixin.js

Vue.mixin({
    beforeCreate (): void {
      // .... in short ...
      const options: any = this.$options
      options.i18n = options.i18n || (options.__i18n ? {} : null)
      this._i18n = options.i18n || (options.__i18n ? {} : null)

      this._i18n.subscribeDataChanging(this)
    },

    beforeDestroy (): void {
      if (!this._i18n) { return }

      if (this._subscribing) {
        // if two 'beforeCreate' hooks has been added to options, there will be two vm pushed to listener array by '_i18n.subscribeDataChanging'
        // but here, only one '_i18n._i18n.unsubscribeDataChanging' will be called
        // so there is a leak
        this._i18n.unsubscribeDataChanging(this)
      }
      // ...
      this._i18n = null
    }
})

src/index.js

class VueI18n {
  // ...
  subscribeDataChanging (vm: any): void {
    this._dataListeners.push(vm)
  }

  unsubscribeDataChanging (vm: any): void {
    // will only remove the first 'vm' in 'this._dataListeners'
    remove(this._dataListeners, vm)
  }
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4