Vue.js inheritance call parent method

前端 未结 3 1296
生来不讨喜
生来不讨喜 2021-02-05 07:28

is it possible to use method overriding in Vue.js?

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


        
相关标签:
3条回答
  • 2021-02-05 07:50

    No, vue doesn't work with a direct inheritance model. You can't A.extend an component, as far as I know. It's parent-child relationships work mainly through props and events.

    There are however three solutions:

    1. Passing props (parent-child)

    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:

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

    2. Mixins

    If this is common functionality that you want to use in other places, using a mixin might be more idiomatic:

    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)

    // In someComponentB's 'someFunction':
    this.$parent.$options.methods.someFunction(...);
    
    0 讨论(0)
  • 2021-02-05 08:02

    In case someone's interested in a JustWorksTM solution:

    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/


    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).
    2. Further elaboration about the solution (whys and hows): 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).

    How to use Function.prototype.call()

    Reference 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"
    
    0 讨论(0)
  • 2021-02-05 08:03

    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://vuejs.org/v2/api/#extends replaces the usage of Vue.extends()

    0 讨论(0)
提交回复
热议问题