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/ 版权全部,欢迎转载,转载请注明原文做者及出处。

相关文章
相关标签/搜索