为AJAX加载创建全局变量

时间:2017-12-18 14:25:37

标签: vue.js vuejs2 axios

我的应用程序中有很多AJAX请求,我想为每个请求显示加载图标,并在收到响应时将其删除。我正在使用axios进行这些调用,因此我创建了一个简单的插件类并添加了自定义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打开和关闭元素?

1 个答案:

答案 0 :(得分:2)

制作反应式全局变量的超级简单方法就是使用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>

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