简体   繁体   English

Vue.js 继承调用父方法

[英]Vue.js inheritance call parent method

Is it possible to use method overriding in Vue.js?是否可以在 Vue.js 中使用方法覆盖?

var SomeClassA = Vue.extend({
  methods: {
    someFunction: function() {
      // ClassA some stuff
    }
  }
});

var SomeClassB = SomeClassA.extend({
  methods: {
    someFunction: function() {
      // CALL SomeClassA.someFunction
    }
  }
});

I want to call ClassA someFunction from ClassB someFunction.我想从 ClassB someFunction 中调用 ClassA someFunction。 Is it even possible?甚至可能吗?

No, vue doesn't work with a direct inheritance model.不,vue 不适用于直接继承模型。 You can't A.extend an component, as far as I know.据我所知,您不能A.extend组件。 It's parent-child relationships work mainly through props and events.它的父子关系主要通过道具和事件起作用。

There are however three solutions:但是有三种解决方案:

1. Passing props (parent-child) 1.传递道具(亲子)

var SomeComponentA = Vue.extend({
    methods: {
        someFunction: function () {
            // ClassA some stuff
        }
    }
});

var SomeComponentB = Vue.extend({
   props: [ 'someFunctionParent' ],
   methods: {
       someFunction: function () {
           // Do your stuff
           this.someFunctionParent();
       }
   }
});

and in the template of SomeComponentA:在 SomeComponentA 的模板中:

<some-component-b someFunctionParent="someFunction"></some-component-b>

2. Mixins 2. 混合

If this is common functionality that you want to use in other places, using a mixin might be more idiomatic:如果这是您想在其他地方使用的常见功能,则使用 mixin 可能更惯用:

var mixin = {
    methods: {
        someFunction: function() {
            // ...
        }
    }
};

var SomeComponentA = Vue.extend({
    mixins: [ mixin ],
    methods: {
    }
});

var SomeComponentB = Vue.extend({
   methods: {
       someFunctionExtended: function () {
           // Do your stuff
           this.someFunction();
       }
   }
});

3. Calling parent props (parent-child, ugly) 3.调用parent props(父子,丑)

// In someComponentB's 'someFunction':
this.$parent.$options.methods.someFunction(...);

In case someone's interested in a JustWorksTM solution:如果有人对 JustWorksTM 解决方案感兴趣:

var FooComponent = {
  template: '<button @click="fooMethod()" v-text="buttonLabel"></button>',

  data: function () {
   return {
     foo: 1,
     bar: 'lorem',
     buttonLabel: 'Click me',
   }
  },

  methods: {
    fooMethod: function () {
      alert('called from FooComponent');
    },
    
    barMethod: function () {
      alert('called from FooComponent');
    },
  }
}

var FooComponentSpecialised = {
  extends: FooComponent,

  data: function () {
   return {
     buttonLabel: 'Specialised click me',
     zar: 'ipsum',
   }
  },

  methods: {
    fooMethod: function () {
      FooComponent.methods.fooMethod.call(this);
    
      alert('called from FooComponentSpecialised');
    },
  }
}

jsfiddle: https://jsfiddle.net/7b3tx0aw/2/ jsfiddle: https ://jsfiddle.net/7b3tx0aw/2/


More info:更多信息:

  1. This solution is for devs that can't use TypeScript for some reason (which I think allows defining vue components as classes, which in turn allows full inheritance feature-set).此解决方案适用于由于某种原因无法使用 TypeScript 的开发人员(我认为这允许将 vue 组件定义为类,这反过来又允许完整的继承功能集)。
  2. Further elaboration about the solution (whys and hows): https://github.com/vuejs/vue/issues/2977关于解决方案的进一步阐述(为什么和如何): https ://github.com/vuejs/vue/issues/2977
  3. This ain't that ugly, considering that no rocket science is used here (calling anonymous functions with the this pointer replaced should be no magic for any decent js dev).考虑到这里没有使用火箭科学,这并没有那么难看(调用匿名函数并替换this指针对于任何体面的 js 开发人员来说都不是魔法)。

How to use Function.prototype.call()如何使用Function.prototype.call()

Reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

Sample code:示例代码:

function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);
// expected output: "cheese"

In case someone asks for a solution here is mine and works fine :如果有人在这里寻求解决方案,这是我的并且工作正常:

var SomeClassA = {
    methods: {
        someFunction: function () {
            this.defaultSomeFunction();
        },
        // defaultSomeFunction acts like parent.someFunction() so call it in inheritance
        defaultSomeFunction: function () {
            // ClassA some stuff
        },
    },
};

var SomeClassB = {
    extends: SomeClassA,
    methods: {
        someFunction: function () {
            // Replace the wanted SomeClassA::someFunction()
            this.defaultSomeFunction();
            // Add custom code here
        },
    },
};

using juste extends from https://v2.vuejs.org/v2/api/#extends replaces the usage of Vue.extends()使用https://v2.vuejs.org/v2/api/#extends的 juste extends替换Vue.extends()的使用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM