在 main.js 文件上使用 vuejs 插件

Edn*_*ulo 2 javascript plugins vue.js vuejs2

我正在尝试创建一个插件来管理我的 vuejs 应用程序中的 Oauth2 令牌数据。

我根据互联网上提供的一些教程创建了该插件。

var plugin = {}

plugin.install = function (Vue, options) {
  var authStorage = {
    getToken () {
      let token = localStorage.getItem('access_token')
      let expiration = localStorage.getItem('expiration')
      if (!token || !expiration) {
        return null
      }
      if (Date.now() > parseInt(expiration)) {
        this.destroyToken()
        return null
      }

      return token
    },
    setToken (accessToken, expiration, refreshToken) {
      localStorage.setItem('access_token', accessToken)
      localStorage.setItem('expiration', expiration + Date.now())
      localStorage.setItem('refresh_token', refreshToken)
    },
    destroyToken () {
      localStorage.removeItem('access_token')
      localStorage.removeItem('expiration')
      localStorage.removeItem('refresh_token')
    },
    isAuthenticated () {
      if (this.getToken()) {
        return true
      } else {
        return false
      }
    }
  }

  Vue.prototype.$authStorage = authStorage
}

export default plugin
Run Code Online (Sandbox Code Playgroud)

但是当尝试访问 main.js 文件上的方法时,我收到错误消息,指出该对象未定义。

import Vue from 'vue'
import App from './App'
import router from './router'
import AuthStorage from './AuthStorage.js'

Vue.config.productionTip = false
Vue.use(AuthStorage)

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requireAuth)) {
    if (!Vue.$authStorage.getToken()) {
      next({
        path: '/',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next()
  }
})
axios.defaults.headers.common = {
  'Authorization': `Bearer ${Vue.$authStorage.getToken()}`
}
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})
Run Code Online (Sandbox Code Playgroud)

chrome 控制台显示错误

在组件内部,插件按预期工作。问题是当 o 尝试在 main.js 文件中使用时。我已经尝试过: this.$authStorage this.authStorage Vue.authStorage

没有成功

Ber*_*ert 5

您正在添加$authStorageprototypeVue.js 中。

Vue.prototype.$authStorage = authStorage
Run Code Online (Sandbox Code Playgroud)

这意味着只能在 Vue 对象的实例上可用(即new Vue(...).

如果你想$authStorage在不创建实例的情况下作为 Vue 的属性可用,则需要将其添加为静态属性。

Vue.$authStorage = authStorage
Run Code Online (Sandbox Code Playgroud)

但是,如果是我,我可能会采取不同的方法。我可能会像这样构建 AuthStorage 插件:

const authStorage = {
    getToken() {
      let token = localStorage.getItem('access_token')
      let expiration = localStorage.getItem('expiration')
      if (!token || !expiration) {
        return null
      }
      if (Date.now() > parseInt(expiration)) {
        this.destroyToken()
        return null
      }

      return token
    },
    setToken(accessToken, expiration, refreshToken) {
      localStorage.setItem('access_token', accessToken)
      localStorage.setItem('expiration', expiration + Date.now())
      localStorage.setItem('refresh_token', refreshToken)
    },
    destroyToken() {
      localStorage.removeItem('access_token')
      localStorage.removeItem('expiration')
      localStorage.removeItem('refresh_token')
    },
    isAuthenticated() {
      if (this.getToken()) {
        return true
      } else {
        return false
      }
    },
    install(Vue) {
      Vue.prototype.$authStorage = this
    }
}

export default authStorage
Run Code Online (Sandbox Code Playgroud)

这将允许我Vue之外像这样使用它,

import Vue from 'vue'
import App from './App'
import router from './router'
import AuthStorage from './AuthStorage.js'

Vue.config.productionTip = false
Vue.use(AuthStorage)

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requireAuth)) {
    if (!AuthStorage.getToken()) {
      next({
        path: '/',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next()
  }
})
Run Code Online (Sandbox Code Playgroud)

并在 Vue 中像这样引用它:

created(){
  let token = this.$authStorage.getToken()
}
Run Code Online (Sandbox Code Playgroud)

这是一个例子