如何从另一个插件访问Vue插件(使用Vue.prototype)?

时间:2019-04-26 20:11:28

标签: javascript vue.js

我正在尝试编写一个Vue插件,该插件是管理我的应用程序中的身份验证状态的简单抽象。此时将需要访问其他Vue插件,即vuexvue-routervue-apollo

我尝试扩展Vue.prototype,但是当我尝试正常访问插件的属性时-例如。 this.$apollo-得到对象的范围,因此出现undefined错误。我也尝试添加vm = this并使用vm.$apollo,但这只会将作用域移到更远的地方,而不是移到Vue对象上-我猜这是因为没有Vue对象的实例

export const VueAuth = {
  install (Vue, _opts) {
    Vue.prototype.$auth = {
      test () {
        console.log(this.$apollo)
      }
    }
  }
}

(其他插件通过主Vue.use()中的app.js导入和添加)

或者,我尝试过...

// ...
  install (Vue, { router, store, apollo })
// ...

但是作为js的新手,我不确定这是如何传递传递的对象的副本,或者它是否会使ref改变原始对象/传递。而且非常明确,如果我的插件要深入到更多的插件中,则意味着更多的开销。

任何人都可以提出一种干净,易于管理的方法建议吗?我是否必须改为更改Vue的实例而不是原型?

3 个答案:

答案 0 :(得分:0)

因此,我通过将我的属性从一个普通的ol'对象转换为一个返回对象的闭包来解决了这个问题,这似乎解决了我的this范围界定问题。

老实说,我以对JS的最少了解跳入了Vue,但我还不完全了解函数和类似对象的作用域(而且我不确定我是否还想在这块岩石下看... ...)。

export const VueAuth = {
  install (Vue, opts) {
    Vue.prototype.$auth = function () {
      let apollo = this.$apolloProvider.defaultClient
      let router = this.$router

      return {
        logIn: function (email, password) {
          apollo.mutate({
            mutation: LOGIN_MUTATION,
            variables: {
              username: email,
              password: password,
            },
          }).then((result) => {
            // Result
            console.log(result)
            localStorage.setItem('token', result.data.login.access_token)
            router.go(router.currentRoute.path)
          }).catch((error) => {
            // Error
            console.error('Error!')
            console.error(error)
          })
        },

        logOut: function () {
          localStorage.removeItem('token')
          localStorage.removeItem('refresh-token')
          router.go()
          console.log('Logged out')
        },
      }
    }

目前这是一个基本的实现,但可以用于测试。

答案 1 :(得分:0)

我找到了解决此问题的简单方法:

在插件安装程序中,您不仅需要为原型增加价值,还需要为Vue自身增加价值,以便能够在全球范围内使用它。

有一个代码示例:

安装程序:

import apiService from "../services/ApiService";
// Service contains 'post' method

export default {
  install(Vue) {
    Vue.prototype.$api = apiService;
    Vue.api = apiService;
  }
};

在其他插件中的用法:

import Vue from "vue";

...

const response = await Vue.api.post({
  url: "/login",
  payload: { email, password }
});

组件中的用法:

const response = await this.$api.post({
  url: "/login",
  payload: { email, password }
});

我不确定这是否是一个很好的解决方案,但这使我的方案运行正常。

答案 2 :(得分:0)

在插件安装功能中,您无法访问Vue实例(this),但您可以通过原型访问其他插件。例如:

main.js:

Vue.use(Apollo)
Vue.use(VueAuth) // must be installed after vue-apollo

plugin.js:

export const VueAuth = {
  install (Vue) {
    Vue.prototype.$auth = {
      test () {
        console.log(Vue.prototype.$apollo)
      }
    }
  }
}