(vuecli,选项式api,js语法)后台管理系统项目笔记

项目git仓库地址

项目搭建

项目基础配置

vueCli基础配置 vue.config.js
反向代理配置
路径别名配置

配置反向代理 以及 axios的二次封装

    proxy: {
      // 开发时所有的请求 必须以 /api开头 (不能加源)
      '/api': {
        // 代理的目标服务器
        target: 'https://www.fastmock.site/mock/2fffb10607d962fe159da85d0dcd9258',
        // 请求时是否切换源
        changeOrigin: true,
        // 路径重写
        pathRewrite: {
          // ^/api所有请求地址 开头/api
          '^/api': '/api'
          /*
            反向代理 必须要有一个 请求前缀,才能触发,比如 上述反向 必须 以/api开头 触发反向代理
            问题?
              大部分前后端分离 接口 有请求前缀 /api 如果 有的接口没有请求前缀
              就需要将 请求中开始 /api 发请求去掉 不然会产生404
              http://xxx.com/itemLists 真实 后端接口完整路径

              配置 /api反向代理后真实发出去的地址时
              target + /api重写后的值 + 路径

             axios发请求地址这样写 http://xxx.com/itemLists
          */
        }
      }
    }

axios二次封装

import axios from 'axios'
// 配置 baseURL 以及超时时间等
const request = axios.create({
  /*
    开发时 baseURL一般为 /api 反向代理 请求前缀
    上线后:
      线上服务器源+/api 一般 上线后 前端代码和后端接口代码部署同一个源下
    怎么解决 axios 请求 基础源 开发和生产不一致问题
  */
  baseURL: process.env.VUE_APP_BASEAPI
})
// 添加请求和响应拦截
request.interceptors.request.use(function (config) {
  // 请求头添加token 做接口 token校验
  return config
}, function (error) {
  return Promise.reject(error)
})

request.interceptors.response.use(function (response) {
  // 判断后端返回 code码 做 登录过期 未登录处理
  return response
}, function (error) {
  return Promise.reject(error)
})

export default request

环境变量

解决开发生产接口源不一致的问题
如何获取环境变量
process.env.具体环境变量名

vueCli(vite) 提供默认环境变量 叫 NODE_ENV 保存的是 现在代码运行环境

process.env.NODE_ENV 变量在开发环境下 值时 development在生产环境下 值时
production

1 利用 NODE_ENV 内置环境变量 来 判断开发生产

import axios from 'axios'
// 配置 baseURL 以及超时时间等
const request = axios.create({
  baseURL: process.env.NODE_ENV === 'development'
    ? '/api'
    : '生产的源+/api'
  
})

2 自定义环境 直接保存 开发源
vueCli中自定义环境变量语法如下

/*
  项目根目录下创建两个文件
  .env.development 某个环境变量在开发时的值
  .env.production 某个环境变量在生产环境时的值

  注意:
    自定义环境变量必须以 VUE_APP_变量名开头
    VUE_APP_变量名=值
  定义完环境变量后重启生效
*/

后台管理常用目录

src
  assets // 静态资源
  api // 封装 接口函数
  utils // 工具函数目录 (比如 对于 axios的二次封装)
  components // 公共组件
  router // 路由配置
  store // vuex 配置
  views // 路由组件 目录名(两个单词 大驼峰 index.vue组件名 name和目录名保持一致)
  App.vue // 根组件
  main.js // 入口文件

mock接口

项目流程:
项目开发时 前后端分离, 前后端同时进行开发, 问题:
前端开发时,后端接口也正在编写,前端开发时 需要 自己mock接口 (模拟接口)
模拟接口:
注意:
模拟每一个接口 多要和 后端真实接口保持一致
1 路径 (源可变)
2 请求方式和参数 保持一致
3 返回数据 结构和真实结构一样

mock接口语法

  • 本地 mockjs 插件进行mock
    mock:拦截ajax请求,并生成随机数据
    特点:
    请求并没有真的发出去(被mockjs拦截了)

基础用法:

  • 安装
  npm i mockjs -D
  
  • 在线mock平台
    利用mockjs语法 生成随机数据,可以真实发出请求

fastmock https://www.fastmock.site/#/
easymock
apipost
rap2.taobao.org

项目中使用import引入和 require引入区别

  • import 必须是 编译前提前引入
    require可以按需引入
    (作业:引入一个assets中的文件 作为 一个 div背景图片)
  • require一般用来 引入 生产环境不需要模块
    显眼(快速区分 生产依赖 非生产依赖)

注意

前后端分离 接口 一般都会有前缀 (/api)

npm 高版本安装包 报错问题

原因:
项目依赖包
dependencies 项目生产环境依赖包
devDependencies 开发依赖包
peerDependencies 所有包的依赖包

peer 包依赖包

// 强制安装
npm i 包 -S --force
npm i --force

element-plus组件库

开发中 页面接口一般会在 外部 提取 单独管理

api
  itemLists.js // 以路由组件进行单独提取
  cateLists.js 

拆分组件

一个 路由组件所有功能 不要都在路由组件中完成 代码量过大 尤其 是 选项式 api 代码审查难度 特别大

遵循状态提升和单向数据流

组件
逻辑组件
(组件内部有很多数据要管理 处理业务 没有任何复用性)
UI组件 (复用 在多个 逻辑组件 都可以使用)

element 表单 验证

常用验证规则

  • 必填验证
{
  required: true,
  message: '该字段必须填写', // 当验证不通过时 错误提示文本
  trigger: 'blur' // 验证触发时机  默认是 blur
}
  • 字符串长度验证
{
  min: 3,
  max: 5,
  message: '该字符长度应该是3-5'
}
  • 常用类型验证
{
  type: 'date', // array 
  message: 'xx'
}

/* 
  string
  number
  boolean
  method
  regexp
  integer
  float
  array
  object
  enum
  date
  url
  hex
  email
  any
*/
  • 使用正则
{
  pattern: /[a-z]\w{3,8}/, // 直接写正则
  message: '该字段4-9位小写字母和数字组成且首字符必须是小写字母'
}
  • 自定义验证规则
{
  validator: (rule, value, callback) => {
    // 运行callback() 则验证通过 运行callback(new Error('验证失败'))
    if (value === '小明') {
      callback()
    } else {
      callback(new Error('必须输入小明'))
    }
  }
}
  • 异步校验
{
    asyncValidator: (rule, value) => {
      return new Promise((resolve, reject) => {
        if (value < 18) {
          reject('too young');  // reject with error message
        } else {
          resolve();
        }
      });
    },
}
// 该字段发给后端校验 校验不通过 后端 报错给前端 axios
{
    asyncValidator: (rule, value) => {
      return axios.get('xxxx', {
        params: {
          key: value
        }
      })
    },
}

项目上传图片 文件

很多接口都需要 图片字段 字段要求传递 图片地址
? 图片只有先上传 才会有地址

假设 有5个接口都需要上传 图片(地址)

接口是这样处理的:
整个项目接口中,有一个单独的接口 一般叫 upload 专门用来上传文件的,上传后会立即返回 上传成功 文件 服务器地址

所有 需要上传文件的接口 在表单控件中新增一个 文件上传 控件, 点击文件上传时 立即上传 返回了地址,地址 合并 最终上传 表单字段中

文件上传常用场景:
1 默认自动上传 如何改成 手动上传
2 限制上传文件的 类型 以及 体积
3 上传成功图片 回显

后台管理中 excel导入导出功能

利用xlsx 实现excel导入导出

导出excel 案例

import { utils, writeFileXLSX } from 'xlsx'

function exportFile() {
  const ws = utils.json_to_sheet(data);
  /* 
    data长这样
    [
      {
        name:'小明',
        age: 10
      }
    ]
  */
  const wb = utils.book_new();
  utils.book_append_sheet(wb, ws, "Data");
  writeFileXLSX(wb, "导出文件名.xlsx");
}

导入 利用 element upload组件 选择文件 (input type=“file”)

      <el-upload
        action="#"
        accept=".xlsx, .xls"
        :before-upload="writeFile"
      >
        <el-button type="primary">
          导入excel批量添加商品
        </el-button>
      </el-upload>
import { read, utils } from 'xlsx'

const writeFile = (file) => {
  // 选择excel模板批量添加商品
      // file就是 选择文件 将文件转换成 arraybuffer格式
      // FileReader
      const fd = new FileReader()
      fd.readAsArrayBuffer(file)
      // 事件  fd 读取文件是异步 读取成功 在 onload事件中触发
      fd.onload = () => {
        // fd.result
        const wb = read(fd.result)
        const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
        const data2 = data.map(el => (
          {
            itemName: el.商品名,
            itemPrice: el.商品价格,
            itemDesc: el.商品描述,
            onSale: el.上下架
          }
        ))
        console.log(data2)
        // 发送请求给 后端批量添加 商品的接口
      }
      return false
}

后台管理中 常用富文本编辑器

ueditor 百度 (样式老旧)

wangeditor (基于vue和react二次封装)
注意:
使用 wangeditor 基于vue封装的组件,使用的 vue3的选项式api,请见 vue2文档

quill (基于vue和react进行二次封装)

后台管理中常用 技术栈 图表(echarts) 地图(百度、高德)

x轴 类目轴
y轴 数据轴
系列:
一个图表可以有多个系列数据

使用vue3 且使用选项式api 才会遇到一个坑

charts两个问题

1 数据一般是后端返回的,请求是异步的
详见官方文档
2 后端返回的数据 和 echarts的数据一般不一致
默认 echarts x轴系列data要求的列数据

{
  cate: ['袜子', '毛衣', '短裙', '围巾'],
  sale: [11, 22,33,44,55],
  profit: [44,23,46,68,89]
}

后端返回是行数据

[
  {
    item: '袜子',
    sale: 11,
    profit: 44
  },
  {
    item: '毛衣',
    sale: 22,
    profit: 23
  },
  {
    item: '短裙',
    sale: 33,
    profit: 46
  },{
    item: '围巾',
    sale: 55,
    profit: 89
  }
]

解决方法:
封装行转列函数,自己将行数据转换成列数据即可 (百度)
作业:
封装函数实现 行数据转列数据

使用echarts 数据集语法

项目中使用地图

百度地图 高德

开放平台

登录地图 开放平台 控制台
创建应用
应用类型两种
服务端
百度地图提供给你的 各种接口
直接请求得到对应数据
poi搜索
(一般给后端用,前端直接发请求会涉及到跨域的问题,前端请求后端的接口,拿到数据再去请求地图服务端接口)
前台
1 提供一个地图组件 在页面上渲染
2 提供方法 做 地图交互 (地图添加标记点 做poi搜索、路线规划)
浏览器
小程序
安卓
IOS
前端使用地图 比如百度地图
1 直接使用原生百度地图
2 使用基于 vue封装的百度地图组件库
http://map.heifahaizei.com/doc/begin/use.html

后台管理中权限

登录鉴权

  • 路由鉴权
    当用户没有登录 是无法 访问(除了登录页) 所有路由
    问题:
    路由鉴权 前端判断 是否登录时 只能判断token是否存在(有安全问题)

  • 接口鉴权
    前端在发请求时,需要将 后端登录返回的token 放到所有请求的请求头中(token access_token)
    后端首先 会校验 token是否传递 是否过期(不对) 返回对应 code(200 403token没有 没有权限 401token过期)

    思路:
    在axios请求拦截中 获取token 设置请求头,将token 定义在请求头中

    在响应拦截中 判断 code 如果是 401则token过期 403则未登录

角色鉴权 rabc (基于角色权限管理)

1 定义用户不同角色角色
2 不同角色分配不同权限
3 每个用户 有一个字段 role 代表当前用户的角色
实现方式有两种

  • 静态角色鉴权
    特点:
    所有的路由侧边导航菜单是在前端定死,路由和导航 数据新增一个字段,代表当前 可以访问这个路由或者导航菜单的所有的角色,用户登录时 登录接口会返回一个 字段 role:'admin’代表当前用户的 角色
    导航菜单:
    filter 条件是 当前导航 roles中是否包含 当前用户的role
    路由:
    新增没有权限路由, 在路由前置首位中判断,当前路由的roles是否包含 当前用户的role 包含则 next
    不包含 重定向没有权限这个路由
    roles: [‘superAdmin’,‘admin’]
      {
        path: 'xxx',
        meta: {
          roles: ['superAdmin','admin']
        }
      }
    
      // 菜单
      {
        label: '仪表盘'
        path: 'xxx',
        isMenu: true,
        roles: ['superAdmin','admin'],
        children: []
      }
    

优缺点:
优点是 实现方式简单,不需要后端过多配合
缺点:
权限上线后是无法修改
使用场景:
适用于 角色较为固定的 中小型项目

  • 动态角色鉴权
    每个角色可以访问的 路由 和 导航菜单数据,都是存储在后端数据库中, 用户登录时,后端会判断登录用户的角色,根据角色返回 当前用户 可以访问路由表 和 导航菜单数组,前端动态添加 导航菜单动态添加路由
    router.addRoute()

后台管理半成品模板:
vue-element-admin

步骤:
1 新增一个新的 路由?
告诉后端, 路由组件名字是什么(views/名字),meta中是否要定义数据、path一般 /名字(首字母大写改成小写)
2 路由需要 在侧边导航显示
点击设置权限管理 新增新的 导航
选择是 菜单(目录)还是导航 自己添加即可

vuex状态持久化

问题:
vuex中状态,当我们刷新浏览器时,会立即 丢失 数据回到初始化数据
原理:
在 缓存中备份一下 vuex中状态,当我们刷新时,取缓存中数据,给vuex状态赋值
备份

vuex某个状态,拿到值之后不会改变(登录接口返回的数据),这种同步,只需要在 请求拿到数据后,
缓存中再储存一下即可
某个状态需要改变的, 在所有mutation 只要值改变了 就要重新缓存一下当前的值

实现方式:
1 用户手动利用缓存备份 (推荐)
2 利用vuex插件 vuex-persister

开发中利用缓存 存储 对象或者 数组

存的时候
JSON.stringify()
取:
使用三目判断 有无缓存,有JSON.parse 没有 给 制定数据类型的初始值

面试题 开发中 如何封装axios (从功能角度说)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不二哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值