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

Access to main Vue instance in App.vue script

在 Vue2 中,我试图在我的 App.vue 文件中设置一个 axios 拦截器来捕获从我的 API 返回 401 的任何响应,所以我可以将用户重定向到 Vue 路由 /sign-in。我的代码有效,但是 我依赖于将在 main.js 中创建的 Vue 实例存储在 window.appvue.

main.js中:

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

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>

我已经尝试从 main.js 中的 App.vue 导入 $axios 并将 $axios.interceptors.response.use(...) 代码移动到该文件,但是当我有一个页面时拦截器永远不会运行$axios.get() returns 401.

有没有办法在不将主 Vue 实例作为全局对象存储在 window 中的情况下完成此操作?还是我应该继续工作并结束工作?


P.S. 当我问这个问题时,我并不知道 $root 的存在,我也没有尝试过 App.vue 中的代码使用 $root 而不是依赖 [=18] 的版本=] 全局,但是当涉及从 main.js 访问 Vue 的 main/root 实例时,$root 绝对优于全局。

在你的 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);
    }
  }
)

我设法通过将 axios 包装器隔离到它自己的 module/file 中来避免使用全局。然后我的 .vue 需要 axios 的文件可以从那里导入而不是直接从 axios

{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;

然后在我的文件中需要调用到API:

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

并使用 $axios 而不是 axios 来进行 API 调用。