考虑下面的合成函数:

import { computed, ref } from '@vue/composition-api'
import { isInternetExplorer } from 'src/services/utils/utilsService'
import { Screen } from 'quasar'
import { auth, getAllScopes } from 'src/services/auth/authService'

const isLoginPopup = Screen.lt.sm || isInternetExplorer ? false : true
const accountID = ref('')

export const setAccountID = () => {
  const account = auth.getAccount()

  if (account) { accountID.value = account.idTokenClaims.oid } 
  else { accountID.value = '' }
}

export const useAccount = () => {
  const loading = ref(false)
  const disabled = ref(false)

  const login = async () => {
    loading.value = true
    disabled.value = true

    const allScopes = getAllScopes()

    if (isLoginPopup) {
      try {
        await auth.loginPopup(allScopes)
      } finally {
        setAccountID()
        disabled.value = false
        loading.value = false
      }
    } else {
      auth.loginRedirect(allScopes)
    }
  }

  const logout = () => { auth.logout() }

  return {
    accountID: computed(() => accountID.value),
    isAuthenticated: computed(() => Boolean(accountID.value)),
    loading: computed(() => loading.value),
    disabled: computed(() => disabled.value),
    login, logout,
  }
}

Now when I want to use the isAuthenticated computed property within /router/index.js Vue throws the error "Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function.":

import { route } from 'quasar/wrappers'
import VueRouter from 'vue-router'
import routes from './routes'

import { useAccount } from 'src/comp-functions/useAccount'

export default route(function ({ Vue }) {
  Vue.use(VueRouter)

  const Router = new VueRouter({
    scrollBehavior: () => ({ x: 0, y: 0 }),
    routes,

    mode: process.env.VUE_ROUTER_MODE,
    base: process.env.VUE_ROUTER_BASE,
  })

  Router.beforeEach((to, from, next) => {
    const { isAuthenticated } = useAccount()

    if (isAuthenticated || to.path === '/' || to.path === '/login') {
      next()
    } else {
      next('/login')
    }
  })

  return Router
})

组件API由文件"/boot/auth"中的Quasar Framework boot file实例化.js':

import VueCompositionApi from '@vue/composition-api'
import { boot } from 'quasar/wrappers'

export default boot(({ Vue }) => {
  Vue.use(VueCompositionApi)
})

有没有办法在组件之外使用导出的计算(computed)属性?

根据this example,它是一个使用相同合成API的库,当isAuthenticatedRouter对象中实例化时,它应该可以工作.有more people人在努力解决这个问题,但我似乎无法正确处理.

推荐答案

这个问题由Vue上的一位朋友解决.js论坛.对于其他遇到这个问题的人,我将在这里发布他的答案.简而言之,您需要创建一个单独的文件来安装composition API插件,并在router/index.ts文件中调用该文件来实例化插件.

这是因为合成API不在Vue内部.随着Vue 3的发布,这一问题将得到解决.

在try 使用任何属于@vue/composition-api的东西之前,你需要输入Vue.use(CompositionApi).

在应用程序入口点main.jsindex.js中,首先安装它:

import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'

Vue.use(VueCompositionApi)

这很管用.但我想你的文件不是这样的,它看起来更像下一个:

import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'
import { isAuthenticated } from '@/store/auth'

Vue.use(VueCompositionApi)

这将再次 destruct 一切,因为安装composition API(Vue.use(VueCompositionApi))的行位于导入使用它的内容(import { unauthenticated } from '@/store/auth')的行之后

同时,在Vue 3.0发布之前,您可以创建一个文件,只需安装插件即可:

// installCompositionApi.js

import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'

Vue.use(VueCompositionApi)

然后在你的入口点:

// main.js
import './installCompositionApi.js'
import Vue from 'vue'
import { isAuthenticated } from '@/store/auth'

if (isAuthenticated.value) {
// ...
} else {
// ...
}

这会管用的.

Vue.js相关问答推荐

Nuxt.js i18n不提供默认区域设置中的页面而不重定向

Vue 2 如何在全局函数中返回观察者

Nuxt3: 安装vue3-spinner (error: require is not defined in ES module scope)

在 VueJS 中,将变量而不是组件的字符串名称传递给动态组件的 :is 属性不起作用

如何在Vue js 3中根据API响应替换react 值

在 Vue 中启用(控制台)记录路由事件

Vue子组件等待props

VueJS 插件的如何react式绑定?

使用 v-slot:body 时 Vuetify v-data-table 没有响应

VueJS:向左,元素的顶部位置?

可以同时使用 Tailwind css 和 Bootstrap 4 吗?

如何将参数传递给使用 ...mapActions(...) 映射的函数?

使用 vue-router 的默认子路由

如何从 v-for 创建的对象中绑定多个类?

Vue Cli 3 不允许我在 Webpack 中处理 SVG

如何让 vuetify 数据表在卡片内时跨越容器的整个宽度?

如何从方法内部访问数据

克隆元素并附加到 DOM 的正确方法

是否有 v-cloak 逆?

如何将单选按钮绑定到 vuex store ?