ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue后台管理系统

2021-03-31 13:33:51  阅读:472  来源: 互联网

标签:vue const 管理系统 js Vue components 后台 import config


Vue后台管理系统

文章目录


前言

一、项目概述

1.1 电商项目基本业务概述

在这里插入图片描述

1.2 电商后台管理系统的功能

在这里插入图片描述

1.3 电商后台管理系统的开发模式(前后端分离)

在这里插入图片描述

二、项目初始化

2.1 通过 Vue 脚手架创建项目

2.1.1 配置 Vue 路由 插件要选择Router

2.1.2 配置 Element-UI 组件库 import方式需要选择import on demand

2.1.3 配置 axios 库 添加axios依赖

在这里插入图片描述

2.1.4 初始化 git 远程仓库需要在github或gitee创建远程仓库

2.1.5 将本地项目托管到 Github 或 码云 中

1、在项目的根目录打开PowerShell

2、git add .

3、git commit -m "说明"

4、按照新建仓库给的连接远程仓库和提交命令继续操作,与远程仓库建立联系

####

2.1.6 梳理项目结构

格式化App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

格式化 router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [

]

const router = new VueRouter({
  routes
})

/*------------实现导航守卫控制页面访问权限----------------*/
/** 
	param: to     将要访问到的路径
	param: from   代表从哪个路径跳转而来
	param:next   代表一个函数,表示放行 
*/
router.beforeEach((to, from, next) => {
  if(to.path === '/login') return next();
  const tokenStr = sessionStorage.getItem("token");
  
  // 判断token是否存在,如果不存在则代表未登录,则强制路由到登录页面
  if(!tokenStr) return next('./login');
  next();
})

格式化 main.js

/*------------------引入element-ui和其他样式--------------------*/ 
import './plugins/element.js'
import './assets/css/global.css'
import './assets/fonts/iconfont.css'

/*------------------封装axios和加载进度条--------------------*/ 
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import axios from 'axios'
Vue.prototype.$http = axios
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'

/*------------------通过axios拦截器添加token验证--------------------*/ 
// 文档通常会说明后台会对操作数据的api进行根据token令牌授权的操作
// 根据实际的文档常常需要在请求头添加内容是token令牌的字段 Authorization
axios.interceptors.request.use(config => {
  NProgress.start();
  // 添加请求头
  config.headers.Authorization = window.sessionStorage.getItem('token');
  return config
})
axios.interceptors.response.use(config => {
  NProgress.done();
  return config
})

/*------------------定义过滤器--------------------*/ 
Vue.filter('dateFormat', function(date) {
  const dateObj = new Date(date);
  const y = dateObj.getFullYear();
  const m = (dateObj.getMonth() + 1 + '').padStart(2, '0');
  const d = (dateObj.getDay() + '').padStart(2, '0');
  const hh = (dateObj.getHours() + '').padStart(2, '0');
  const MM = (dateObj.getMinutes()+ '').padStart(2, '0');
  const ss = (dateObj.getSeconds() + '').padStart(2, '0');
  return `${y}-${m}-${d} ${hh}:${MM}:${ss}`;
})

格式化 element.js

import Vue from 'vue'
import { 
	Button,
    Message, 
    MessageBox 
} from 'element-ui'
Vue.prototype.$message = Message

// 实现基于element-ui的message全局弹框组的配置
Vue.prototype.$confirm = MessageBox.confirm

2.2 后台项目的环境安装配置

2.2.1 导入数据库

1、停止本地mysql80服务

2、启动phpstudy,开启mysql的服务

在这里插入图片描述

3、先创建数据库,再导入sql脚本

在这里插入图片描述

2.2.2 修改项目的config文件修改用户和密码为自己刚刚创建的数据库的用户和密码

在这里插入图片描述

2.2.3 在项目根目录打开powershell运行node ./app.js

2.2.4 使用postman看看接口是否跑起来了,如果有数据返回则服务器运行成功

在这里插入图片描述



三、实现功能业务的一般流程

3.1 开始新业务开发,首先创建并切换到新分支 git checkout -b 新分支名

3.2 新建组件并初始化结构 template、script、style

3.3 在router/index.js创建并引入路由 {path: '路径' ,component: 组件名}

3.4 实现页面ui结构 通过原生标签和element-ui配合组成页面结构


3.5 定义数据和自封装函数来实现业务功能

3.5.1 加载页面的时候就触发获取列表数据的事件,所以应该把该事件的触发放到created周期

3.5.2 当在html页面上需要用到某些数据的时候先到data里面找,如果没有则用作用域插槽的scope.row来获取当前表格行的数据

在这里插入图片描述

3.6 将本地代码提交到码云上

3.6.1 把文件提交到暂存区 git add .

在这里插入图片描述

提交到仓库 git commit -m "说明"

在这里插入图片描述

提交到远程仓库的功能分支 git push -u origin 分支名

在这里插入图片描述

切换为主分支并合并分支 git checkout master、git merge 分支名

在这里插入图片描述

提交到远程仓库 git push

在这里插入图片描述



四、登录/退出功能

3.1 登录业务流程

在这里插入图片描述

3.2 技术选择

3.2.1 方案1:cookie和session记录登录状态

3.2.2 方案2:token 维持登录状态

在这里插入图片描述

方案使用场景
cookie、session服务器和客户端不跨域
token服务器和客户端跨域,常用

在这里插入图片描述

3.3 登录页面的实现过程

3.3.1 表单的数据绑定

在这里插入图片描述

3.3.2 表单的数据校验

在这里插入图片描述

3.3.3 表单重置

 methods: {
    resetLoginForm: function() {
        // this指向当前组件实例,refs是存有含有ref属性的组件的对象,resetFields()方法是重置所有的表单项
        this.$refs.loginFormRef.resetFields()
    }
},

在这里插入图片描述

3.3.4 表单提交前先通过validate函数预校验再提交,登录后需要有路由指向

login: function() {
    this.$refs.loginFormRef.validate(async valid => {
    	// 1、预校验
        if(!valid) return;
        const { data: res } = await this.$http.post("login",this.loginForm);
        if(res.meta.status != 200) return this.$message.error('登陆失败!')
        this.$message.success('登陆成功!')
       
        // 2、将token保存到客户端的sessionStorage中
        //  2.1 项目中除了登录之后的其他API接口,必须在登录之后才能访问
        //  2.2 token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
        window.sessionStorage.setItem("token", res.data.token);
        
        // 3、通过编程式导航到后台主页,路由地址是 /home
        this.$router.push("/home");
    })
}


四、主页功能

4.1 主页布局

在这里插入图片描述

4.2 登录后退出功能

	// 在已登录放行的页面定义
    methods: {
        exit: function() {
        	// 移除token并跳转到登陆页面
            window.sessionStorage.removeItem("token");
            this.$router.push('/login');
        }
    }

4.3 v-for循环渲染菜单列表

在这里插入图片描述

4.4 给其他功能组件提供占位

在这里插入图片描述



五、其他业务功能的布局和功能实现

5.1 基于element-ui绘制用户列表的组件

5.3.1 页内导航 BreadCrumb

5.3.2 主要内容面板 Card

5.3.3 栅格系统 col、row

5.3.4 数据表格 el-table

5.3.5 分页导航 el-pagination


5.2 基于el-table渲染数据列表

5.2.1 获取用户信息列表

5.2.2 渲染数据列表

5.2.3 实现分页展示用户数据


5.3 实现增删改查功能

5.3.1 添加功能常需要弹出对话框 el-dialog

1、对话框的显隐标志visible需要用v-bind绑定而不是v-model v-bind:visible="..."

2、对话框要添加关闭事件@close="关闭事件名",不然点击关闭按钮会无反应

3、关闭对话框的同时需要清空表单,该操作最好添加在关闭事件上 this.$refs.表单实例对象.resetFields();

4、对话框内容常常是表单,需要遵守表单的规则


5.3.2 删除功能常需要弹出消息框 基于messageBox的confirm

方法名() {
	this.$confirm('此操作将永久删除..., 是否继续?', '消息框标题', {
	  confirmButtonText: '确定',
	  cancelButtonText: '取消',
	  type: 'warning'
	}).then(() => {
	  // 在这里发送删除请求
	  this.$message({
	    type: 'success',
	    message: '删除成功!'
	  });
	}).catch(() => {
	  this.$message({
	    type: 'info',
	    message: '已取消删除'
	  });
	});
}

5.3.3 修改功能也常需要弹出对话框 el-dialog

5.3.4 搜索功能 设计接口的时候把搜索所需要的信息设计为可空



六、引入的功能组件

6.1 树形表格 vue-table-with-tree-grid

6.1.1 安装 npm i vue-table-with-tree-grid -S

6.1.2 引入

import ZkTable from 'vue-table-with-tree-grid'
Vue.use(ZkTable)
Vue.component('tree-table',ZkTable)

6.1.3 使用

https://github.com/connie1992/vue-table-with-tree-grid-icon
在这里插入图片描述

在这里插入图片描述

<!-- 数据列表 -->
<tree-table :data="cateList" :columns="columns" 
:selection-type="false" :expand-type="false" 
:show-index="true" index-text="#" :border="true" 
:stripe="true" :show-row-hover="false" class="treetable">
    <!-- 是否有效列 -->
    <template slot="isok" slot-scope="scope">
        <i class="el-icon-success iconSuccess" v-if="scope.row.cat_deleted == false"></i>
        <i class="el-icon-error iconError" v-else></i>
    </template>

    <!-- 排序列 -->
    <template slot="sort" slot-scope="scope">
        <el-tag v-if="scope.row.cat_level == 0" size="mini">一级</el-tag>
        <el-tag type="success" v-else-if="scope.row.cat_level == 1" size="mini">二级</el-tag>
        <el-tag type="warning" v-else size="mini">三级</el-tag>
    </template>

    <!-- 操作列 -->
    <template slot="action" >
        <el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button>
        <el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
    </template>
</tree-table>
columns: [
    {
        label: '分类名称',
        prop: 'cat_name'
    },
    {
        label: "是否有效",
        // 将当前列作为模板列
        type: 'template',
        template: 'isok'
    },
    {
        label: '排序',
        type: 'template',
        template: 'sort'
    },
    {
        label: '操作',
        type: 'template',
        template: 'action'                    
    }
],

6.2 富文本编辑器 vue-quill-editor

6.2.1 下载 npm install vue-quill-editor -S

6.2.2 引入

import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css' // import styles
import 'quill/dist/quill.snow.css' // for snow theme
import 'quill/dist/quill.bubble.css' // for bubble theme
Vue.use(VueQuillEditor)

6.2.3 使用

<quill-editor v-model="addForm.goods_introduce"/>

6.3 第三方可视化库 Echarts

https://echarts.apache.org/zh/index.html

6.2.1 下载 npm install echarts -S

6.2.2 引入

import * as echarts from 'echarts';

6.2.3 使用

<div id="main" style="width: 750px;height:400px;"></div>
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 绘制图表
myChart.setOption({
    title: {
        text: 'ECharts 入门示例'
    },
    tooltip: {},
    xAxis: {
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
    },
    yAxis: {},
    series: [{
        name: '销量',
        type: 'bar',
        data: [5, 20, 36, 10, 10, 20]
    }]
});

6.4 第三方工具库,主要降低 array、number、objects、string 等等的使用难度 Lodash

https://www.lodashjs.com/

6.2.1 下载 npm i --save lodash

6.2.2 引入

import _ from 'lodash'

6.2.3 使用

<div id="main" style="width: 750px;height:400px;"></div>
// 深拷贝
const form =  _.cloneDeep(this.addForm);

// 合并对象
const result =  _.merge(res.data, this.options)

七、项目优化

7.1 项目优化策略

7.1.1 生成打包报告

1、在可视化的UI面板中,通过控制台和分析面板,可以方便地看到项目中所存在的问题

在这里插入图片描述

2、清除所有的console.log语句

下载包 npm install babel-plugin-transform-remove-console --save-dev或安装开发依赖
/*----------------------------------babel.comfig.js---------------------------------------*/
// 这是项目发布阶段才用的babel插件
const prodPlugins = []
if(process.env.NODE_ENV === 'production') {
  // 只在发布阶段清除console语句
  prodPlugins.push('transform-remove-console')
}
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [    
    // 发布产品时候的插件数组
    ...prodPlugins,
  ]
}

3、为开发模式与发布模式指定不同的打包入口

开发模式的入口文件为 src/main-dev.js
发布模式的入口文件为 src/main-prod.js
vue.config.js 导出的配置对象中,新增 configureWebpack 或 chainWebpack 节点,来自定义 webpack 的打包配置
① chainWebpack 通过链式编程的形式,来修改默认的 webpack 配置
② configureWebpack 通过操作对象的形式,来修改默认的 webpack 配置
module.exports = {
	// 使用chainWebpack节点
    chainWebpack: config => {
        config.when(process.env.NODE_ENV === 'production',config => {
        	// 获取app的入口文件对象,先清空再添加路径
            config.entry('app').clear().add('./src/main-prod.js')
        })
        config.when(process.env.NODE_ENV === 'development',config => {
            config.entry('app').clear().add('./src/main-dev.js')
        })
    }
}

7.1.2 第三方库启用 CDN

通过 import 语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而导致打包成功后,单文件体积过大的问题

module.exports = {
	// 使用chainWebpack节点
    chainWebpack: config => {
        config.when(process.env.NODE_ENV === 'production',config => {
        	// 获取app的入口文件对象,先清空再添加路径
            config.entry('app').clear().add('./src/main-prod.js')

			// 通过 webpack 的 externals 节点,来配置并加载外部的 CDN 资源。凡是声明在externals 中的第三方依赖包,都不会被打包
			config.set('externals', {
                vue: 'Vue', 
                axios: 'axios',
                lodash: '_',
                echarts: 'echarts',
                nprogress: 'NProgress', 'vue-quill-editor': 'VueQuillEditor'
            })
        })
        config.when(process.env.NODE_ENV === 'development',config => {
            config.entry('app').clear().add('./src/main-dev.js')
        })
    }
}

在main-prod.js中删除上述externals中的第三方包的css文件 删除红框部分

在这里插入图片描述

在public/index.html中引入样式和js文件

    <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
    <!-- 富文本编辑器 的样式表文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
 	<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
    <script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
    <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
    <!-- 富文本编辑器的 js 文件 -->
    <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>

7.1.3 Element-UI 组件按需加载

注释掉引入elementui的语句

在这里插入图片描述

在public/index.html中引入样式和js文件

<!-- element-ui 的样式表文件 --> 
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.1/theme-chalk/index.css" />

<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.15.1/index.js"></script>

7.1.4 首页内容定制

不同的打包环境下,首页内容可能会有所不同。我们可以通过插件的方式在进行定制

chainWebpack: config => {
	 config.when(process.env.NODE_ENV === 'production', config => {
		 config.plugin('html').tap(args => {
			 args[0].isProd = true
			 return args
		 })
	 })
	 config.when(process.env.NODE_ENV === 'development', config => {
		 config.plugin('html').tap(args => {
			 args[0].isProd = false
			 return args
		 })
	 })
}

根据 isProd 的值,来决定如何渲染页面结构

<!– 按需渲染页面的标题 -->
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>
<!– 按需加载外部的 CDN 资源 -->
<% if(htmlWebpackPlugin.options.isProd) { %>
<!—通过 externals 加载的外部 CDN 资源-->
<% } %>

7.1.5 路由懒加载

安装开发依赖 @babel/plugin-syntax-dynamic-import

在babel.config.js 配置文件中声明该插件

在这里插入图片描述

将路由改为按需加载的形式

const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Login.vue')
const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Home.vue')
const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Welcome.vue')
// import Login from '../components/Login.vue'
// import Home from '../components/Home.vue'
// import Welcome from '../components/Welcome.vue'

const Users = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/Users.vue')
const Rights  = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Rights.vue')
const Roles = () => import(/* webpackChunkName: "Users_Rights_Roles" */ '../components/power/Roles.vue')
// import Users from '../components/Users.vue'
// import Rights from '../components/power/Rights.vue'
// import Roles from '../components/power/Roles.vue'


const Cate = () => import(/* webpackChunkName: "Cates_Params_List_Add" */ '../components/goods/Cate.vue')
const Params = () => import(/* webpackChunkName: "Cates_Params_List_Add" */ '../components/goods/Params.vue')
const List = () => import(/* webpackChunkName: "Cates_Params_List_Add" */ '../components/goods/List.vue')
const Add = () => import(/* webpackChunkName: "Cates_Params_List_Add" */ '../components/goods/Add.vue')
// import Cate from '../components/goods/Cate.vue'
// import Params from '../components/goods/Params.vue'
// import List from '../components/goods/List.vue'
// import Add from '../components/goods/Add.vue'

const Order = () => import(/* webpackChunkName: "Order_Report" */ '../components/order/order.vue')
const Report = () => import(/* webpackChunkName: "Order_Report" */ '../components/report/Report.vue')
// import Order from '../components/order/order.vue'
// import Report from '../components/report/Report.vue'

总结

标签:vue,const,管理系统,js,Vue,components,后台,import,config
来源: https://blog.csdn.net/Satosere/article/details/114886017

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有