1

I am building a SPA with Vue for the first time. I am going to re-use a couple of functions but can't seem to make it work. I get the error "this.ExperienceToLevel is not a function".

At the same time, I'm not even sure creating a plugin is the best way to achieve what I am trying to. Which is, making some functions global "the Vue way". I don't want to assign it to window like window.UserLevel = new UserLevel().

UserLevel.js

/*
Create Levels array
 */
let Levels = [];
for (let i = 0; i < 100; i++) {
    let xp = Math.floor(Math.pow(i, 1.3) * 100);
    Levels.push(xp);
}

/*
Create UserLevel Plugin
 */
const UserLevel = {
    install(Vue, options) {
        Vue.ExperienceToLevel = function (xp) {
            for (const [level, levelXP] of Object.entries(options.levels)) {
                if (levelXP > xp) {
                    return level-1;
                }
            }
        }

        Vue.LevelToExperience = function (level) {
            return options.levels[level];
        }

        Vue.ExperiencePercent = function (level) {
            return ((this.xp - this.LevelToExperience(this.level)) / (this.LevelToExperience(this.level + 1) - this.LevelToExperience(this.level))) * 100;
        }
    }
};

export {
    Levels,
    UserLevel
};

I try to import the plugin into a component like this:

import { UserLevel, Levels } from './../../UserLevel';
Vue.use(UserLevel, { levels: Levels });

And use the global methods like so: this.ExperienceToLevel(this.xp)

1 Answer 1

5

According to Vue documentation on Plugins, you have two options:

Declare those methods inside a mixin:

const UserLevel = {
    install(Vue, options) {
        Vue.mixin({
            methods: {
                ExperienceToLevel(xp) { ... },
                LevelToExperience(level) { ... },
                ExperiencePercent(level) { ... },
            }
        })
    }
};

Or bind them to Vue.prototype:

Vue.prototype.$ExperienceToLevel = function (xp) { ... }
Vue.prototype.$LevelToExperience = function (level) { ... }
Vue.prototype.$ExperiencePercent = function (level) { ... }

I would go with the former.

Sign up to request clarification or add additional context in comments.

1 Comment

I vote for the former as well. I just noticed that calling a prototype method from a template loses the this object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.