2016-06-28 14 views
6

Sto provando a creare una base DataComponent che conterrà la funzionalità comune richiesta per molti altri componenti che si occupano di entità CRUD di base.
Finora hoEreditarietà componente con vue js

//main.js 
 
import Vue from 'vue'; 
 

 
new Vue({ 
 
    el:'#app', 
 
    components:{ 
 
    DataComponent, 
 
    Quotation 
 
    } 
 
});

//data-component.js 
 
import Vue from 'vue'; 
 

 
export 
 
default Vue.extend({ 
 

 
     data() { 
 
      return { 
 
      saved: false 
 
      } 
 
     }, 
 

 
     methods: { 
 

 
      //This method will be used by all inheriting components to alert 
 
      //the user regarding any changes which need to be saved. 
 
      
 
      alertSave(entity, fields, intFields) { 
 
       var changeCount = 0; 
 
       fields.forEach(function(field) { 
 
       
 
       var compareWith = this[field]; 
 
       
 
       //Here "this" need to refer to the child instance but it does not 
 
       //how can I achieve? 
 
       
 
       if ((compareWith || entity[field.camelToSnake()]) && 
 
        entity[field.camelToSnake()] !== compareWith) { 
 
        changeCount++; 
 
       } 
 
       }); 
 
       intFields.forEach(function(field) { 
 
       var compareWith = parseInt(this[field]); 
 
       if ((compareWith || entity[field.camelToSnake()]) && 
 
        entity[field.camelToSnake()] !== compareWith) { 
 
        changeCount++; 
 
       } 
 
       }); 
 
       vm.saved = changeCount <= 0; 
 
      }, 
 
      
 
      //sanitizeValue method works as intended as it does not have any reference to "this" 
 
      
 
      sanitizeValue(value) { 
 
       if (value) { 
 
       return String(value).trim(); 
 
       } else { 
 
       return null; 
 
       } 
 
      }, 
 
      
 
      //In getDbData method also this needs to refer to the inheriting child instance 
 
      //from where this method is called - how can I achieve it? 
 
      
 
      getDbData(entity) { 
 
       if (entity) { 
 
       this.dbTextFields.forEach(function(field) { 
 
        this[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       this.dbIntFields.forEach(function(field) { 
 
        this[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       this.dbObjFields.forEach(function(field) { 
 
        this[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       this.dbAppendedFields.forEach(function(field) { 
 
        this[field] = entity[field.camelToSnake()] 
 
       }); 
 
       this.saved = true; 
 

 
       } 
 
      } 
 
     });

//quotation.js 
 

 
import DataComponent from './data-component'; 
 

 
export default DataComponent.extend({ 
 
    
 
    data(){ 
 
    return{ 
 
     id:0, 
 
     date:'', 
 
     remarks:'', 
 
     terms:'', 
 
     quote:{}, 
 
     dbTextFields:['to', 'org', 'address', 'items', 'description', 'quoted_by'], 
 
     dbIntFields:['quote_ref', 'quantity', 'amount', 'discount', 'total'], 
 
     dbObjFields:['inquiry', 'booking'] 
 
    } 
 
    }, 
 
    
 
    methods:{ 
 
    setDbData(){ 
 
     let entity = this.quote; 
 
     this.getDbData(entity); 
 
     
 
     //getDbData gives error as "this" in getDbData does not refer to this 
 
     // child component and so this.dbTextFields becomes undefined. 
 
     
 
    } 
 
    } 
 
    
 
});

How to achieve method inheritance as I am trying to do? Is it possible in Vue.js? 

Modifica

Se cambio la firma del metodo in data-Component.js come sotto, passando l'istanza di ereditare componente ("questo") come vm, funziona

//data-component.js 
 
import Vue from 'vue'; 
 

 
export 
 
default Vue.extend({ 
 

 
     data() { 
 
      return { 
 
      saved: false 
 
      } 
 
     }, 
 

 
     methods: { 
 

 
      //This method will be used by all inheriting components to alert 
 
      //the user regarding any changes which need to be saved. 
 
      
 
      alertSave(entity, fields, intFields, vm) { 
 
       var changeCount = 0; 
 
       fields.forEach(function(field) { 
 
       //var compareWith = this[field]; 
 
       var compareWith = vm[field]; 
 
       
 
       //Changed "this" to vm (passed as a parameter) 
 
       //how can I achieve? 
 
       
 
       if ((compareWith || entity[field.camelToSnake()]) && 
 
        entity[field.camelToSnake()] !== compareWith) { 
 
        changeCount++; 
 
       } 
 
       }); 
 
       intFields.forEach(function(field) { 
 
       //var compareWith = parseInt(this[field]); 
 
       var compareWith = parseInt(vm[field]); 
 
       if ((compareWith || entity[field.camelToSnake()]) && 
 
        entity[field.camelToSnake()] !== compareWith) { 
 
        changeCount++; 
 
       } 
 
       }); 
 
       vm.saved = changeCount <= 0; 
 
      }, 
 
      
 
      //sanitizeValue method works as intended as it does not have any reference to "this" 
 
      
 
      sanitizeValue(value) { 
 
       if (value) { 
 
       return String(value).trim(); 
 
       } else { 
 
       return null; 
 
       } 
 
      }, 
 
      
 
      //In getDbData method also this needs to refer to the inheriting child instance 
 
      //from where this method is called - how can I achieve it? 
 
      
 
      getDbData(entity, vm) { //instance as "vm" parameter 
 
      //change all this to vm 
 
       if (entity) { 
 
       vm.dbTextFields.forEach(function(field) { 
 
        vm[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       vm.dbIntFields.forEach(function(field) { 
 
        vm[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       vm.dbObjFields.forEach(function(field) { 
 
        vm[field] = entity[field.camelToSnake()]; 
 
       }); 
 
       vm.dbAppendedFields.forEach(function(field) { 
 
        vm[field] = entity[field.camelToSnake()] 
 
       }); 
 
       vm.saved = true; 
 

 
       } 
 
      } 
 
     });

E poi nel componente ereditare

//quotation.js 
 

 
import DataComponent from './data-component'; 
 

 
export default DataComponent.extend({ 
 
    
 
    data(){ 
 
    return{ 
 
     id:0, 
 
     date:'', 
 
     remarks:'', 
 
     terms:'', 
 
     quote:{}, 
 
     dbTextFields:['to', 'org', 'address', 'items', 'description', 'quoted_by'], 
 
     dbIntFields:['quote_ref', 'quantity', 'amount', 'discount', 'total'], 
 
     dbObjFields:['inquiry', 'booking'] 
 
    } 
 
    }, 
 
    
 
    methods:{ 
 
    setDbData(){ 
 
     let entity = this.quote; 
 
     this.getDbData(entity, this); 
 
     
 
     //passing this (instance) as a parameter 
 
     
 
     
 
    } 
 
    } 
 
    
 
});

Passando l'istanza ("questo") per i metodi di vm, funziona come previsto.

Non sono sicuro se questo è il modo migliore per farlo. Ma sicuramente non è eredità.
Come utilizzare l'ereditarietà per ottenere ciò che sto cercando di fare?

risposta

7

Si dovrebbe usare mixin per aggiungere funzionalità comuni a più (o tutti i) componenti: https://vuejs.org/guide/mixins.html

Questo vi permetterà di aggiungere le stesse funzioni a qualunque o tutti i componenti, in modo da poter aggiungere automaticamente this.foobar() a i tuoi componenti.

Se si desidera aggiungere funzionalità a tutti i componenti senza inquinare lo spazio dei nomi dei componenti, è possibile utilizzare un plugin personalizzato: https://vuejs.org/guide/plugins.html

Questo vi permetterà di aggiungere un servizio per tutti i componenti in modo da poter utilizzare ovunque come this.$service.foobar().

Se si desidera lavorare con la funzionalità CRUD, si dovrebbe creare una risorsa utilizzando VueResource: https://github.com/vuejs/vue-resource/blob/master/docs/resource.md

Questo vi permetterà di creare facilmente/cancellare/modificare le risorse utilizzando FoobarService.create({foo: 'bar'}) o FoobarService.delete({id: 1})

Edit: per creare un plug-in, sarà simile a questa:

var MyPlugin = {}; 

MyPlugin.install = function (Vue, options) { 

    var service = { 
    foo: function(bar) { 
     //do something 
    } 
    } 

    Vue.prototype.$service = service; 
} 

Vue.use(MyPlugin); //this runs the install function 

//Then when you have any Vue instance 
this.$service.foo(bar); 
+0

Potete per favore elaborare un po 'su come posso avvicinarmi a scrivere un plug-in per il mio requisito?Non riesco a capire dalle informazioni sul link del plugin. L'esempio mostrato fornisce tre opzioni, metodi globali, direttive e metodo di istanza. Non riesco a capire dove dovrei inserire i miei metodi nella definizione del plugin in modo che possa quindi usarlo nei componenti come 'this. $ Service.method()'. Puoi indicarmi qualche risorsa in cui posso trovare istruzioni dettagliate o un esempio di "Hello World" su come scrivere un plugin? Si prega di – Donkarnash

+0

vedere modifica @Donkarnash – Jeff

+0

Grazie mille @Jeff per aver preso interesse e risparmiando tempo per aiutarmi e fornire il codice del plugin. Grazie ancora. – Donkarnash