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
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 } })
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