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:
- 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).
- Más detalles sobre la solución (por qué y cómo): https://github.com/vuejs/vue/issues/2977
- 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()