javascript - 监听窗口属性变化

标签 javascript vue.js window

我正在尝试在 vue 组件内部监听窗口属性更改,我不确定这是否可行。
用于加载程序,基本上我有一个文件,其中有一个拦截器,它改变窗口对象上的“加载”属性(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}
    }

我也尝试过这个解决方案:

created () {
    window.addEventListener('loading', this.handleLoading);
  },
  destroyed () {
    window.removeEventListener('loading', this.handleLoading);
  },
  methods: {
    handleLoading(val){
      console.log(val)
    this.loading =  val
}
  },

问题是我如何在我的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;
        },
    };
}

这是具有创建商店的工厂函数的文件:

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

最佳答案

我真的不认为通过 window.loading 传达加载状态是一个好主意。使用 Vuex 存储或类似的单例之类的东西来保存加载状态似乎是一种更好的方法,但在问题中已(有点神秘地)排除了这一点。

但是,假设window.loading是唯一的选择...

window.loading 定义 getter 和 setter 可能是使该方法发挥作用的一种方法。有多种方法可以完成,但在我的示例中,我选择代理到 Vue observable 来保存该值。

const loadingMonitor = Vue.observable({
  loading: false
})

Object.defineProperty(window, 'loading', {
  get () {
    return loadingMonitor.loading
  },
  
  set (loading) {
    loadingMonitor.loading = loading
  }
})

new Vue({
  el: '#app',
  
  computed: { 
    loading () {
      return window.loading
    }
  },
  
  methods: {
    toggle () {
      window.loading = !window.loading
    }
  }
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
  <p>{{ loading }}</p>
  <button @click="toggle">Toggle</button>
</div>

请注意,Vue.observable 是在 Vue 2.6 中添加的,因此如果您使用的是旧版本,则需要使用新 Vue 实例的 data 来达到同样的效果。

由于该值保存在可观察对象中,因此它可以像其他所有东西一样参与 react 系统。这使得它可以作为 react 性依赖项在计算属性中使用。

关于javascript - 监听窗口属性变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57670698/

相关文章:

javascript - jsPlumb - 每侧的动态端点 anchor

javascript - JQuery:如何替换两个特定部分之间的属性部分?

vue.js - 在共享主机上部署 Nuxt

javascript - Vue 未解析的变量 PhpStorm

javascript - 如何制作多个可移动元素

javascript - 检测字符串上的 html 标签,获取值并删除 javascript 中 html 标签内的值

javascript - Google Chrome 崩溃内存泄漏或任何渲染问题

.net - 如何创建数据库设置

html - 如果我从左到右书写,如何更改换行方向以保持旧行在顶部和新行向下突破?

macos - 在 OSX 上用鼠标单击 View 时如何防止焦点窗口?