插件中的 Vue.js 绑定上下文?
Posted
技术标签:
【中文标题】插件中的 Vue.js 绑定上下文?【英文标题】:Vue.js binding context in plugin? 【发布时间】:2016-07-06 02:19:02 【问题描述】:我正在尝试在 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
上下文,它应该已经有了正确的上下文。
编辑
为了澄清,我正在寻找一种解决方案来传递正确的上下文。以上只是一个示例,我不是在寻找跟踪状态的解决方案。
例如在 vue-resource
插件中,如果我们发出任何 http 请求。
this.$http.get('/some/url', , function ()
this.func();
console.log(this.var);
);
上下文已经存在于回调中。我不需要做某种var _this = this
来进入视图范围。我想为我的插件实现相同的目标,以便正确的this
就在那里。我试图从vue-resource
插件中找出答案,但很难遵循所有代码。
【问题讨论】:
所以你的 Vue 组件上有一个name
属性,并且你希望这个插件随着 HTTP 请求的进行更新该值?我认为这给了你一个糟糕的责任链。您能否创建一个名为status
的State
属性已更新?那么您可以使用this.$state.status
知道当前状态吗?然后插件负责它的用途,组件保持独立
【参考方案1】:
将我的评论扩展到答案 -
所以你的 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
。这样您就可以在每个请求中传递不同的自定义变量并独立跟踪它们
【讨论】:
我想你误会了。没有$state.status
。当调用 this.$state.post(ctx, 'someStateVar
...` 时被传入。在该请求期间,ctx['someStateVar']
会更新状态。这个想法是不必传递ctx
上下文,它应该就在那里。无论如何,这只是一个例子,重点是在那里获得适当的上下文。例如vue-resource
插件,您可以在success
和error
回调中执行this.func()
或this.var
,而无需在范围外引用var _this = this
。我正在努力实现同样的目标。
您已经可以在成功和错误回调中调用this.func()
或this.var
。它们是写在 Vue 组件的作用域中然后传入的,所以它们仍然有原来的作用域。从这里,您只需将它们称为cb()
或errorCb()
。关键是插件永远不需要知道它被调用的上下文。你永远不应该从插件更新ctx['someStateVar']
,而应该是插件的一个属性。否则,您的插件取决于该变量,这不是一个好主意。我编辑了更多...
已经是自定义变量了。我的评论写错了,但是如果您查看示例,您会发现插件中没有任何硬编码。只是ctx[someVar]
。 $http
再次以某种方式绑定它,因此可以在不传递 ctx
或调用 bind
的情况下进行绑定。只是想弄清楚如何。
这在哪里使用调用上下文? github.com/vuejs/vue-resource/blob/master/src/http/index.js#L81 。在您的编辑示例中,该函数定义在 Vue 组件内部,因此它当然具有正确的上下文。在您的完整代码中,它在State
中定义,因此它具有该上下文。 vue-resource
没有在这里绑定任何东西
这里有一个绑定函数...你可以访问你插件中的变量this.$vm
吗? github.com/vuejs/vue-resource/blob/master/src/http/index.js#L81【参考方案2】:
我最终解决了这个问题,比我想象的要容易。
这只是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 上的 sn-p here
【讨论】:
到 Github 的 sn-p 链接失效了,能否请您在此处提供 sn-p 或新链接?我一直在试图找出一种在插件中实现相同功能的方法。非常感谢您的帮助。以上是关于插件中的 Vue.js 绑定上下文?的主要内容,如果未能解决你的问题,请参考以下文章