2017-12-18 215 views
1

我的应用程序中有很多AJAX请求,我想为每个请求显示加载图标,并在收到响应时将其删除。我为这些调用使用axios,所以我创建了一个简单的插件类并添加了定制的axios拦截器。为AJAX加载创建全局变量

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); 
}); 

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

在我的例子中,我有一个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

这是一个耻辱,你没有使用Vuex。我发现它非常适合在我的应用程序中处理状态,并将其广泛用作API调用和表示组件之间的缓冲区。 – Phil

+0

您应该尝试重构Vuex,因为这会为您节省像这样的麻烦。 –

+0

问题是应用程序建立在spark之上,不使用Vuex。而这一切都完成了。除此之外,所有事情都应该如此。 如果这是控制它的唯一方法,我会寻找另一种解决方案。我讨厌将Vuex包含在这一件小事中。 – Nathan

回答

0

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

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