我试图在Vue.js中创建一个简单的插件来包装vue-resource
插件以跟踪请求的状态。
function State() {}
State.prototype.post = function (ctx, name, url, data, successCB, errorCB) {
var options = {};
if (errorCB) {
options.error = function (resp) {
ctx[name] = 'error';
return errorCB(resp);
};
}
ctx[name] = 'sending';
ctx.$http.post(url, data, function (res, code, req) {
ctx[name] = 'sent';
return successCB(res, code, req);
}, options);
};
function install(Vue) {
Object.defineProperties(Vue.prototype, {
$state: {
get: function () {
return new State;
// return Vue.state.bind({$vm: this});
}
}
});
}
module.exports = install;
您会看到我从调用的Vue传递ctx
上下文,以便访问它的data
值。我在vue-resource
插件中看到有一种方法可以通过插件自动绑定它,这样就可以使语法正确。
基本上我想避免每次都要传递ctx
上下文,它应该只有适当的上下文。
修改
澄清我正在寻找一种能够通过适当语境的解决方案。上面只是一个例子,我没有寻找跟踪状态的解决方案。
例如,如果我们发出任何http请求,请在vue-resource
插件中。
this.$http.get('/some/url', {}, function () {
this.func();
console.log(this.var);
});
回调中已存在上下文。我不需要做某种var _this = this
来进入视图范围。我想为我的插件实现相同的目的,以便正确的this
就在那里。我试图从vue-resource
插件中弄清楚它,但是很难跟踪所有代码。
答案 0 :(得分:3)
将我的评论扩展为答案 -
因此,您的Vue组件上有name
属性,并且您希望此插件在HTTP请求进行时更新该值?我认为这会给你一个糟糕的责任链。您的Vue实例需要具有name
属性,并且您的插件不会是独立的。
最好让插件自己处理所有状态跟踪。您可以创建名为status
的State属性,该属性随着请求的进行而更新。然后,您可以使用this.$state.status
了解当前状态。然后插件负责它的目的,组件保持独立
State.prototype.status = "not sent";
State.prototype.post = function (url, data, successCB, errorCB) {
var options = {};
if (errorCB) {
options.error = function (resp) {
this.status = 'error';
return errorCB(resp);
};
}
this.status = 'sending';
this.Vue.http.post(url, data, function (res, code, req) {
this.status = 'sent';
return successCB(res, code, req);
}, options);
};
function install(Vue) {
Object.defineProperties(Vue.prototype, {
$state: {
get: function () {
var state = new State;
state.Vue = Vue;
return state;
}
}
});
}
然后在html:
<div v-if="$state.status == 'sending'">Sending...</div>
<div v-if="$state.status == 'sent'">Sent!</div>
<div v-if="$state.status == 'error'">Error!</div>
如果您确实想按照自己的方式行事,我认为您每次都需要在Vue组件中绑定this
到post()
:
this.$state.post(args){
}.bind(this)
所以在post
函数this
中你的Vue就是。我认为第一种方式是最好的
编辑 -
函数successCb
和errorCb
已经在Vue组件的范围内运行,因为您在那里定义了它们。您所处情况的vue-resource
回调的范围为State
,因为您在此处定义了这些回调,除非您按照惯例传递上下文,否则不会发生变化。但这里的要点是你的插件不需要知道组件的上下文,就像vue-resource
永远不知道组件的上下文一样。它只获取数据,发送请求并运行回调。从不了解调用组件。
因此,在您作为回调发送给this.$state.post
的功能中,您可以使用this.var
- 编辑您的Vue数据,因为您应该。在您从状态发送到Vue.http.post
的回调中,您可以编辑State
对象的属性 - 再次预期的行为。您需要将name
或status
变量作为State
的一部分,然后在Vue组件中将其引用为this.$state.name
以检查状态。
编辑2:
您甚至可以拥有变量$state.response
并传递myCustomVar
,然后跟踪$state.response.myCustomVar
。这样,您可以在每个请求上传递不同的自定义变量并单独跟踪它们
答案 1 :(得分:1)
我最终对此进行了整理,这比我想象的要容易。
这只是$http
中vue-router
方法的简单快捷包装,因此可以这样调用:
this.$state.get('/buildings', data, function (resp) {
this.buildings = resp.data;
}, {
track: 'getBuildingState'
});
或者
this.$state('/buildings', {
data: data,
track: 'getBuildingState',
success: function (resp) {
this.buildings = resp.data;
}
});
可以查看Gihub上的代码段here