Vue + Element UI 實現權限管理系統 前端篇(八):管理應用狀態

使用 Vuex 管理應用狀態

1. 引入背景

像先前咱們是有導航菜單欄收縮和展開功能的,可是由於組件封裝的緣由,隱藏按鈕在頭部組件,而導航菜單在導航菜單組件,這樣就涉及到了組件收縮狀態的共享問題。收縮展開按鈕觸發收縮狀態的修改,導航菜單須要根據收縮狀態來設置導航欄的寬度。這樣就須要在收縮狀態變動時刷新導航菜單樣式。後續相似的組件狀態共享還會有許多。爲了解決組件間狀態的共享,增長組件交互的易用性,咱們引入 vuex 專門管理應用狀態。css

2. 安裝依賴

執行如下命令,安裝 vuex 依賴。前端

yarn add vuex

3. 添加配置

3.1 添加 Store

在 src 目錄下,新建一個 store 目錄,專門管理應用狀態,在 index.js 中建立 store。vue

 

index.jsgit

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex);

const store = new vuex.Store({
    state:{
        collapse:false  // 導航欄收縮狀態
    },
    mutations:{
        collapse(state){  // 改變收縮狀態
            state.collapse = !state.collapse;
        }
    }
})

export default store

3.2 引入 Store

 在 main.js 引入 storevuex

4. 使用 Store

4.1 修改狀態

在原先響應摺疊導航欄的函數內替換原有邏輯,改成發送提交請求來改變收縮狀態。後端

4.2 獲取狀態

在原先引用 collapse 的地方改成引用 $store.state.collapse 。app

根據收縮狀態綁定不一樣樣式,就能夠實現導航菜單欄根據收縮狀態更新頁面效果了。svg

MenuBar.vue模塊化

HeadBar.vue函數

 Main.vue

5. 測試效果

進入主頁,點擊收縮按鈕,效果以下圖。

Store 模塊化

如今咱們的狀態都維護在index.js,狀態一多就會出現臃腫,這裏能夠根據需求進行模塊化。

1. 文件結構

模塊化後的文件結構

2. Store 封裝

改寫index.js,引入模塊化,這裏把以前的狀態抽取到AppStore,後續可能還會有UserStore、MenuStore之類的。

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex);

import AppStore from './modules/AppStore.js';

const store = new vuex.Store({
    modules: {
        app: AppStore   
        // 其餘
    }
})

export default store

AppStore.js

export default {
    state: {
        appName: "I like Kitty",  // 應用名稱
        collapse:false  // 導航欄收縮狀態
    },
    getters: {
        collapse(state){// 對應着上面state
            return collapse;
        }
    },
    mutations: {
        collapse(state){  // 改變收縮狀態
            state.collapse = !state.collapse;
        }
    },
    actions: {

    }
}

 3. 狀態引用

在引用 store 狀態的地方加上模塊名稱

若是一個文件內引用過多,嫌引用路勁又長又臭,可使用 mapState、mapGetter、mapActions 工具進行簡化。

如 MenuBar.vue 中引用較多,咱們用 mapState 簡化對屬性的引用。以下圖,給狀態賦予別名。

 引用狀態的地方就能夠直接用上面定義的別名進行訪問了。

 

mapState、mapGetter、mapActions 工具對於文件內大量又長又臭的狀態引用時很是有用,能夠適當的運用。

封裝收縮組件

1. 組件封裝

 以下圖,新建目錄和文件,封裝收縮組件展開導航欄組件。

Hamburger/index.vue

<template>
  <svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
    version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
    <path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
      p-id="1692"></path>
    <path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
      p-id="1693"></path>
    <path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
      p-id="1694"></path>
  </svg>
</template>

<script>
export default {
  name: 'hamburger',
  props: {
    isActive: {
      type: Boolean,
      default: false
    },
    toggleClick: {
      type: Function,
      default: null
    }
  }
}
</script>

<style scoped>
.hamburger {
  display: inline-block;
  cursor: pointer;
  width: 20px;
  height: 20px;
  transform: rotate(90deg);
  transition: .38s;
  transform-origin: 50% 50%;
}
.hamburger.is-active {
  transform: rotate(0deg);
}
</style>

2. 引入組件

HeadBar.vue 中引入組件

響應函數,經過 store 修改收縮狀態

3. 測試效果

進入主頁,效果以下圖。

 

封裝麪包屑組件

將麪包屑從主內容中抽取出來,封裝成 BreadCrumb。

BreadCrumb/index.vue

<template>
  <el-breadcrumb separator="/" class="breadcrumb">
    <el-breadcrumb-item v-for="item in $route.matched" :key="item.path">
      <a href="www.baidu.com">{{ item.name }}</a>
    </el-breadcrumb-item>
  </el-breadcrumb>
</template>

<script>
export default {
  data() {
    return {
    };
  },
  methods: {

  },
  mounted() {

  }
};
</script>

<style scoped lang="scss">
.breadcrumb {
  padding: 10px;  
  border-color: rgba(38, 86, 114, 0.2);
  border-bottom-width: 1px;
  border-bottom-style: solid;
  // background: rgba(180, 189, 196, 0.1);
}
</style>

main.js 中 引入

動態換膚

1. 功能背景

以前的動態換膚,只能刷新 Element 相關組件的顏色,而若是咱們但願在換膚的時候咱們的頭部區域也同步改變就須要作進一步的修改了。接下來,咱們就實現這個功能,賦予換膚組件在更新 Element 組件顏色的時候,能夠定製插入一些自定義的操做。

2. 改進ThemePicker 

修改 ThemePicker 插件, 綁定導出函數和主題色參數。

3. 父組件函數綁定

在父組件綁定處理函數,增長自定義同步更新邏輯。

這裏是切換主題顏色的時候,設置 store 狀態,保存共享主題色,這樣其餘綁定主題色的組件均可以自動更新了。

4. 添加共享狀態

在 store 中定義主題色相關的狀態。

5. 共享狀態引入

在要使用的組件處引入主題色狀態。

組件樣式綁定主題色狀態,主題色並更時,更新組件背景色樣式。

6. 測試效果

進入主頁,點擊動態換膚取色器,換膚效果以下。

 

源碼下載

後端:https://gitee.com/liuge1988/kitty

前端:https://gitee.com/liuge1988/kitty-ui.git


做者:朝雨憶輕塵
出處:https://www.cnblogs.com/xifengxiaoma/ 版權全部,歡迎轉載,轉載請註明原文做者及出處。

相關文章
相關標籤/搜索