如何控制弹窗优先级?

在某些项目中,进入页面时可能会有多个消息弹窗,如果让所有弹窗都显示会影响用户体验,我的做法是:

  • 通过配置文件来定义好优先级规则
  • 利用数据结构-栈控制弹窗的显隐

配置文件的定义

const PRIORITY = {
  popup1: {
    level: 2, // 弹窗优先级
    method: 'setShowPopupFlag1', // 控制的弹窗显隐的方法
  },
  popup2: {
    level: 3,
    method: 'setShowPopupFlag2',
  },
};


export default PRIORITY;

栈-控制弹窗显隐

如何控制弹窗优先级?_第1张图片

注意:mobx是用6.0.x版本,与4、5版本是用方式有区别

class BaseStore {
  constructor() {
    makeAutoObservable(this)
  }
  /** 弹窗优先级-栈 */
  stack: Stack = new Stack(this);

  /** 弹窗1的控制变量 */
  showPopupFlag1 = false;

  /** 弹窗2的控制变量 */
  showPopupFlag2 = false;

  /** 弹窗1 */
  setShowPopupFlag1 = (showPopupFlag1: boolean) => {
    this.showPopupFlag1 = showPopupFlag1;
  }

  /** 弹窗2 */
  setShowPopupFlag2 = (showPopupFlag2: boolean) => {
    this.showPopupFlag2 = showPopupFlag2;
  }

  /** 调接口模拟消息,是否展示弹窗1 */
  fetchPopup1 = async () => {
    try {
      const { code } = await fetchPopup1();
      if (code === 200) {
        runInAction(() => {
          // 入栈
          this.stack.intoStack(PRIORITY.popup1);
        })
      }
    } catch (error) {
      console.log(error);
    }
  }

  /** 调接口模拟消息,是否展示弹窗2 */
  fetchPopup2 = async () => {
    try {
      const { code } = await fetchPopup2();
      if (code === 200) {
        runInAction(() => {
          // 入栈
          this.stack.intoStack(PRIORITY.popup2);
        })
      }
    } catch (error) {
      console.log(error);
    }
  }
}

export default BaseStore;

栈定义

class Stack {
  topStore: BaseStore;

  constructor(topStore: BaseStore) {
    makeAutoObservable(this);
    this.topStore = topStore;
  }

  item: any = [];

  get size() {
    return this.item.length;
  }

  get isEmpty() {
    return this.item.length === 0;
  }

  get topEle() {
    return this.item[this.item.length - 1];
  }

  intoStack = (targetEle: {level: number, method: string}) => {
    if (this.isEmpty) {
      this.item.push(targetEle);
      (this.topStore[targetEle.method as keyof BaseStore] as (value: boolean) => void)(true);
    } else {
      if (targetEle.level > this.topEle.level) {
        (this.topStore[this.topEle.method as keyof BaseStore] as (value: boolean) => void)(false);
        this.item.pop();
        this.item.push(targetEle);
        (this.topStore[targetEle.method as keyof BaseStore] as (value: boolean) => void)(true);
      }
    }
  }
}

export default Stack;

弹窗控制变量不集中在一个store中

假如控制弹窗显隐的方法不集中在一个store中,为了方便我们操作其他store中的控制方法,可以如下改造store的结构:
如何控制弹窗优先级?_第2张图片

class RootStore {
 constructor() {
 this.userStore = new UserStore(this)
 this.todoStore = new TodoStore(this)
 }
}
​
class UserStore {
 constructor(rootStore) {
 this.rootStore = rootStore
 }
​
 getTodos(user) {
 // 通过根 store 来访问 todoStore
 return this.rootStore.todoStore.todos.filter(todo => todo.author === user)
 }
}
​
class TodoStore {
 @observable todos = []
​
 constructor(rootStore) {
 this.rootStore = rootStore
 }
}

并且,在配置文件中增加控制方法存在于哪个store中的变量,方便调用:

const PRIORITY = {
  popup1: {
    level: 2, // 弹窗优先级
    storeName: 'xxx', // 控制方法存在于哪个store中
    method: 'setShowPopupFlag1', // 控制的弹窗显隐的方法
  },
  popup2: {
    level: 3,
    storeName: 'xxx', // 控制方法存在于哪个store中
    method: 'setShowPopupFlag2',
  },
};


export default PRIORITY;

你可能感兴趣的:(弹窗栈优先级react.js)