Vue 3正在访问vue路由器中的vue示例,在Vue文件之外

jyztefdp  于 2022-12-30  发布在  Vue.js
关注(0)|答案(4)|浏览(212)

我已经坚持了一段时间,我想从vue router.js文件中访问我的keycloak示例。

const preventRoutes = {
  beforeEnter: (to, from, next) => {
    console.log(App.$keycloak.authenticated); //here. (Undefined)
    if (store.getters.getLoginState === "true") {
      ...
    } else {
      ...
    }
  }
}

access vue 3 app instance api from non-vue fiile
我正在尝试这个解决方案。因为这是我能找到的唯一的VUE3,但我仍然认为他跳过了一些步骤。有人能简化一下吗?
建议解决方案

const preventRoutes = {
  beforeRouteEnter(to, from, next) {
    next(vm => {
      // access to component instance via `vm`
      // console.log(vm.$keycloak.authenticated);
      if (this.vm.$keycloak.authenticated) {
        next();
      } else {
        next("/");
      }
    })
  }
}

main.js

const myApp = createApp(App)

let initOptions = {
  url: KeycloakConfig["auth-server-url"], realm: KeycloakConfig.realm, clientId: KeycloakConfig.resource, clientSecret: KeycloakConfig.credentials.secret
}

const keycloak = Keycloak(initOptions)

myApp.config.globalProperties.$keycloak = keycloak;
myApp.use(VueAxios, axios)
myApp.use(store)
myApp.use(router)
myApp.mount("#app");

keycloak.init({
  onLoad: "check-sso",

  checkLoginIframe: false
}).then(async (auth) => {
  if (!auth) {

  } else if (auth) {
    router.push("/dashboard"); 
  }
}).catch((e) => {
  console.log('Serwer lezy: ' + e)
})
6jjcrrmo

6jjcrrmo1#

我有另一个解决方案(也许它更多的是一个变通办法,但感觉有点正确)
您可以将路由器 Package 在自定义插件安装方法中,例如:

const router = createRouter({
    history: createWebHashHistory(),
    routes,
});

export default {
    install(app, options) {
        router.install(app)

        router.beforeEach((to, from, next) => {
            // access all used plugins
            console.log(app.config.globalProperties.$store)
            console.log(app.config.globalProperties.$First)
            // ... stuff ...
        });
    },
};

在你的main.js中,你可以像以前一样use(...)路由器:

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import * as plugins from "./plugins";

const app = createApp(App)

app.use(store)
   .use(plugins.First)
   .use(plugins.Second)
   .use(router, app) // add "app" as second param, that way you can access the store and every other plugin within the router
   .mount("#app");
2uluyalo

2uluyalo2#

router.js的一个解决方案是导出一个函数,该函数捕获给定的app参数,该参数可以用在路由的beforeEnter钩子中:

// router.js
import { createRouter as createVueRouter, createWebHistory } from 'vue-router'

const createRoutes = (app) => [
  {
    path: '/restricted',
    component: () => import('@/views/Restricted.vue'),
    beforeEnter(to, from, next) {
                             👇
      const authenticated = app.config.globalProperties.$keycloak?.authenticated
      if (authenticated) {
        next()
      } else {
        next('/login')
      }
    }
  },
  //...
]

export const createRouter = (app) => {
  return createVueRouter({
    history: createWebHistory(),
    routes: createRoutes(app), 👈
  })
}

demo 1
...或在全局beforeEach挂接中:

// router.js
import { createRouter as createVueRouter, createWebHistory } from 'vue-router'

const createRoutes = () => [
  {
    path: '/restricted',
    component: () => import('@/views/Restricted.vue'),
    meta: { requiresAuth: true }, 👈
  },
  //...
]

export const createRouter = (app) => {
  const router = createVueRouter({
    history: createWebHistory(),
    routes: createRoutes(),
  })

  router.beforeEach((to, from, next) => {
                          👇
    const authenticated = app.config.globalProperties.$keycloak?.authenticated
    if (to.meta.requiresAuth && !authenticated) {
      next({ name: 'Login' })
    } else {
      next()
    }
  })
  return router
}

demo 2
那么您的main.js将像这样使用它:

import { createRouter } from './router'

const app = createApp(App)
const router = createRouter(app)
app.use(router)

const keycloak = /*...*/

keycloak.init(/*...*/)
  .then((auth) => {
    if (auth) {
      router.push('/dashboard')
    }
  })

app.mount('#app')
trnvg8h3

trnvg8h33#

beforeEnterbeforeRouteEnter没有对Vue示例的访问权限。
您可以将逻辑更改为使用beforeRouteLeave,该beforeRouteLeave具有对使用this的示例的访问权限,也可以添加回调函数,如下所示:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // access to component instance via `vm`
    console.log(vm.$keycloak.authenticated);
  })
}

在您的特定情况下,我将更改逻辑以使用beforeRouteLeave,并防止在用户未通过身份验证的情况下调用next()函数。
您可以在此处找到更多详细信息:https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards

rpppsulh

rpppsulh4#

您可以将路由守卫附加到main.js文件中,根据您的代码,该文件将变为:

const myApp = createApp(App)

let initOptions = {...}

const keycloak = Keycloak(initOptions)

myApp.config.globalProperties.$keycloak = keycloak;
myApp.use(VueAxios, axios)
myApp.use(store)
myApp.use(router)
myApp.mount("#app");

keycloak.init({...}).then(async (auth) => {
  if (auth) {
    router.push("/dashboard"); 
  }
}).catch((e) => {...})

router.beforeEnter: (to, from, next) => {
  console.log(myapp.$keycloak.authenticated); //here. (Undefined)
  if (store.getters.getLoginState === "true") {
    ...
  } else {
    ...
  }
}

相关问题