Saltar al contenido

Método padre de llamada de herencia de vue.js

Solución:

No, vue no funciona con un modelo de herencia directa. No puedes A.extend un componente, hasta donde yo sé. Las relaciones entre padres e hijos funcionan principalmente a través de accesorios y eventos.

Sin embargo, existen tres soluciones:

1. Pasar accesorios (padre-hijo)

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

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

y en la plantilla de SomeComponentA:

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

2. Mixins

Si esta es una funcionalidad común que desea usar en otros lugares, usar un mixin podría ser más idiomático:

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. Llamar apoyos para padres (padre-hijo, feo)

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

En caso de que alguien esté interesado en una solución 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/


Más información:

  1. Esta solución es para desarrolladores que no pueden usar TypeScript por alguna razón (lo que creo que permite definir componentes vue como clases, lo que a su vez permite un conjunto completo de características de herencia).
  2. Más detalles sobre la solución (por qué y cómo): https://github.com/vuejs/vue/issues/2977
  3. Esto no es tan feo, considerando que aquí no se usa ciencia espacial (llamar a funciones anónimas con el this puntero reemplazado no debería ser mágico para cualquier desarrollador js decente).

Cómo utilizar Function.prototype.call()

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

Código de muestra:

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"

En caso de que alguien pida una solución, aquí es mía y funciona bien:

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
        },
    },
};

usando juste extends de https://vuejs.org/v2/api/#extends reemplaza el uso de Vue.extends()

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *