系统简介

  • 此管理系统是基于Vite2和Vue3.0构建生成的后台管理系统。目的在于学习vite和vue3等新技术,以便于后续用于实际开发工作中;
  • 本文章将从管理系统页面布局、vue路由鉴权、vuex状态管理、数据持久化、用户信息加密等方面进行介绍和记录;
  • 这也是我边学习边实践的过程,此次记录一是方便自己日后开发过程中有用到时候便于借鉴和复习,再次是为了初学vue3和尝试上手vite2和vue3搭建管理系统的小伙伴提供一些学习方法和技术点;
  • 本Vue后台管理系统使用的技术点主要有:vite2vue3vue-router4.xvuex4.x、vuex-persistedstate(vuex数据持久化)、Element Plus等。

用户登录

登录页面代码

<template>
<div class="login">
<el-card class="login_center">
<template #header>
<div class="card_header">
<span>用户登录</span>
</div>
</template>
<el-form :model="loginFormState" :rules="rules" ref="loginFormRef">
<el-form-item prop="name">
<el-input
prefix-icon="el-icon-user-solid"
v-model.trim="loginFormState.name"
maxlength="32"
placeholder="请输入账号"
clearable
></el-input>
</el-form-item>
<el-form-item prop="pwd">
<el-input
prefix-icon="el-icon-lock"
v-model.trim="loginFormState.pwd"
maxlength="16"
show-password
placeholder="请输入密码"
clearable
@keyup.enter.exact="handleLogin"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" style="width: 100%" :loading="loginFormState.loading" @click="handleLogin">登 录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>

登录逻辑代码

import { getCurrentInstance, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { encode } from "js-base64"; export default {
setup() {
const { proxy } = getCurrentInstance();
const router = useRouter();
const store = useStore();
const loginFormRef = ref(); const loginFormState = reactive({
name: "",
pwd: "",
loading: false
}); const rules = {
name: [{ required: true, message: "账号不能为空", trigger: "blur" }],
pwd: [
{ required: true, message: "密码不能为空", trigger: "blur" },
{ min: 5, max: 16, message: "密码长度为5-16位", trigger: "blur" }
]
}; const handleLogin = () => {
loginFormRef.value.validate(valid => {
if (!valid) {
return false;
} loginFormState.loading = true; let params = { name: loginFormState.name, pwd: loginFormState.pwd }; setTimeout(() => {
let users = { role: loginFormState.name === "admin" ? "admin" : "", username: loginFormState.name };
Object.assign(params, users);
sessionStorage.setItem("jwt", encode(JSON.stringify(params)));
store.dispatch("setUser", params);
loginFormState.loading = false;
router.replace("/");
}, 1000); // proxy.$axios
// .post("/user/login", proxy.$qs.stringify(params))
// .then(res => {
// let { code, result_data, message } = res.data;
// if (code == 1) {
// console.log("login_success", result_data);
// ElMessage.success("登录成功");
// } else {
// ElMessage.error("登录失败:" + message);
// }
// })
// .catch(err => {
// console.log("login err", err);
// ElMessage.error("登录失败");
// });
});
}; return { loginFormRef, loginFormState, rules, handleLogin };
}
};

登录简介:

  • 登录页面采用的是一级录用,与控制台的路由同级,这样写便于对vue-router路由权限校验的控制;
  • 在vue2中我们频繁使用 this 来处理事件函数和组件数据,vue3大多事件函数和数据状态的存储基本都实在setup函数中完成的,在vue3中无法通过 this 来获取当前组件的实例,故无法像vue2中那样操作数据和事件函数;
  • vue3中为了获取到当前组件的实例,我们可以采用 vue3中提供的 getCurrentInstance 来获取组件的实例;
  • 当我们使用全局对象或者函数时,我们大多是将事件函数绑定在vue的原型实例上,当再次访问时只需使用过this来访问自己指定的事件名即可;
  • 在vue3中我们若是使用全局变量或者事件函数时,我们需要借助 globalProperties 来实现全局事件函数的绑定;此时在需要使用的地方可以通过当前组件实例来访问全局的 property 属性;
  • 对登录用的的信息进行加密处理,我采用的是 js-base64 的 encode 方法来实现登录信息的加密。使用方式为:encode(“需要加密的JSON字符串”)。

系统主页

Layout布局代码

<template>
<el-header height="56px">
<!-- header -->
<div class="header_left">Element-Plus Create By Vite</div>
<div class="header_right">
<!-- 退出全屏、进入全屏按钮 -->
<el-tooltip :content="isFullScreen ? '退出全屏' : '全屏'">
<i class="el-icon-full-screen" @click="handleFullScreen"></i>
</el-tooltip>
<!-- 下拉菜单 -->
<el-dropdown size="medium" @command="handleCommand">
<!-- 用户信息 -->
<div class="user_info">
<!-- 用户头像 -->
<el-avatar :size="36" :src="avatar" />
<!-- 用户名宁 -->
<span class="username">{{ userName }}</span>
</div>
<template #dropdown>
<!-- 折叠菜单 -->
<el-dropdown-menu>
<el-dropdown-item icon="el-icon-user" command="user">个人中心</el-dropdown-item>
<el-dropdown-item icon="el-icon-switch-button" command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
</template> <!-- 二级路由公用路由页面 -->
<template>
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</template>

主页Header相关逻辑

import { computed, getCurrentInstance, reactive, toRefs } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import screenfull from "screenfull";
import avatar from "@/assets/img/admin.png"; export default {
setup() {
const { proxy } = getCurrentInstance();
const router = useRouter();
const store = useStore(); const state = reactive({
isFullScreen: false,
avatar,
screenfull
});
const userName = computed(() => store.getters.getUserName); const handleCommand = command => {
if (command === "user") {
router.push("/user");
} else {
proxy.$message.success("退出成功");
store.dispatch("clearUser");
router.replace("/login");
sessionStorage.clear();
localStorage.clear();
}
}; const handleFullScreen = () => {
if (screenfull.isEnabled) {
state.isFullScreen = !state.isFullScreen;
screenfull.toggle();
}
}; return {
userName,
handleCommand,
handleFullScreen,
...toRefs(state)
};
}
};

注:

  • Header分左右两部分,其中左侧为系统的名字,右侧为用户登录的账户相关的信息以及进入和退出全屏的按钮;
  • 不同用户权限会对应不同的账户头像,会对不同账户的用户权限做相应的限制处理;
  • 全屏的切换借助的是第三方的插件进行处理的,此方式减少代码量的同时也减少了不同浏览器兼容性问题的出现;
  • 退出账户逻辑的处理,当用户点击退出账户的时候进行相应的退出登录的弹窗提示,在退出后进行数据的初始化和本地存储信息的清除处理,并跳转到用户登录页。
  • 主页使用了地图模块,地图模块是借助的“高德地图”API实现的H5版的网页地图,此Demo需要使用注册高德地图开发者来获取开发的keys来创建地图实例;
  • 本笔记主要就后台管理系统做笔记分析,高德地图此处不做过多介绍,若想进一步了解,请前往高德开放平台进行了解学习。

数据管理

<template>
<el-card shadow="never" class="index">
<template #header>
<div class="card_header">
<b>数据列表</b>
</div>
</template>
<el-empty description="暂无数据"></el-empty>
</el-card>
</template> <script></script> <style lang="scss" scoped>
.card_header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

注:没有数据时的提示信息;

视频播放器

<template>
<el-card shadow="never" class="index">
<template #header>
<div class="card_header">
<b>西瓜播放器</b>
</div>
</template>
<div id="xg"></div>
</el-card>
</template> <script>
import { onMounted, onBeforeUnmount, getCurrentInstance, ref } from "vue";
import Player from "xgplayer"; export default {
setup() {
const { proxy } = getCurrentInstance(); let player;
onMounted(() => {
initPlayer();
}); onBeforeUnmount(() => {
player.destroy();
player = null;
}); const initPlayer = () => {
player = new Player({
id: "xg",
url: "https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4",
poster: "https://img03.sogoucdn.com/app/a/07/f13b5c3830f02b6db698a2ae43ff6a67",
fitVideoSize: "auto",
fluid: true /* 流式布局 */,
// download: true /* 视频下载 */
// pip: true /* 画中画 */,
// errorTips: `请<span>刷新页面</span>试试` /* 自定义错误提示 */,
lang: "zh-cn"
});
}; return {};
}
};
</script> <style lang="scss" scoped>
.card_header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

注:

  • 安装西瓜视频播放器:yarn add xgplayer
  • 西瓜播放器官方文档:http://v2.h5player.bytedance.com/
  • 西瓜播放器适合手机版和PC电脑版视频点播或直播使用,详细参数配置请参考官方文档。

富文本编辑器

富文本编辑器插件封装

<template>
<div ref="editor" class="editor_ref"></div>
</template> <script>
import { onMounted, onBeforeUnmount, watch, getCurrentInstance, ref } from "vue";
import WEditor from "wangeditor"; export default {
props: {
defaultText: { type: String, default: "" }
},
setup(props, context) {
const { proxy } = getCurrentInstance();
const editor = ref(); let instance;
onMounted(() => {
initEditor();
}); onBeforeUnmount(() => {
instance.destroy();
instance = null;
}); watch(
() => props.defaultText,
nv => {
instance.txt.html(nv);
!!nv && context.emit("richHtml", nv);
}
); const initEditor = () => {
instance = new WEditor(editor.value);
// 配置富文本
Object.assign(instance.config, {
zIndex: 100,
// placeholder: "" /* 提示文字 */,
showFullScreen: true /* 显示全屏按钮 */,
showLinkImg: true /* 显示插入网络图片 */,
showLinkVideo: true /* 显示插入网络视频 */,
onchangeTimeout: 400 /* 触发 onchange 的时间频率,默认 200ms */,
uploadImgMaxLength: 1 /* 单次上传图片数量限制 */,
uploadImgMaxSize: 5 * 1024 * 1024 /* 上传图片大小限制 */,
uploadVideoAccept: ["mp4", "mov"] /* 上传视频格式限制 */,
uploadVideoMaxSize: 1024 * 1024 * 1024 /* 上传视频大小限制1024m */,
excludeMenus: ["strikeThrough", "todo", "code"] /* 移除系统菜单 */,
customAlert(msg, type) {
type == "success" ? proxy.$message.success(msg) : proxy.$message.error(msg);
},
customUploadImg(resultFiles, insertImgFn) {
/**
* @param {Object} file - 文件对象
* @param {String} rootPath - 文件根路径(默认为空、例:“filepath/”)
* @param {Array} fileType - 文件类型限制(默认 [] 不限制,例:['.png','.jpeg'])
* @param {Number} size - 文件大小限制(单位:兆、默认 0 不限制、例:1)
**/
proxy.$oss(resultFiles[0]).then(imgUrl => !!imgUrl && insertImgFn(imgUrl));
}, customUploadVideo(resultFiles, insertVideoFn) {
proxy.$oss(resultFiles[0]).then(videoUrl => !!videoUrl && insertVideoFn(videoUrl)); /* 参数同上 */
},
onchange(nv) {
context.emit("richHtml", nv);
}
});
instance.create();
}; return { editor };
}
};
</script> <style scoped>
div.editor_ref :deep(iframe) {
max-width: 100%;
max-height: auto;
width: 360px;
height: 180px;
}
</style>

组件内使用

<template>
<el-card shadow="never" class="index">
<template #header>
<div class="card_header">
<b>富文本编辑器</b>
</div>
</template>
<!-- 富文本 -->
<WEditor :defaultText="defaultText" @richHtml="getRichHtml" />
</el-card>
</template> <script>
import { onMounted, ref } from "vue";
import WEditor from "../../components/WEditor.vue"; export default {
components: { WEditor },
setup() {
const defaultText = ref("");
const richText = ref(""); onMounted(() => {
// 初始化数据
defaultText.value = "<h1>Editor</h1>";
}); const getRichHtml = nv => {
richText.value = nv;
}; return { defaultText, getRichHtml };
}
};
</script>

注:

  • 此次是基于Vue3封装的富文本编辑器,编辑器使用的是开源的富文本编辑器wangeditor;
  • 代码块一是基于官方文档和配置信息对富文本编辑器进行的相关配置,其中富文本编辑器使用的ali-OSS的云存储,若想详细了解请参照之前的“阿里云文件直传”博客笔记进行了解和学习;
  • ref相当于DOM元素的Id,要保持唯一,若一个页面要使用多个富文本编辑器,请做好区分,以便于区分组件的数据。

个人中心

总结

本篇文章主要介绍使用element-plus进行页面的布局和数据展示处理,后续笔记将继续分享和介绍动态路由菜单的处理,以及用户权限的动态校验。(。・・)ノ

源码地址

Vue3后台管理系统源代码地址

vue3后台管理系统(模板)的更多相关文章

  1. vue3项目后台管理系统模板

    Vue3.0 发布第一个版本至今有一段时间了,到现在一直在更新优化,在性能方面,对比 Vue2.x ,性能的提升比较明显,打包后体积更小 来看下 Vue3.x 新增了哪些功能和特性. Performa ...

  2. VUE3后台管理系统【路由鉴权】

    前言: 在"VUE3后台管理系统[模板构建]"文章中,详细的介绍了我使用vue3.0和vite2.0构建的后台管理系统,虽然只是简单的一个后台管理系统,其中涉及的技术基本都覆盖了, ...

  3. Admin Panel – 非常漂亮的后台管理系统模板

    网站或者应用系统的管理后台的设计虽然不像前台界面那样要求设计精美,但是也需要有清晰的管理模块划分,下面分享的这个后台管理模板的设计非常漂亮,特别是导航部分,头部还有未读的短消息和提醒的条数显示.赶紧下 ...

  4. easyui+ztree 后台管理系统模板

    用easyui+ztree做了个后台管理系统模板,效果图: 下载地址: csdn:http://download.csdn.net/detail/jackpay/6744505 github:http ...

  5. 3YAdmin-专注通用权限控制与表单的后台管理系统模板

    3YAdmin基于React+Antd构建.GitHub搜索React+Antd+Admin出来的结果没有上百也有几十个,为什么还要写这个东西呢? 一个后台管理系统的核心我认为应该是权限控制,表单以及 ...

  6. Bootstrap 轻量级后台管理系统模板--ACE使用介绍

    在上一篇基于Bootstrap介绍了一个免费的后台管理模板Charisma UI. 参见链接: 基于Jquery.Bootstrap的后台管理免费UI框架推荐--Charisma UI 今天继续分享一 ...

  7. SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑

    (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y-h/p ...

  8. SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(一): 搭建基本环境、整合 Swagger、MyBatisPlus、JSR303 以及国际化操作

    相关 (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y- ...

  9. vue+element-ui JYAdmin后台管理系统模板-集成方案【项目搭建篇2】

    项目搭建时间:2020-06-29 本章节:讲述基于vue/cli, 项目的基础搭建. 本主题讲述了: 1.跨域配置 2.axios请求封装 3.eslint配置 4.环境dev,test,pro(开 ...

随机推荐

  1. 重新整理 .net core 实践篇————依赖注入应用之生命法则[三]

    前言 该章演示依赖注入中,对象的释放行为. 紧接上文表示,演示: services.AddSingleton<IMySingletonService, MySingletonService> ...

  2. PHP转JAVA开发30分钟实战攻略

    服务端开发中,有很多知识是相通的,例如mysql,redis,http协议等. 基于这些基础,在编程语言上的转变并不困难. 本文主要从下面几点出发,讲述如何快速从php开发转为java开发: 使用框架 ...

  3. 硬件安全模块如何启用AUTOSAR

    硬件安全模块如何启用AUTOSAR How hardware security modules enable AUTOSAR 越来越复杂的软件和车内连接需要越来越多的加密保护.这种保护也必须由经典的实 ...

  4. CSS 常见问题笔记

    CSS 常见问题 布局 一.盒模型宽度计算 问题:div1 的 offsetWidth 是多少? <style> #div1 { width: 100px; padding: 10px; ...

  5. python读取配置文件,yaml模块读取yml文件

    ymal文件编写语法参考http://www.ruanyifeng.com/blog/2016/07/yaml.html ymal在python中的安装:pip install pyyaml yml文 ...

  6. zookeeper分布式锁,解决了羊群效应, 真正的zookeeper 分布式锁

    zookeeper 实现分布式锁,监听前一个节点来避免羊群效应, 思路:很简单,但是实现起来要麻烦一些, 而且我也是看了很多帖子,发现很多帖子的代码,下载下来逐步调试之后发现,看起来是对的,但在并发情 ...

  7. SpringCloud Alibaba实战(5:子模块基本业务开发)

    源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 在上一节里,我们搭建了一个微服务项目的整体架构,并进行了版本控制. 接下来我们进一步 ...

  8. 如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1。 如果不是这样,则返回0

    ''' 它接受数字num1和num2,如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1. 如果不是这样,则返回0 例子 triple_double(4519 ...

  9. 一、DNS服务器的搭建

    一.介绍 DNS服务:域名解析   将域名解析ip地址 DNS服务器的功能– 正向解析:根据注册的域名查找其对应的IP地址– 反向解析:根据IP地址查找对应的注册域名,不常用 所有完整的域名都要以点结 ...

  10. 『无为则无心』Python基础 — 3、搭建Python开发环境

    目录 1.Python开发环境介绍 2.Python解释器的分类 3.下载Python解释器 4.安装Python解释器 5.Python解释器验证 1.Python开发环境介绍 所谓"工欲 ...