我正在尝试构建一个基础DataComponent
,它将包含处理基本CRUD实体的许多其他组件所需的通用功能。
到目前为止我已经
//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;
}
}
});
&#13;
//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.
}
}
});
&#13;
How to achieve method inheritance as I am trying to do? Is it possible in Vue.js?
修改
如果我将data-component.js中方法的签名更改为,将继承组件的实例(&#34; this&#34;)作为vm传递,则可以正常工作
//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;
}
}
});
&#13;
然后在继承组件
中
//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
}
}
});
&#13;
将实例(&#34; this&#34;)作为vm传递给方法,它按预期工作。
我不确定这是否是最好的方法。但那肯定不是遗产 如何使用继承来实现我想要做的事情?
答案 0 :(得分:11)
您应该使用Mixins为多个(或所有)组件添加常用功能:https://vuejs.org/guide/mixins.html
这将允许您向任何或所有组件添加相同的功能,因此您可以自动将this.foobar()
添加到组件中。
如果要在不污染组件命名空间的情况下为所有组件添加功能,可以使用自定义插件:https://vuejs.org/guide/plugins.html
这将允许您为所有组件添加服务,以便您可以在this.$service.foobar()
之外的任何地方使用它。
如果您想使用CRUD功能,则应使用VueResource
创建资源:https://github.com/vuejs/vue-resource/blob/master/docs/resource.md
这样您就可以使用FoobarService.create({foo: 'bar'})
或FoobarService.delete({id: 1})
编辑:要创建一个插件,它看起来像这样:
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);