简体   繁体   English

在 App.vue 脚本中访问主 Vue 实例

[英]Access to main Vue instance in App.vue script

In Vue2, I'm trying to set up an axios interceptor in my App.vue file to trap any responses that come back 401 from my API so I can redirect the user to the Vue route /sign-in .在 Vue2 中,我试图在我的App.vue文件中设置一个axios拦截器,以捕获从我的 API 返回401的任何响应,以便我可以将用户重定向到 Vue 路由/sign-in My code works, but I rely on storing the Vue instance created in main.js in window.appvue .我的代码有效,我依赖于将window.appvue中创建的 Vue 实例存储在main.js中。

In main.js :main.js

window.appvue = new Vue({
    router,
    render: (h) => h(App),
}).$mount("#app");

In App.vue :App.vue

<script>
import...
export default { ... }
 
export const $axios = axios.create();
$axios.interceptors.response.use(
    (response) => {
        return response;
    },
    (error) => {
        if (error.response.status === 401) {
            window.appvue.$router.push("/sign-in");
        } else {
            return Promise.reject(error);
        }
    }
);
<script>

I have tried importing $axios from App.vue in main.js and moving the $axios.interceptors.response.use(...) code to that file, but then the interceptor never runs when I have a page where an $axios.get() returns 401.我尝试从App.vue中的 App.vue 导入$axios main.js $axios.interceptors.response.use(...)代码移动到该文件,但是当我有一个$axios.get()的页面时,拦截器永远不会运行$axios.get()返回 401。

Is there a way to accomplish this without storing the main Vue instance in window as a global?有没有办法在不将主 Vue 实例作为全局存储在window中的情况下实现这一点? Or should I just go with what's working and call it a day?或者我应该只使用 go 什么工作,然后就这样结束了吗?


PS I was not aware of the existence of $root , when I asked this question, and I have not tried a version where the code in App.vue uses $root instead of relying on the window.appvue global, but when it comes to accessing the main/root instance of Vue from main.js , $root is definitely preferable to a global. PS我不知道$root的存在,当我问这个问题时,我还没有尝试过App.vue中的代码使用$root而不是依赖window.appvue全局的版本,但是当涉及到从main.js访问 Vue 的 main/root 实例, $root绝对比全局更可取。

inside your main.js try something like this在你的main.js尝试这样的事情

import router from './router'
import axios from 'axios'

Vue.prototype.axios.interceptors.reponse.use(
  res => {
    // res stuff here
  },
  err => {
    // error stuff here
    if (err.response.status === 401) {
      router.push("/sign-in");
    } else {
      return Promise.reject(err);
    }
  }
)

I managed to avoid using the global by isolating the axios wrapper into its own module/file.我设法通过将axios包装器隔离到它自己的模块/文件中来避免使用全局。 Then my .vue files that need axios can import from that instead of from axios directly然后我需要axios.vue文件可以从中导入,而不是直接从axios

In {root}/src/axios.js :{root}/src/axios.js

import axios from "axios";
import router from "@/router";

const $axios = axios.create();
$axios.interceptors.response.use(
    [stuff that uses router]
);
export default $axios;

Then in my files that need to call to the API:然后在我需要调用 API 的文件中:

import $axios from "@/axios.js";

and use $axios instead of axios to make the API call.并使用$axios而不是axios进行 API 调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM