zoukankan      html  css  js  c++  java
  • 功能组件封装(七)

    组件封装

    为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度。

    组件结构

    组件封装重构后,试图组件结构如下图所示

    代码一览

    Home组件被简化,包含导航、头部和主内容三个组件。

    Home.vue

    复制代码
    <template>
      <div class="container">
          <!-- 导航菜单栏 -->
          <MenuBar></MenuBar>
          <!-- 头部区域 -->
          <HeadBar></HeadBar>
          <!-- 主内容区域 -->
          <Main></Main>
      </div>
    </template>
    
    <script>
    import HeadBar from "./HeadBar/HeadBar"
    import MenuBar from "./MenuBar/MenuBar"
    import Main from "./Main/Main"
    export default {
      components:{
            HeadBar,
            MenuBar,
            Main
      }
    };
    </script>
    
    <style scoped lang="scss">
      .container {
        position:absolute;
        top: 0px;
        left: 0px;
        right: 0px;
        background: #4b5f6e;
      }
    </style>
    复制代码

    HeadBar.vue

    复制代码
    <template> 
      <div class="container">
        <!-- 导航菜单隐藏显示切换 -->
        <span class="collapse-switcher" @click.prevent="collapse">
          <i class="el-icon-menu"></i>
        </span>
        <!-- 导航菜单 -->
        <span class="nav-bar">
          <el-menu :default-active="activeIndex" class="el-menu-demo" text-color="#fff"
              active-text-color="#ffd04b" mode="horizontal" @select="selectNavBar()">
            <el-menu-item index="1" @click="$router.push('/')">{{$t("common.home")}}</el-menu-item>
            <el-menu-item index="2">{{$t("common.doc")}}</el-menu-item>
            <el-menu-item index="3">{{$t("common.msgCenter")}}</el-menu-item>
          </el-menu>
        </span>
        <span class="tool-bar">
          <!-- 主题切换 -->
          <ThemePicker class="theme-picker"></ThemePicker>
          <!-- 语言切换 -->
          <LangSelector class="lang-selector"></LangSelector>   
          <!-- 用户信息 -->
          <el-dropdown class="user-info-dropdown" trigger="hover">
            <span class="el-dropdown-link"><img :src="this.userAvatar" /> {{username}}</span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>{{$t("common.myMsg")}}</el-dropdown-item>
              <el-dropdown-item>{{$t("common.config")}}</el-dropdown-item>
              <el-dropdown-item divided @click.native="logout">{{$t("common.logout")}}</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </span>
      </div>
    </template>
    
    <script>
    import mock from "@/mock/index.js";
    import ThemePicker from "@/components/ThemePicker"
    import LangSelector from "@/components/LangSelector"
    export default {
      components:{
            ThemePicker,
            LangSelector
      },
      data() {
        return {
          isCollapse: false,
          username: "Louis",
          userAvatar: "",
          activeIndex: '1'
        };
      },
      methods: {
        selectNavBar(key, keyPath) {
          console.log(key, keyPath)
        },
        // 语言切换
        handleCommand(command) {
          let array = command.split(':')
          let lang = array[0] === '' ? 'zh_cn' : array[0]
          let label = array[1]
          document.getElementById("language").innerHTML = label
          this.$i18n.locale = lang
        },
        //折叠导航栏
        collapse: function() {
          this.isCollapse = !this.isCollapse;
        },
        //退出登录
        logout: function() {
          var _this = this;
          this.$confirm("确认退出吗?", "提示", {
            type: "warning"
          })
          .then(() => {
            sessionStorage.removeItem("user");
            this.$router.push
            ("/login");
          })
          .catch(() => {});
        }
      },
      mounted() {
        this.sysName = "I like Kitty";
        var user = sessionStorage.getItem("user");
        if (user) {
          this.userName = user;
          this.userAvatar = require("@/assets/user.png");
        }
      }
    };
    </script>
    
    <style scoped lang="scss">
    .container {
      position: absolute;
      left: 200px;
      right: 0px;
      height: 60px;
      line-height: 60px;
      .collapse-switcher {
         40px;
        float: left;
        cursor: pointer;
        border-color: rgba(111, 123, 131, 0.8);
        border-left- 1px;
        border-left-style: solid;
        border-right- 1px;
        border-right-style: solid;
        color: white;
        background: #504e6180;
      }
      .nav-bar {
        margin-left: auto;
        float: left;
        .el-menu {
          background: #504e6180;
        }
      }
      .tool-bar {
        float: right;
        .theme-picker {
          padding-right: 10px;
        }
        .lang-selector {
          padding-right: 10px;
          font-size: 15px;
          color: #fff;
          cursor: pointer;
        }
        .user-info-dropdown {
          font-size: 20px;
          padding-right: 20px;
          color: #fff;
          cursor: pointer;
          img {
             40px;
            height: 40px;
            border-radius: 10px;
            margin: 10px 0px 10px 10px;
            float: right;
          }
        }
      }
    }
    </style>
    复制代码

    MenuBar.vue

    复制代码
    <template>
        <div class="menu-bar-container">
        <!-- logo -->
        <div class="logo" :class="isCollapse?'menu-bar-collapse-width':'menu-bar-width'">
            <img :src="this.logo" /> <div>{{isCollapse?'':sysName}}</div>
        </div>
        <!-- 导航菜单 -->
        <el-menu default-active="1-1" :class="isCollapse?'menu-bar-collapse-width':'menu-bar-width'" @open="handleopen" @close="handleclose" @select="handleselect" :collapse="isCollapse">
          <el-submenu index="1">
            <template slot="title">
              <i class="el-icon-location"></i>
              <span slot="title">{{$t("sys.sysMng")}}</span>
            </template>
            <el-menu-item index="1-1" @click="$router.push('user')">{{$t("sys.userMng")}}</el-menu-item>
            <el-menu-item index="1-2" @click="$router.push('dept')">{{$t("sys.deptMng")}}</el-menu-item>
            <el-menu-item index="1-3" @click="$router.push('role')">{{$t("sys.roleMng")}}</el-menu-item>
            <el-menu-item index="1-4" @click="$router.push('menu')">{{$t("sys.menuMng")}}</el-menu-item>
            <el-menu-item index="1-5" @click="$router.push('log')">{{$t("sys.logMng")}}</el-menu-item>
          </el-submenu>
          <el-submenu index="2">
            <template slot="title">
              <i class="el-icon-location"></i>
              <span slot="title">{{$t("sys.sysMonitor")}}</span>
            </template>
          </el-submenu>
          <el-menu-item index="3" disabled>
            <i class="el-icon-document"></i>
            <span slot="title">{{$t("sys.nav3")}}</span>
          </el-menu-item>
          <el-menu-item index="4">
            <i class="el-icon-setting"></i>
            <span slot="title">{{$t("sys.nv4")}}</span>
          </el-menu-item>
        </el-menu>
        </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          isCollapse: false,
          sysName: "",
          logo: "",
        };
      },
      methods: {
        handleopen() {
          console.log('handleopen');
        },
        handleclose() {
          console.log('handleclose');
        },
        handleselect(a, b) {
          console.log('handleselect');
        }
      },
      mounted() {
        this.sysName = "I like Kitty";
        this.logo = require("@/assets/logo.png");
      }
    };
    </script>
    
    <style scoped lang="scss">
    .menu-bar-container {
      .el-menu {
        position:absolute;
        top: 60px;
        bottom: 0px;
        text-align: left;
      }
      .logo {
        position:absolute;
        top: 0px;
        height: 60px;   
        line-height: 60px;
        background: #4b5f6e;
        img {
             40px;
            height: 40px;
            border-radius: 0px;
            margin: 10px 10px 10px 10px;
            float: left;
        }
        div {
          font-size: 22px;
          color: white;
          text-align: left;
        }
      }
      .menu-bar-width {
         200px;
      }
      .menu-bar-collapse-width {
         65px;
      }
    }
    </style>
    复制代码

    Main.vue

    复制代码
    <template>
      <div class="container">
        <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>
        <transition name="fade" mode="out-in">
          <router-view></router-view>
        </transition>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
        };
      },
      methods: {
    
      },
      mounted() {
    
      }
    };
    </script>
    
    <style scoped lang="scss">
    .container {
      position: absolute;
      top: 60px;
      bottom: 0px;
      left: 200px;
      right: 0px;
      .breadcrumb {
        padding: 10px;  
        border-color: rgba(38, 86, 114, 0.2);
        border-bottom- 1px;
        border-bottom-style: solid;
        background: rgba(138, 158, 170, 0.2);
      }
    }
    </style>
    复制代码

    国际化语言切换也被封装成为了组件 LangSelector

    LangSelector/index.js

    复制代码
    <template>
      <el-dropdown class="lang-selector" @command="handleCommand">
        <span class="el-dropdown-link">
          <span id="language">中文</span><i class="el-icon-arrow-down el-icon--right"></i>
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="zh_cn:中文">中文</el-dropdown-item>
          <el-dropdown-item command="en_us:English">English</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </template>
    
    <script>
      export default {
        methods: {
          // 语言切换
          handleCommand(command) {
            let array = command.split(':')
            let lang = array[0] === '' ? 'zh_cn' : array[0]
            let label = array[1]
            document.getElementById("language").innerHTML = label
            this.$i18n.locale = lang
          }
        }
      }
    </script>
    复制代码

    组件封装重构之后,同步修改路由配置

    复制代码
    import Vue from 'vue'
    import Router from 'vue-router'
    import Login from '@/views/Login'
    import NotFound from '@/views/404'
    import Home from '@/views/Home'
    import Intro from '@/views/Intro'
    import User from '@/views/SysMng/User'
    import Dept from '@/views/SysMng/Dept'
    import Role from '@/views/SysMng/Role'
    import Menu from '@/views/SysMng/Menu'
    import Log from '@/views/SysMng/Log'
    
    Vue.use(Router)
    
    const router = new Router({
      routes: [
        {
          path: '/',
          name: '首页',
          component: Home,
          children: [
            { path: '', component: Intro, name: '系统介绍' },
            { path: '/user', component: User, name: '用户管理' },
            { path: '/dept', component: Dept, name: '机构管理' },
            { path: '/role', component: Role, name: '角色管理' },
            { path: '/menu', component: Menu, name: '菜单管理' },
            { path: '/log', component: Log, name: '日志管理' }
          ]
        },
        {
          path: '/login',
          name: '登录',
          component: Login
        }
        ,{
          path: '/404',
          name: 'notFound',
          component: NotFound
        }
      ]
    })
    
    router.beforeEach((to, from, next) => {
      // 登录界面登录成功之后,会把用户信息保存在会话
      // 存在时间为会话生命周期,页面关闭即失效。
      let user = sessionStorage.getItem('user');
      if (to.path == '/login') {
        // 如果是访问登录界面,如果用户会话信息存在,代表已登录过,跳转到主页
        if(user) {
          next({ path: '/' })
        } else {
          next()
        }
      } else {
        // 如果访问非登录界面,且户会话信息不存在,代表未登录,则跳转到登录界面
        if (!user) {
          next({ path: '/login' })
        } else {
          next()
        }
      }
    })
    
    export default router
    复制代码

    测试效果

    封装重构之后,启动界面,效果跟之前差别不大。

     原文出处:https://www.cnblogs.com/xifengxiaoma/ 
    自己整理记录。

  • 相关阅读:
    HOJ 2139 Spiderman's workout(动态规划)
    FZU 2107 Hua Rong Dao(dfs)
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 计算机存储中有多少字节
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 合法括号序列
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
    Java 第十一届 蓝桥杯 省模拟赛 无向连通图最少包含多少条边
  • 原文地址:https://www.cnblogs.com/windok/p/10681871.html
Copyright © 2011-2022 走看看