【问题标题】:Override Vue's mixin methodOverride Vue's mixin method
【发布时间】:2019-11-14 14:19:27
【问题描述】:

有没有办法覆盖本地组件内部调用的一些 npm 的 mixin?

我里面有一个 npm 包组件 node_modules/somePackageName/components/footer.vue 使用另一个来自 node_modules/somePackageName/mixins/popup.js

popup.js 包含以下方法:

methods: {
  setPopupActiveStatus (val, blur = true) {
    const isVisible = false
  }
},

我想从 App.vue 覆盖它的行为,我使用 footer.vue 组件,如下所示:

methods: {
  setPopupActiveStatus (val, blur = true) {
    const isVisible = true
  }
},

但它并没有像我想要的那样工作。

==== 更新 ====

这是我如何根据@Estradiaz 的回答解决我的问题的解释:

【问题讨论】:

  • 你就不能class ExtendedComp extends Original{setPopupActiveStatus (val, blur = true) { //this.super();\n const isVisible = true; }}吗?
  • @Estradiaz - 我认为在没有示例的情况下理解代码的实现对我来说是一个高级别的 JS。
  • aspirinemaga,您能否使用codesandbox 或对您的问题进行更多描述来获取示例?
  • @aspirinemaga 我的错,我在打字稿领域做得很多 - 但基本想法就像 vuejs.org/v2/api/#Vue-extendVue.extend(OriginalCompOption).extend(changes)OriginalComp.extend(changes) 实际上取决于 footer.vue 中的导出与ClonedOriginalComp.mixins.push(changes) 相同

标签: javascript vue.js


【解决方案1】:

combining mixin & component options:

当 mixin 和组件本身包含重叠选项时,它们将使用适当的策略“合并”:

  • 数据对象进行递归合并,在发生冲突时组件的数据优先。

  • 钩子函数将同名的函数合并到一个数组中,这样所有的函数都会被调用。 Mixin 钩子会在组件自己的钩子之前被调用。

  • 方法组件指令将合并到同一个对象中。当这些对象中存在冲突的键时,组件的选项将优先。

这是一个由组件和 mixin 提供的方法的示例:

var mixin = {
  methods: {
    foo: function () {
      console.log('Mixin Msg')
    },
  }
}

var vm = new Vue({
  mixins: [mixin],
  methods: {
    foo: function () {
      console.log('Component Msg')
    },
  }
})

vm.foo() // => "Component Msg"

这是example in codesandbox

所以我相信你应该能够简单地通过在组件上提供一个具有相同名称的方法来“覆盖”mixin,并且它会优先

【讨论】:

  • 这就是我所做的,我尝试通过简单地在调用者的方法中重新定义具有相同名称的方法来覆盖 mixins 方法。与您的示例相同,但它所做的只是用组件内新定义的方法调用旧的 mixin 方法,而不是替换它。
【解决方案2】:

Vue 扩展的地方

所以基本上你想要做的是通过自定义方法扩展你当前的组件。 这可以通过Vue.extend 完成。 Vue 通过将一个组件分配给extends 选项,提供了一个无忧克隆/扩展组件的选项:

Option/ Composition - extends

import SourceComponent from 'node_modules/somePackageName/components/footer.vue'
export default {
   name: "override",
   extends: SourceComponent,
   methods: {
      thatActualMethodBehaviour(){}
   }
} 

Vue.extend

// can be  Function | Object
import SourceComponent from 'node_modules/somePackageName/components/footer.vue'
if(typeof SourceComponent === 'function'){
  export default SourceComponent.extend({
      methods: {thatActualMethodBehaviour(){}}
  })
} else {
  export default Vue.extend(SourceComponent).extend({
      methods: {thatActualMethodBehaviour(){}}
  })  
}

Option/ Composition - mixins

// must be Object
import SourceComponentOption from 'node_modules/somePackageName/components/footer.vue'
if(typeof SourceComponent !== 'function'){
  export default Vue.extend({
      mixins: [SourceComponentOption],
      methods: {thatActualMethodBehaviour(){}}
  })
}

-Y U DO DIS ?!?? - 路径

import SourceComponentOption from 'node_modules/somePackageName/components/footer.vue'
export default Object.assign({}, SourceComponentOption, {methods: Object.assign({}, SourceComponentOption.methods, {thatActualMethodBehaviour: function(){}}))

打字稿:vue-property-decorator

import {Vue, Component} from 'vue-property-decorator'
import SourceComponent from 'node_modules/somePackageName/components/footer.vue'
@Component<CustomComponent>({...hooks})
export default class CustomComponent extends SourceComponent{
   methods: thatActualMethodBehaviour(){}
}

【讨论】:

  • 感谢您的帮助!第一个解决方案,vuejs.org/v2/api/#extends 方法帮助我解决了问题。我的理解是,如果你想覆盖一个mixin,你应该在调用者组件中进行,所以我必须克隆一个footer.vue,然后克隆popup.vue,其中popup.js被调用。
  • @aspirinemaga 不客气,___ 我不确定我是否理解 "footer.vue 和 popup.vue where popup.js where called" 但要 @987654336 @ && name.js 感觉有点多余
  • 请在 UPDATED 部分后查看我的问题帖子以获得更好的解释。
猜你喜欢
  • 2018-08-02
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
相关资源
最近更新 更多