Vue _ 后台管理

news/2024/7/23 22:07:12 标签: Vue

目录

一、后台管理

1.1、elmentui 安装与配置

1.2、后台登录

1.2.1、全局混入实现自定义验证提取

1.2.2、局部混入实现自定义验证规则

1.2.3、登录按钮实现防抖处理

1.3、后台登录接口编写

1.3.1、jwt

1.3.2、生成 jwt 凭证

1.3.3、网络请求封装

1.4、权限控制

1.4.1、登录权限

1.4.2、菜单权限

1.4.3、路由权限

1.4.4、按钮

富文本编辑器

自动化 导入 路由 配置 文件 : 

Vuex%C2%A0%20%E6%A8%A1%E5%9D%97%E5%8C%96%E9%85%8D%E7%BD%AE%20%E6%96%87%E4%BB%B6%20%3A%C2%A0-toc" style="margin-left:80px;">自动化 导入 Vuex  模块化配置 文件 : 


后台管理

1.1、elmentui 安装与配置

Element  UI  组件库 :

Element - The world's most popular Vue UI framework

elementui 组件库,此组件库只针对于 pc 端 ,一般用于 后台管理系统

npm i element-ui -S

"element-ui" : "^2.15.6"

npm install babel-plugin-component -D

"babel-plugin-component" : "^1.1.1"

将我们 根目录 下的 babel.config.js 修改如下 :

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

然后在 main.js 文件内 导入我们刚刚创建好的 组件文件 element.js

配置 OK =>  启动服务器 ( npm run serve )

下面让我们先来简单上手测试一下 :

先用简单的按钮来进行测试一下看是否成功 ,


1.2、后台登录

一个简易的登录页面 :

<template>
  <div class="login">
    <el-form
      :model="ruleForm"
      status-icon
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="账号" prop="username">
        <el-input
          type="text"
          v-model="ruleForm.username"
          autocomplete="off"
        ></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input
          type="text"
          v-model="ruleForm.password"
          autocomplete="off"
        ></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
          >提交</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      loading: false,
      ruleForm: {
        username: "",
        password: "",
        // checkPass: "",
      },
      rules: {
        username: [
          { required: true, message: "账号不能为空" },
          // 自定义验证规则实现规则定义
          { validator: this.validateUsername },
          // {type:'string',regexp://}
        ],
        password: [
          { required: true, message: "密码不能为空" },
          { validator: this.validatePassword },
        ],
      },
    };
  },
  methods: {
    // 自定义验证规则 ( 最终要拆分出去 : 利用混入 )
    validateUsername(rule, value, callback) {
      if (/^\s+$/.test(value)) {
        callback(new Error("空格不能当用户名"));
      } else {
        callback();
      }
    },
    validatePassword(rule, value, callback) {
      if (/^\s+$/.test(value)) {
        callback(new Error("空格不能当密码"));
      } else {
        callback();
      }
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert("submit!");
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

<style lang="scss" scoped>
  .login {
    width: 500px;
    margin: 100px auto;
    border: 10px solid skyblue;
    border-radius: 10px;
    padding: 20px 30px 0 0;
  }
</style>

1.2.1、全局混入实现自定义验证提取

1.2.2、局部混入实现自定义验证规则

1.2.3、登录按钮实现防抖处理

不断点击登陆按钮时 , 会一直触发提交功能 , 消耗浏览器性能 , 需进行防抖优化处理 :

利用 elementUI 组件库内的 : Message 消息提示 ( onClose  参数 )

Button 按钮 ( loading  和  disabled  参数 )

 

 

1.3、后台登录接口编写

写后端接口所需下载的 第三方包 :

测试后端接口使用的工具插件 : Apizza


1.3.1、jwt

在之前的项目中,大部分网页是通过 session 来判断用户是否有权限来访问个别网页的,但是如果是 SPA 项目的话,前后端 分离,客户请求的是 前端 ,所以并不会保存数据到 session ,那该怎么办呢?针对这一问题,可以使用  jwt  来解决!

JWT 也就是 JSON Web Token( JWT ),是目前最流行的 跨域身份验证 解决方案 。

JWT 的组成 :一个 JWT 实际上就是一个 字符串 ,它由 三部分 组成 :头 部 ( Header ) 、载 荷   ( Payload ) 与 签名 ( signature ) 。生成一个 加密后的字符串 ,发送给 客户端 ,客户端保存在浏览器中 ( cookie / localstorage / sessionstorage ) , 在客户端请求敏感数据时,需要必须让客户端在 头部 ( Header ) 携带 加密 的字符串 ( token ) 给服务器,服务器获取到 token 值后,进行 解密 ,进行信息的比对,如果 比对成功则返回数据,不对则不返回数据

1.3.2、生成 jwt 凭证

nodejs  中  jsonwebtoken  提供了一套( jwt )加密  和 解码的 算法

  • 安装

npm i -S jsonwebtoken

  • 加密 解密

var token = require("jsonwebtoken");

// 加密 生成密钥 key

var key = token.sign( 数据 , 加密串 );

// 解密 通过加密串将密钥解密还原

var source = token.verify( key, 加密串 );

正式测试一下自己所写的后端请求端口 :

1.3.3、网络请求封装

下载 axios 第三方

npm i -S axios

"axios": "^0.24.0",

src / utils / request.js

封装 sessionStorage 会话存储 的 Api 方法 :

操作方法 Api :

import store from './sessionStore'
const key = 'token'
export const setToken = token => store.set(key, token)
export const getToken = () => store.get(key)
export const delToken = () => store.del(key)
// 判断是否有 token
export const hasToken = () => store.get(key) === '' ? false : true

loginAction 是一个 Promise

    登录成功跳转页面之后 在 sessionStorage 内为什么能够成功写入数据呢 ?

    是因为首先你一定要有一个 返回值 (boolean)

    如果你不写返回值的话 , 因为这个写入是异步的 , 而跳转又是同步的 ,

    你可能会出现的异常情况就是 : 你写入数据写了一半时 , 它跳转走了 , 导致你的数据一会有一会又没有了

    所以你每次登录的时候每次都是第一次登录不成功 , 第二次登录就成功了的原因所在

    (第一次你写了一半的时候它跳转走了 , 第二次在写的时候又把第一次的写进去了 , 第二次用的其实就是第一次的了 , 但是给人的感觉就像是第二次才登录成功了)

    但是你有了返回值 ( boolean )就没有问题了 , Promise 得到了你成功 ( true ) 了之后才会再执行下一步的操作

src / config / api / loginConfig.js

src / api / loginApi.js

src / store / module / user.js

// 导入请求的方法
import { doLoginApi } from '@/api/loginApi'

import { setUid } from '@/utils/uid'
import { setUserName } from '@/utils/username'
import { setToken } from '@/utils/token'
// import { setPassWord } from '@/utils/password'

export default {
  namespaced: true,
  state: {
    uid: 0,
    token: '',
    username: ''
  },
  mutations: {
    addUid(state, uid) {
      setUid(uid)
      state.uid = uid
    },
    addUserName(state, username) {
      setUserName(username)
      state.username = username
    },
    addToken(state, token) {
      setToken(token)
      state.token = token
    },
  },
  actions: {
    /* loginAction 是一个 Promise
    登录成功跳转页面之后 在 sessionStorage 内为什么能够成功写入数据呢 ? 
    是因为首先你一定要有一个 返回值 (boolean) 
    如果你不写返回值的话 , 因为这个写入是异步的 , 而跳转又是同步的 ,
    你可能会出现的异常情况就是 : 你写入数据写了一半时 , 它跳转走了 , 导致你的数据一会有一会又没有了
    所以你每次登录的时候每次都是第一次登录不成功 , 第二次登录就成功了的原因所在
    (第一次你写了一半的时候它跳转走了 , 第二次在写的时候又把第一次的写进去了 , 第二次用的其实就是第一次的了 , 但是给人的感觉就像是第二次才登录成功了)
    但是你有了返回值就没有问题了 , Promise 得到了你成功了之后才会再执行下一步的操作 */
    async loginAction({ commit }, userData) {
      let ret = await doLoginApi(userData)
      if (ret.code === 0) {
        /* 分开最大的好处就是你的代码结构比较完整(函数式编程)
        在这里呢 , 我们其实可以只写一个的 , 但是为什么我们写多个呢 ?
        因为假如某一天我们不要哪一个了的话 , 我们就直接在这里注释掉就可以了
        你的方法关闭和开合就会很方便了 */
        commit('addUid', ret.data.uid)
        commit('addUserName', ret.data.username)
        commit('addToken', ret.data.token)
      }
      return ret.code === 0 ? true : false
    }
  }
}

1.2.6、后台登录实现

1.2.7、后台用户访问验证

1.2.8、后台界面展示

1.2.9、后台页面子路由设置显示

1.2.10、菜单动态管理

1.2.11、通过动态路由添加来完成路由权限控制

1.2.12、动态添加路由来完成路由权限

1.4、权限控制

1.4.1、登录权限

检查用户是已经登录

// 路由全局前置守卫
router.beforeEach((to, form, next) => {
  if (to.path != '/login') {  // 如果不是登录页面, 怎进行向下验证
    console.log('to.path 不是 login');
    if (true) { // 这里只需要判断是否有 token 令牌
      console.log('没有 token 则为假 , 跳登录页面');
      next({
        path: '/login',
        replace: true // 不能进行返回操作
      })
    } else {
      next()  // 向下执行
    }
  } else {
    next()  // 向下执行
  }
})

1.4.2、菜单权限

基于角色的权限控制 rbac

在公司中都是在登录时后台通过用户名来完成对于此用户属于哪一个角色,根据此角色来完成对应菜单数据返回

1.4.3、路由权限

如果当前用户的角色没有对应的路由权限则直接访问也无法获获取对应的页面展示

router.addRoute( )    api  

vue-router3  

router.addRoutes( [ ] )

router.addroute( { } )

vue-router4

router.addroute( { } )

1.4.4、按钮


富文本编辑器

基本使用 · wangEditor 用户文档

可以简单的理解为 在线 Word , 有图有文字 , 实现如下操作步骤 : 

"wangeditor": "^4.7.9"

使用 : 

module.exports = {
  lintOnsave: false
}

<template>
  <div id="div1">
    <p>请输入内容</p>
  </div>
</template>

<script>
// Web 富文本编辑器
import E from "wangeditor";
export default {
  data() {
    return {
      editor: null,
      userinfo: {
        introduce: "",
      },
    };
  },
  mounted() {
    this.editor = new E("#div1");
    // 或者 const editor = new E( document.getElementById('div1') )
    // 监听编辑器的变化
    this.editor.config.onchange = (newHtml) => {
      this.userinfo.introduce = newHtml;
      // console.log(newHtml);
    };
    this.editor.create();
  },
  beforeDestroy() {
    this.editor = null;
  },
};
</script>

<style lang="scss" scoped>
  @import "./scss/index.scss";
</style>

附例 :  Vue 中的  @  符 提示 文件配置 

jsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

自动化 导入 路由 配置 文件 : 

// vue-cli 中脚手架工具(webpack工具)提供一个api方法完成对于模块的自动加载
// 参数1:要去检索的目录
// 参数2:是否递归检索,true是,false否
// 参数3:指定要检索的文件类型  用正则来完成
// 返回值:是一个函数,且此函数有一个方法为keys返回一个检索到的文件列表(数组)
// 正则的 i不区分大小写 g全局 u支持中文
// const moduleFn = require.context('./routes', false, /\.(js|txt)$/i)
const moduleFn = require.context('./routes', false, /\.js$/i)
/* const routes = []
moduleFn.keys().forEach(file => {
  // 动态得到当前导入的对象,可能为对象也可能为数组
  let module = moduleFn(file).default
  // es6提供一个api
  if (Array.isArray(module)) {
    routes.push(...module)
  } else {
    routes.push(module)
  }
}) */
const routes = moduleFn.keys().reduce((prev, curr) => {
  // 动态得到当前导入的对象,可能为对象也可能为数组
  let module = moduleFn(curr).default
  // es6提供一个api
  if (Array.isArray(module)) {
    prev.push(...module)
  } else {
    prev.push(module)
  }
  return prev
}, [])

Vuex%C2%A0%20%E6%A8%A1%E5%9D%97%E5%8C%96%E9%85%8D%E7%BD%AE%20%E6%96%87%E4%BB%B6%20%3A%C2%A0">自动化 导入 Vuex  模块化配置 文件 : 

let moduleFn = require.context('./module', false, /\.js$/i)
let modules = moduleFn.keys().reduce((prev, curr) => {
  let value = { ...moduleFn(curr).default, namespaced: true }
  // 字符串方法和正则表达式中的分组
  let key = curr.match(/\.\/(\w+)\.js/i)[1]
  prev[key] = value
  return prev
}, {})

http://www.niftyadmin.cn/n/1497910.html

相关文章

递归从入门到精通

递归——初学者学习语言的最大障碍之一 递归是真的难懂&#xff0c;我每次都是绕进去&#xff0c;然后绕不出来&#xff0c;一个程序能做到这样&#xff0c;我服&#xff01;&#xff01;&#xff01; 我们看一段文字先欣赏一下递归的轮廓&#xff0c;如果看完不懂&#xff0c;…

线程以及进程(通俗易懂)

通俗易懂&#xff0c;适合初学者阅读。强烈推荐。5星。 申明&#xff1a;此文章是在他处看到的,转自阮一峰博客。 来源: http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 1. 计算机的核心是CPU&#xff0c;它承担了所有的计算任务。它就像一座工厂&#x…

验证码跟ehcash整合

1.所有配置文件如下&#xff1a; <bean class"com.mocent.shiro.captcha.DreamCaptcha"><property name"cacheManager" ref"shiroSpringCacheManager"/><!-- 复用半小时缓存 --><property name"cacheName" valu…

小程序 _ 学习笔记

目录 一、小程序介绍 1.1、小程序是什么 1.2、小程序与普通网页开发区别 1.3、小程序与传统 App 区别 1.4、小程序框架结构 二、申请账号与登录设置 2.1、申请账号 2.2、登录 2.3、获取开发 appid 三、开发工具 3.1、下载与安装 3.2、helloworld 项目 四、小程序的…

python编程入门到实践405_python 模拟post登陆 HTTP错误405

# -*- coding: utf-8 -*-#!/usr/bin/pythonimport HTMLParserimport urlparseimport urllibimport urllib2import cookielibimport stringimport reimport jsonhosturl http://insysu.com/sign_inposturl http://insysu.com/#cookie处理器cj cookielib.LWPCookieJar()cookie…

leetcode刷题记录03——无重复字符的最长子串(Java和JavaScript)

3. 无重复字符的最长子串 难度&#xff1a;中等 给定一个字符串&#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 示例 2: 输…

sqlite3 简单实用方法

打开数据库&#xff1a;sqlite3.exe test.db 显示所有表&#xff1a; .tables 退出 sqlite3&#xff1a;.quit 还有个问题&#xff0c;已经打开一个数据库文件了。 不知道如何在不退出命令行的情况下&#xff0c;更换另一个数据库文件&#xff1f;&#xff01; 有知道的&#x…

LeetCode 326 Power of Three(3的幂)(递归、Log函数)

翻译 给定一个整型数&#xff0c;写一个函数决定它是否是3的幂&#xff08;翻译可能不太合适……跟进&#xff1a; 你能否够不用不论什么循环或递归来完毕。 原文 Given an integer, write a function to determine if it is a power of three.Follow up: Could you do it with…