狀態機Vuex的奇淫巧技-多彈框、多事件統一控制

​ 現實中的許多Web應用都有許多彈框,或者交互事件的開發需求。博主曾開發過較大型的Vue Web應用,光控制這些彈框的顯示隱藏都感受噁心:初始化isDialogShow=false,點擊按鈕isDialogShow=true,彈框顯示後點擊確認、取消和關閉按鈕須要廣播事件或者經過$parent將父組件的isDialogShow置爲false。還有就是跨組件的事件廣播也讓人頭大。如若彈框比較多或者跨組件事件較多,採用生硬的控制顯得很不優雅。javascript

​ 福音來了,如若你的Vue應用已經自帶vuex或者應用交互過多須要引入vuex,那麼下面的方案將是個不錯的解決方案。先說一下用vuex統一管理彈框和事件優勢:統一控制,一目瞭然控制簡單。其相關概念可查看vuex,這裏就不贅述了。vue

  1. 初始化state

    state: {
      // 彈框信息顯示控制標識統必定義於此,統一管理
      BooleanFlag: {
        //小駝峯:is 名詞 動詞
        isDemoDialogShow: false, // demo 彈框顯示
      },
      // 事件直通車, 相關事件能夠統一管理
      EventBus: {
        Page1ToPage2: {}, // 採用對象是爲了傳遞數據
      }
    }
    複製代碼
  2. 定義mutations

    mutations: {
      // 自動取反
      BooleanFlag(state, flagKeys) {
        if (!Array.isArray(flagKeys)) return
        const BooleanFlag = state.BooleanFlag
        flagKeys.forEach(flagKey => BooleanFlag[flagKey] = !BooleanFlag[flagKey])
      },
      // EventBus
      EventBus(state, eventWithData={}) {
        const EventBus = state.EventBus
        Object.keys(eventWithData).forEach(eventKey=>{
          if(EventBus[eventKey] !== undefined){
            EventBus[eventKey] = eventWithData[eventKey]
          }
        })
      }
    }
    複製代碼
  3. 父組件應用

    <template>
      <div>
        <div class="button-bar">
          <el-button @click="onDialogShow" type="primary">打開彈框</el-button>
          <el-button @click="onEmitData" type="primary">廣播數據</el-button>
        </div>
        <div>
          <demo-dialog v-if="BooleanFlag.isDemoDialogShow"></demo-dialog>
        </div>
      </div>
    </template>
    
    <script>
    import { mapState } from "vuex";
    import DemoDialog from "@/dialogs/DemoDialog";
    export default {
      components: {
        DemoDialog
      },
      computed: mapState(["BooleanFlag"]),
      methods: {
        // 彈框Demo
        onDialogShow() {
          this.$store.commit("BooleanFlag", ["isDemoDialogShow"]);
        },
        // 廣播事件
        onEmitData() {
          const messageObj = {
            message: "from page1"
          };
          this.$store.commit("EventBus", {
            Page1ToPage2: messageObj
          });
        }
      }
    };
    複製代碼
  4. 彈框組件的應用

    <template>
      <div>
        <el-dialog :title="title" :visible.sync="isShow" :width="width" custom-class="ht-dialog" :before-close="onCancle">
          <div class="dialog-container">
            彈框內容
          </div>
          <div class="bottom-buttons">
            <el-button @click="onCancle">{{$t('Common.cancel')}}</el-button>
            <el-button type="primary" @click="onSure">{{$t('Common.sure')}}</el-button>
          </div>
        </el-dialog>
      </div>
    </template>
    
    <script>
    export default {
      name: "DemoDialog",
      data() {
        return {
          title: "彈框標題",
          width: "500px",
          isShow: true
        };
      },
      methods: {
        onSure() {
          // 業務代碼
          this.onCancle()
        },
        onCancle() { // 關閉彈框
          this.$store.commit("BooleanFlag", ["isDemoDialogShow"]);
        }
      }
    };
    </script>
    複製代碼
  5. 兄弟頁面的應用(響應事件)

注意這裏要配合 來使用,採用監聽數據變化的方式來響應事件。java

<template>
  <div>
    page2下的內容
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  computed: mapState(["EventBus"]),
  watch: {
    "EventBus.Page1ToPage2": function(message) {
      console.log("Page1ToPage2", message);
    }
  }
};
</script>
複製代碼
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息