为 AJAX 加载创建全局变量

Creating Global Variable for AJAX loading

我的应用程序中有很多 AJAX 请求,我想为每个请求显示加载图标,并在收到响应时将其删除。我正在使用 axios 进行这些调用,因此我创建了一个简单的插件 class 并添加了自定义 axios 拦截器。

const MyGlobalVariables= {
  install(Vue, options) {

    Vue.load_mask = true;

    MyGlobalVariables.getLoadMask = function() {
      return Vue.load_mask;
    },

    MyGlobalVariables.setLoadMask = function(val) {
      Vue.load_mask = val;
    }

  }
};
export default MyGlobalVariables;

然后拦截器

// Add a request interceptor
window.axios.interceptors.request.use(function (config) {

  // Do something before request is sent
  MyGlobalVariables.setLoadMask(true);
  console.log(MyGlobalVariables.getLoadMask());

  return config;
}, function (error) {
  MyGlobalVariables.setLoadMask(false);

  console.log(MyGlobalVariables.getLoadMask());
  // Do something with request error
  return Promise.reject(error);
});

// Add a response interceptor
window.axios.interceptors.response.use(function (response) {

  // control the load mask on AJAX calls
  MyGlobalVariables.setLoadMask(false);
  console.log(MyGlobalVariables.getLoadMask());
  return response;

}, function (error) {

  MyGlobalVariables.setLoadMask(false);
  console.log(MyGlobalVariables.getLoadMask());
  // Do something with response error
  return Promise.reject(error);
});

所以那部分工作正常。我的全局变量在适当的时候切换 true/false。我遇到的困难是如何在我的主模板上设置一个实际切换它的变量?

在我的例子中,我有一个 inline-template 是我整个项目的根。

<home :user="user" inline-template>
    // Bunch of content here

    <div v-if="shouldShowLoadMask" class='lmask'></div>
</home>

然后在我的 home.js 文件中:

import MyGlobalVariables from "./extras/my-global";

Vue.component('home', {
  props: ['user'],

  computed: {
    shouldShowLoadMask() {
      console.log('show load mask? ' + MyGlobalVariables.getLoadMask());
      return MyGlobalVariables.getLoadMask();
    },
   }

问题是 shouldShowLoadMask 仅在应用程序开始时触发一次。所以我需要在插件变量上 watch (或类似的东西)。但是怎么办?我看到有人引用 Vuex 的示例,但我没有在我的应用程序中使用它。

TL;DR:如何监控全局插件变量,以便可以使用 v-if 打开和关闭元素?

制作响应式全局变量的超级简单方法就是使用 Vue.这是概念:

const global = new Vue({data:{loading: false}})

const GlobalPlugin = {
  install(Vue){
    Vue.prototype.$global = global
  }
}

然后你就可以像这样在Vue中使用它了:

console.clear()

// set up the reactive global object
const global = new Vue({data:{loading: false}})

// make a plugin to add it to Vue
const GlobalPlugin = {
  install(Vue){
    Vue.prototype.$global = global
  }
}

Vue.use(GlobalPlugin)

// Set up a faux change to the global loading property
setInterval(() => global.loading = !global.loading, 2000)

// Reactivity!
Vue.component("some-component", {
  template:`
    <div>
      <h2> Some component </h2>
      Loading: {{$global.loading}}
    </div>
  `
})

new Vue({
  el: "#app",
  computed:{
    loading() {
      return this.$global.loading
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
<div id="app">
  <h2>Root Vue</h2>
  Loading: {{loading}}
  <some-component></some-component>
</div>

显然您需要在您的应用程序中做一些工作,但这是非常简单的反应式全局对象的核心。