Javascript 侦听窗口属性更改
我正在尝试在vue组件内部侦听窗口属性更改,我不确定这是否可行。Javascript 侦听窗口属性更改,javascript,vue.js,window,Javascript,Vue.js,Window,我正在尝试在vue组件内部侦听窗口属性更改,我不确定这是否可行。 该用法用于加载程序,实际上我有一个文件,其中包含一个拦截器,该拦截器可更改窗口对象的“加载”属性(window.loading=true请求启动时,window.loading=false请求完成时(或错误))(我在访问拦截器内的存储时遇到问题)。 vue组件如下所示: <template> <v-progress-linear //this is the loader element
该用法用于加载程序,实际上我有一个文件,其中包含一个拦截器,该拦截器可更改窗口对象的“加载”属性(
window.loading=true
请求启动时,window.loading=false
请求完成时(或错误))(我在访问拦截器内的存储时遇到问题)。
vue组件如下所示:
<template>
<v-progress-linear //this is the loader element
height="20"
v-show="loading"
>
</v-progress-linear>
...
computed: {
loading(){
return window.loading}
}
问题是如何在我的窗口中进行监听。加载
编辑
这是包含拦截器代码的文件,请注意,该文件无权访问vue实例
import axios from 'axios';
import { Utils } from 'em-common-vue';
import {UsersApi} from "./usersApi";
import {PartnersApi} from "./partnersApi";
import {TrialsApi} from "./trialsApi";
export function apiFactory($security) {
const $http = axios.create({
baseURL: process.env.VUE_APP_API_URL
});
$http.interceptors.request.use(function (config) {
window.loading = true
const token = $security.loginFrame.getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, function (error) {
window.loading = true
Utils.EventBus.$emit('toastMessageHandler', {message: error.message, type: 'error'});
window.loading = false
return Promise.reject(error);
}
);
$http.interceptors.response.use(function (response) {
window.loading = false
return response;
}, function (error) {
if (error.response && error.response.status === 401) {
Utils.EventBus.$emit('authErr', error);
} else if (error.response && error.response.status === 403) {
alert('You are not authorized to access this application. If you believe you are seeing this message in error, please contact support@emergingmed.com.');
}
else if (error.response && error.response.status !== 409){
Utils.EventBus.$emit('toastMessageHandler', {message: error.message, type: 'error'});
}
else if (error.response && error.response.status === 500){
Utils.EventBus.$emit('toastMessageHandler', {message: 'There was a problem with this operation - please contact support@emergingmed.com.', type: 'error'});
}
window.loading = false
return Promise.reject({error});
});
const $api = {
users: new UsersApi($http),
partners: new PartnersApi($http),
trials: new TrialsApi($http)
};
return $api;
}
// register $api as vue plugin
export function apiPluginFactory($api) {
return {
install(vue) {
vue.prototype.$api = $api;
},
};
}
以下是具有创建存储的factory函数的文件:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import {usersStoreFactory} from "./users/module";
// global
import {InitActions} from './actions';
import mutations from './mutations'
import getters from "./getters";
export function storeFactory($api, $config) {
// global
const actions = InitActions($api);
const store = new Vuex.Store({
modules: {
users: usersStoreFactory($api, $config),
},
state: {
partners: null,
// loading: window.loading
},
actions,
mutations,
getters
});
return store;
}
我真的不认为通过窗口传递加载状态。加载是个好主意。使用类似Vuex存储或类似的单例来保存加载状态似乎是一种更好的方法,但在这个问题中(有些神秘地)已经排除了这一点
但是,假设窗口。加载是唯一的选项
为窗口定义一个getter和setter。加载可能是使该方法起作用的一种方法。有几种方法可以实现,但在我的示例中,我选择通过代理到Vue observable来保存值
const loadingMonitor=Vue.observable({
加载:错误
})
Object.defineProperty(窗口“加载”{
得到(){
返回loadingMonitor.loading
},
设置(加载){
loadingMonitor.loading=正在加载
}
})
新Vue({
el:“#应用程序”,
计算:{
加载(){
返回窗口。正在加载
}
},
方法:{
切换(){
window.loading=!window.loading
}
}
})
{{loading}}
切换
感谢您的详细回答,有几个问题/要点:1)由于应用程序的引导方式,我无法使用应用商店,我在上面添加了代码,基本上所有内容都是使用工厂功能创建的,因此我无法从拦截器文件内访问应用商店。2) 您的解决方案是否允许设置窗口。从vue组件外部加载属性时,我需要在拦截器文件中设置它?3) 你为什么说这是不推荐的?Thanks@Michael我提供的代码允许您设置窗口。从可以访问窗口
对象的任何位置加载。您需要确保在尝试使用getter和setter之前,尽早创建getter和setter。除了污染全局名称空间之外,您还有多种选择。通过快速浏览您发布的额外代码,我可以看到两位候选人。一种是使用事件总线。第二个是将加载属性放在$api
上。我最初的印象是你们的架构太复杂了,虽然我显然不知道是什么推动了它,所以我不能确定。真的学到了很多谢谢!我很好奇为什么选择使用Object.defineProperty
,而不是简单地通过写入window.loading=loadingMonitor.loading
?Michael没有什么可以保持window.loading
与loadingMonitor.loading
同步的。初始值应该是正确的,但随后您又回到了使用窗口开始的位置。加载时,会出现无法在Vue中跟踪的值。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import {usersStoreFactory} from "./users/module";
// global
import {InitActions} from './actions';
import mutations from './mutations'
import getters from "./getters";
export function storeFactory($api, $config) {
// global
const actions = InitActions($api);
const store = new Vuex.Store({
modules: {
users: usersStoreFactory($api, $config),
},
state: {
partners: null,
// loading: window.loading
},
actions,
mutations,
getters
});
return store;
}