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

Jam*_*oth 9 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)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Vue.use()(其他插件通过 main 中导入并添加app.js

或者,我尝试过...

// ...
  install (Vue, { router, store, apollo })
// ...
Run Code Online (Sandbox Code Playgroud)

但作为一个 js 新手,我不确定这在传递传递对象的副本方面是如何工作的,或者它是否会改变原始文件/通过引用传递。而且它也非常明确,如果我的插件要进一步接触更多插件,则意味着更多的开销。

任何人都可以建议一种干净、可管理的方法来做到这一点吗?我是否必须更改实例Vue而不是原型?

Cha*_*Nau 6

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

main.js:

Vue.use(Apollo)
Vue.use(VueAuth) // must be installed after vue-apollo
Run Code Online (Sandbox Code Playgroud)

插件.js:

export const VueAuth = {
  install (Vue) {
    Vue.prototype.$auth = {
      test () {
        console.log(Vue.prototype.$apollo)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*oth 0

因此,我通过将属性从普通对象转换为返回对象的闭包来解决这个问题,这似乎解决了我的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')
        },
      }
    }
Run Code Online (Sandbox Code Playgroud)

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