Vue.js 插件中的绑定上下文?
Vue.js binding context in plugin?
我正在尝试在 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
插件有一种方法可以通过插件自动绑定它 bat 不能完全正确地获得语法。
基本上我想避免每次都必须传递 ctx
上下文,它应该已经有了正确的上下文。
编辑
澄清一下,我正在寻找一种解决方案来传递适当的上下文。以上只是一个示例,我并不是在寻找一种跟踪状态的解决方案。
例如在 vue-resource
插件中,如果我们发出任何 http 请求。
this.$http.get('/some/url', {}, function () {
this.func();
console.log(this.var);
});
上下文已经在回调中。我不需要做某种 var _this = this
来进入视图范围。我想为我的插件实现相同的目的,以便正确的 this
就在那里。我试图从 vue-resource
插件中找出答案,但很难理解所有代码。
将我的评论扩展到答案 -
所以你的 Vue 组件上有一个 name
属性,你希望这个插件随着 HTTP 请求的进行更新那个值?我认为这会给你带来糟糕的责任链。您的 Vue 实例将需要有一个 name
属性,并且您的插件不会是独立的。
最好让插件自行处理所有状态跟踪。您可以创建一个名为 status
的 属性 状态,它会随着请求的进行而更新。然后你可以使用 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
永远不知道组件的上下文一样。它只是获取数据,发送请求,然后 运行s 回调。对调用组件一无所知。
因此,在您作为回调发送至 this.$state.post
的函数中,您可以使用 this.var
- 编辑您的 Vue 数据,正如您应该能够 那样。在您从您的州发送到 Vue.http.post
的回调中,您可以编辑 State
对象的属性 - 同样,这是预期的行为。您需要使 name
或 status
变量成为 State
的一部分,然后在您的 Vue 组件中将其引用为 this.$state.name
以检查状态。
编辑 2:
你甚至可以有一个变量 $state.response
并传入 myCustomVar
,然后跟踪 $state.response.myCustomVar
。这样你就可以在每个请求中传递不同的自定义变量并独立跟踪它们
我最终解决了这个问题,它比我想象的要容易。
它只是 vue-router
中 $http
方法的一个简单快捷方式包装器,因此可以像这样进行调用:
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
我正在尝试在 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
插件有一种方法可以通过插件自动绑定它 bat 不能完全正确地获得语法。
基本上我想避免每次都必须传递 ctx
上下文,它应该已经有了正确的上下文。
编辑
澄清一下,我正在寻找一种解决方案来传递适当的上下文。以上只是一个示例,我并不是在寻找一种跟踪状态的解决方案。
例如在 vue-resource
插件中,如果我们发出任何 http 请求。
this.$http.get('/some/url', {}, function () {
this.func();
console.log(this.var);
});
上下文已经在回调中。我不需要做某种 var _this = this
来进入视图范围。我想为我的插件实现相同的目的,以便正确的 this
就在那里。我试图从 vue-resource
插件中找出答案,但很难理解所有代码。
将我的评论扩展到答案 -
所以你的 Vue 组件上有一个 name
属性,你希望这个插件随着 HTTP 请求的进行更新那个值?我认为这会给你带来糟糕的责任链。您的 Vue 实例将需要有一个 name
属性,并且您的插件不会是独立的。
最好让插件自行处理所有状态跟踪。您可以创建一个名为 status
的 属性 状态,它会随着请求的进行而更新。然后你可以使用 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
永远不知道组件的上下文一样。它只是获取数据,发送请求,然后 运行s 回调。对调用组件一无所知。
因此,在您作为回调发送至 this.$state.post
的函数中,您可以使用 this.var
- 编辑您的 Vue 数据,正如您应该能够 那样。在您从您的州发送到 Vue.http.post
的回调中,您可以编辑 State
对象的属性 - 同样,这是预期的行为。您需要使 name
或 status
变量成为 State
的一部分,然后在您的 Vue 组件中将其引用为 this.$state.name
以检查状态。
编辑 2:
你甚至可以有一个变量 $state.response
并传入 myCustomVar
,然后跟踪 $state.response.myCustomVar
。这样你就可以在每个请求中传递不同的自定义变量并独立跟踪它们
我最终解决了这个问题,它比我想象的要容易。
它只是 vue-router
中 $http
方法的一个简单快捷方式包装器,因此可以像这样进行调用:
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