ページ要素権限制御


ボタン権限制御
ボタン権限制御のインタラクションは、「非表示」と「非表示」の2つにほかならない.
非表示
非表示のインタラクションは比較的簡単で、DOMの表示非表示を制御すればよい.Vueでは、以下のようにして実現することができる.
  • v-ifは、
  • を表示するか否かを制御する.
  • v-showは表示するかどうかを制御するが、保険が足りない.結局v-showはスタイルをdisplay: noneに変更しただけで、実際のDOMレンダリングには
  • が存在する.Reactでは、以下のようにして実現することができる.
  • JSXにおける条件判定
  • const Demo = () => {
      return 
    {boolean && }
    }
  • 高次構成要素HOCを用いる、抽出判定ロジック
  • .
    const Demo = () => {
      return 
    code...
    } /** */ const HOC = (Com: Com: React.ComponentType) => { if (whiteList.includes(code)) return return null; }

    可視不可点
    ページには多くの機能点があり、一部の機能点ユーザーがDOMを表示せずに操作できない場合、ページレイアウトが乱れたり、ページの美しさに影響を与えたりする可能性があります.一部の製品では、機能点の権限を制御する際に要素が「見えない」ことを望んでいます.Vueでは、以下のようにして実現することができる.
  • カスタム命令Vue.directive.addEventListenerを使用して要素に1つのキャプチャイベントを追加すると、キャプチャイベントは@clickよりも優先的にトリガされ、その後、キャプチャイベント方法体においてstopImmediatePropagationを使用してイベントバブルや他の同じイベントのトリガを阻止するため、要素のクリック不可を制御する目的を達成する
  • .
    複数のイベントリスナーが同じ要素の同じイベントタイプにアタッチされている場合、イベントがトリガーされると、追加された順序で呼び出されます.いずれかのイベントリスナーで実行する場合stopImmediatePropagation()であれば、残りのイベントリスナーは呼び出されません.
    MSDN - stopImmediatePropagation
    //          
    /**      */
    const interception = (event) => {
        event && event.stopImmediatePropagation();
    }
    
    /**     */
    const whiteList = [];
    
    /**      */
    Vue.directive('permission', {
        bind(el, binding) {
            /**        */
            if (!whiteList.includes(binding.value)) {
                el.style.pointerEvents = 'none';
                el.setAttribute('disabled', 'disabled');
                el.addEventListener('click', interception, true);
            }
        },
        unbind(el) {
            el.removeEventListener('click', interception);
        }
    });

    ここではpointer-eventsを使用するのは単なる補助機能であり、必ずしも要素上のイベントリスナーが永遠にトリガーされないとは限らない.pointer-eventsCSSプロパティは、特定のグラフィック要素がマウスイベントになる場合(ある場合)を指定します.CSS3 . 使用法の詳細:
    MSDN - pointer-events pointer-eventsでは、以下のようにして実現することができる.
    import { Button } from 'antd';
    import axios from 'axios';
    import React, { Component } from 'react';
    
    /**            */
    const RbacHOC = (Com: any) => {
      return class WrappedComponent extends Component {
        divRef = React.createRef();
    
        componentDidMount() {
          this.fetchWilteList();
        }
    
        componentWillUnmount() {
          this.divRef.current?.removeEventListener('click', this.intercept);
        }
    
        /**        */
        fetchWilteList = async () => {
          try {
            const { code, data } = await axios.get(`${url}`).then((res: any) => res.data);
            if (code === 200 && !data) {
              this.register();
            }
          } catch (error) {
            this.register();
          }
        };
    
        /**       ,     */
        register = () => {
          this.divRef.current?.addEventListener('click', this.intercept, true);
        };
    
        /**      */
        intercept = (event: Event) => {
          event.stopImmediatePropagation();
          message.info('          !!!');
        };
    
        render() {
          const { props } = this;
          return (
            
    ); } }; }; export default RbacHOC;

    ページコンポーネントで使用:
    import React from 'react';
    
    const Demo = () => {
      return <>coding...>
    }
    
    export default RbacHOC(inject('store')(observer(Demo)));
    // export default inject('store')(observer(RbacHOC(Demo)); 
    //      ,  store   WrappedComponent        ,    Demo   props  ,Demo       

    トリガをクリックするたびにインタフェースを呼び出して白黒リストを取りたくない場合は、白黒リストデータを格納するtargetを上位コンポーネントに転送できます.
    import React from 'react';
    
    const Demo = () => {
      return <>coding...>
    }
    
    export default inject('xxxstore')(RbacHOC(inject('store')(observer(Demo))));

    リファレンス
    Elementボタン権限に基づく実装スキーム