Vue + Element UI 前端篇(七):功能组件封装

news2024/11/25 1:41:39

组件封装

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

组件结构

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

代码一览

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 {
    width: 40px;
    float: left;
    cursor: pointer;
    border-color: rgba(111, 123, 131, 0.8);
    border-left-width: 1px;
    border-left-style: solid;
    border-right-width: 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 {
        width: 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 {
        width: 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 {
    width: 200px;
  }
  .menu-bar-collapse-width {
    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-width: 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

复制代码

测试效果

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/978038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql表操作-约束删除、用户填加、授权和撤权

目录 一、表的约束删除 1.查看所有表的约束条件 2.删除主键 3.删除唯一键 4.删除check键值 5.删除check键值 6.删除not null键值并删除check键值 7.删除键外值 8.检查表的约束条件是否存在 二、设置数据库密码策略 1.查看数据库密码的策略 2.修改数据库密码的长度 …

视频汇聚/视频云存储/视频监控管理平台EasyCVR安全检查的相关问题及解决方法2.0

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多…

Leetcode 1572.矩阵对角线元素之和

给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&#xff…

C#使用proto

写多了go代码&#xff0c;被go mod tidy惯坏了&#xff0c;还以为全天下的都很好用呢&#xff0c;结果发现并不是这样。尤其是项目组的proto还是又封了个工具直接就能跑得&#xff0c;导致以为没那么复杂的事情变得复杂了起来。是有两套生成的规则&#xff0c;时间有点晚&#…

【漏洞复现】网御ACM上网行为管理系统bottomframe.cgi接口存在SQL注入漏洞

漏洞描述 网御上网行为管理系统(简称Leadsec ACM)是网御为互联网接入用户在信息内容安全、网络应用管理、组织运营效率、网络资源利用、法律风险规避及网络投资回报等方面提供的全方位解决方案。网御上网行为管理系统存在SQL注入漏洞。 网御 ACM上网行为管理系统 bottomfram…

docker快速安装-docker一键安装脚本

1.下载/配置安装脚本 touch install-docker.sh #!/bin/bash #mail:ratelcloudqq.com #system:centos7 #integration: docker-latestclear echo "######################################################" echo "# Auto Install Docker …

【ABAP】 如何实现点击不同按钮动态显示不同的选择屏幕?(附完整示例代码)

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;阿里云社区专家博主&#xff0c;华为云云享专家&#xff0c;腾讯云社区认证作者&#xff0c;CSDN SAP应用技术领域优质创作者。在学习工作中&#xff0c;我通常使用偏后端的开发语言ABAP&#xff0c;SQL进行任务的完成…

Docker实战:docker compose 搭建Rocketmq

1、配置文件准备 1.1、 新建目录&#xff1a;/home/docker/data/rocketmq/conf mkdir /home/docker/data/rocketmq/conf1.2、 在上面目录下新建文件broker.conf文件&#xff0c;内容如下 brokerClusterName DefaultCluster brokerName broker-a brokerId 0 deleteWhen 0…

Linux命令之目录管理(详解)

Linux命令之目录管理 创建目录删除目录显示目录目录的拷贝返回上层目录目录的移动 创建目录 创建目录用 mkdir命令 mk–>make dir–>direction 同样的mkdir有很多选项&#xff0c;你可以通过用man命令查这个mkdir命令来获得 mkdir [选项] 目录名创建多级目录 mkdir -r /…

开源项目观察8月报

前言 总结8月份自己关注的一些项目/语言的新版本 大数据 hue 1月19: 4.11 https://docs.gethue.com/releases/release-notes-4.11.0/ 支持 iceberg 数据源 通过缓存 Livy session 中的信息来加速 SparkSQL&#xff0c;并适配 Spark UDF 支持 HPL/SQL: hive sql 的高级语法…

React 状态管理 - Redux 入门

目录 扩展学习资料 Redux基础 Redux动机 Redux核心概念 Redux的三个原则 Redux运转图 React & Redux的搭配使用 Redux API React-Redux API&#xff08;关联组件&#xff09; 从头创建一个工程 package.json /src/reducer/index.js /src/reducer/home/index.js…

springboot配置统一返回结果类

目录结构&#xff1a; Result类&#xff1a; package com.xxxx.common.result;import lombok.Data;Data public class Result<T> {//状态码private Integer code;//信息private String message;//数据private T data;//构造私有化private Result() { }//设置数据,返回对…

如何分库分表?

分析&回答 分库&#xff1f;分表&#xff1f;还是既分库又分表&#xff1f; 如果需要分表&#xff0c;那么分多少张表合适&#xff1f; 由于所有的技术都是为业务服务的&#xff0c;那么&#xff0c;我们就先从数据方面回顾下业务背景。 如果每天产生 8w 笔交易单&#…

RouterOS-配置PPPoEv4v6 Server

1 接口 ether3 出接口 ether4 内网接口 2 出接口 出接口采用PPPoE拨号SLAAC获取前缀&#xff0c;手动配置后缀 2.1 选择出接口interface&#xff0c;配置PPPoE client模式 2.2 配置PPPoE client用户名和密码 2.3 从PPPoE client获取前缀地址池 2.4 给出接口选择前缀并配置…

GIS:DataStore数据管理框架

1.架构设计 OGC 规范对空间矢量数据的框架进行了设计&#xff0c;GeoTools 对其进行了实现。其中的 DataStore 可以近似理解成关系数据库中的个数据库实例&#xff0c;FeatureSource 可以近似理解成关系数据库中的一张表。 DataAccess 接口主要对空间要素类型的相关信息的构建…

MySQL连接错误1045:完美解决指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

第五章 数据分析模型 题目学习(40%)

第一节 主成分的计算步骤&#xff1a;1、主成分建模&#xff0c;标准化处理。2、计算特征根、特征向量。3、选取主成分个数。 题目 选择B&#xff0c;依次递减。 相关系数和关联矩阵都做了标准化&#xff0c;做完标准化后方差就不会造成影响&#xff0c;所以选A。 A可以进行判断…

JavaScript-----对象(创建对象、数组与字符串)

目录 前言&#xff1a; 1. JavaScript创建对象 1.1 对象的创建 1.2 对象的调用 1.3 for-in循环语句 2.内置对象 2.1 Array&#xff08;数组&#xff09;对象 属性和方法 2.2 String&#xff08;字符串&#xff09;对象 属性和方法 2.3 Math对象 2.4 日期对象 前言&a…

华为云API对话机器人CBS的魅力—实现简单的对话操作

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI智能的问答管理、全面的对话管理、高效训练部署 1.IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts …

Unity项目包体优化经验方法论(Android平台)

前言 本篇文章主要讲解对于Unity Android平台也就是APK包体的优化经验&#xff0c;使用哪些工具能够更加便利的定位资源重灾区。本篇讲解的方法中对于Unity资源使用的AssetBundle的方式&#xff0c;如果使用addressable或其他资源管理方式&#xff0c;我还不是很清楚是否适用&…