Search code examples
javascriptvue.jsvue-resource

Vue.js binding context in plugin?


I'm trying to create a simple plugin in Vue.js to wrap the vue-resource plugin to track the state of a request.

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;

You will see I pass the ctx context from the calling Vue to get access to it's data values. I've seen with the vue-resource plugin that there is a way to automatically bind this through the plugin bat can't quite get the syntax right.

Basically I would like to avoid having to pass the ctx context in each time, it should just have the proper context already.

EDIT

To clarify I'm looking for a solution to pass the proper context in. The above is just sort of an example and I'm not looking for a solution to track states.

For example in the vue-resource plugin if we make any http request.

this.$http.get('/some/url', {}, function () {
    this.func();

    console.log(this.var);
});

The context is already there in the callback. I don't need to do some kind of var _this = this to get into the views scope. I want to achieve the same for my plugin so that the proper this is just there. I'm trying to figure it out from the vue-resource plugin but having a hard time following all the code.


Solution

  • I ended up sorting this out, it was easier than I thought.

    It's just a simple shortcut wrapper around the $http method in the vue-router so that calls can be made like so:

    this.$state.get('/buildings', data, function (resp) {
        this.buildings = resp.data;
    }, {
        track: 'getBuildingState'
    });
    

    Or

    this.$state('/buildings', {
        data: data,
        track: 'getBuildingState',
        success: function (resp) {
            this.buildings = resp.data;
        }
    });
    

    Can check out the snippet on Gihub here