写后台系统的总结

第一天,准备好项目,先创建一个项目 vue create vue2pro 这里因为我是新手选择的是vue2,然后把目录中默认的一些文件不需要的删除,然后这个项目我放在gitte上,这里说下我是先再本地创建的git init 然后就去gitte官网创建一个仓库,然后再本地与远程连接起来,刚创建的时候是有命令提示的,照着那个来做就行,但一般的新手有可能会有一些报错,去网上搜哈,都是这样走过来的。

 

然后开始搭建页面和路由,搭建再views里面准备每一个大的路由准备每一个文件夹,然后再router里面配置路由 准备base.css 把默认重置样式都准备好

 

* {
            margin: 0px;
            padding: 0px;
            box-sizing: border-box;
         }

         ul,
         ol {
            list-style: none;
         }

         a {
            text-decoration: none;
         }

         img {
            vertical-align: middle;
         }

简单准备一下,再页面上看一下效果就行,准备一些要用的插件,这里主要是用的element-ui axios querystring ,可以去看官网https://element.eleme.cn/#/zh-CNs 这个是中国的地址,它默认地址再外网,跟GitHub一样,然后就说echarts,因为要用一些图标,非常的好用

在本次项目中要用到很多组件,其中布局有他的layout,但我觉得不咋样不如自己写的,在做侧边栏导航要用的组件的NavMenu导航侧栏,其中如果我们要修改样式,他的里面有一些可以修改,有一些就要我们自己强行去修改,刚开始的小伙伴应该看到了,比如给你这个el-xxxx 标签加个class,有的压根就不理你,虽然你写上去,但是优先级低,可以直接在页面检查获取他的class 在修改的时候加个/deep/ 穿透,非常好用,实在不行在来个!important 这直接上梁山。这里面的组件很多很多,有兴趣的小伙伴可以好好看看

然后主要的就是接口,我是准备一个api文件, 里面创建一个index.js 这里我准备了一个处理不同接口报错的问题,request.js ,然后再这个js文件里面写一个axios,然后暴露出来,导入就可以用了

 

 接下来说下echarts图标

中间echarts图表   
  实现静态布局
   使用echarts
     第一步:安装
      npm install echarts --save
      yarn add  echarts
     第二步:  xx.vue文件中引入
      import * as echarts from 'echarts';
     第三步: 准备容器
       <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
      <div id="left" style="height: 320px"></div>
     第四步: 生成图表
 为不同的图表封装方法,到mounted生命周期方法中调用   
        mounted() {
            // 画柱状图和折线图
            this.drawBarAndLine();
            // 画饼图
            this.drawPie();
       },

 发请求拿数据,准备数据
      
   echarts的注意点【面试题】:
      1 如果是静态图表,那么就在mounted生命周期中书写代码。
      2 如果是动态图表,那么就在created生命周期中写代码。

然后来说下其中的时间处理,其中如果是我们来处理就只能写js代码,但是有现成比如moment

日期格式处理
      yarn add moment  
      import moment from "moment"
       注册方法
        methods: {           
            // fn:moment,
            // moment:moment,
            moment,
            // 发请求,拿数据
         }
     模板中使用
           <el-table-column prop="create_time" label="添加时间"> 
             <template slot-scope="scope">
              {{  moment(scope.row.create_time).format("YYYY-MM-DD HH:mm:ss") }}
             </template>
          </el-table-column>

 

把整个前面布局写完,再使用element-ui 组件的时候有个bug就说他的表格,再点击搜索的时候会出现底部滚动条,主要就说因为的他的样式问题,修改一下 

解决产品列表页当左侧菜单收缩时表格不能自动缩放的问题
      /deep/.el-table__header,
      /deep/.el-table__body {
         width: 100% !important;
         table-layout: auto;
      }

 在使用这个页面也有一些问题要处理

删除单条数据之后的页面处理
      // 最大的页码数 = 上一次的总数-1 /  每页的条数
      let lastPageNum =  Math.ceil((this.total - 1) / this.pageSize);
      // 当前页
      this.pageNum = this.pageNum< lastPageNum ? this.pageNum: lastPageNum ;              
      this.getProductList(); //重新加载数据

来说说编辑添加的页面这页面的功能有俩好玩的,一个就事上传图片,一个就说下面的富文本

 上传组件
        <!-- 
            action    必选参数,上传的地址
            list-type    文件列表的类型
            :on-preview="handlePictureCardPreview"   //预览
            :on-remove="handleRemove"  //删除
         -->
         <el-upload
            :action="$api.upload"
            list-type="picture-card"    
         >
         <!-- 加号的图标 -->
            <i class="el-icon-plus"></i>
         </el-upload>
  

富文本编辑器
      1 安装
         yarn add @wangeditor/editor
         # 或者 npm install @wangeditor/editor --save

         yarn add @wangeditor/editor-for-vue
         # 或者 npm install @wangeditor/editor-for-vue --save
      2 引入
        import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
      3 注册
           components: { Editor, Toolbar },

然后我之前在博客上找到一个很不错的现在没找到

现在components中创建组件wangEditor.vue

代码如下

<template>
    <div ref="editor"></div>
  </template>
  
  <script>
  import E from 'wangeditor';
  export default {
    props: {
      value: {
        type: String,
        default: '',
      },
      meanArray: {
        // 自定义菜单
        type: Array,
        default: null,
      },
    },
    model: {
      prop: 'value',
      event: 'change',
    },
    watch: {
      value: function (value) {
        if (value !== this.editor.txt.html()) {
          this.editor.txt.html(this.value);
        }
      },
      //value为编辑框输入的内容,这里我监听了一下值,当父组件调用得时候,如果给value赋值了,子组件将会显示父组件赋给的值
    },
    data() {
      return {
        // 默认有这么多菜单,meanArray有值以meanArray为准
        defaultMeanus: [
          'head',
          'bold',
          'fontSize',
          'fontName',
          'italic',
          'underline',
          'strikeThrough',
          'indent',
          'lineHeight',
          'foreColor',
          'backColor',
          'link',
          'list',
          'justify',
          'quote',
          'emoticon',
          'image',
          'video',
          'table',
          'code',
          'splitLine',
          'undo',
          'redo',
        ],
        editor: '',
      };
    },
    methods: {
      init() {
        const _this = this;
        this.editor = new E(this.$refs.editor);
        this.editor.config.uploadImgShowBase64 = true; // 使用 base64 保存图片
        this.setMenus(); //设置菜单
        this.editor.config.onchange = (html) => {
          _this.$emit('change', html); // 将内容同步到父组件中
        };
        this.editor.create(); //创建编辑器
      },
      setMenus() {
        // 设置菜单
        if (this.meanArray) {
          this.editor.config.menus = this.meanArray;
        } else {
          this.editor.config.menus = this.defaultMeanus;
        }
      },
      getHtml() {
        // 得到文本内容
        return this.editor.txt.html();
      },
      setHtml(txt) {
        // 设置富文本里面的值
        this.editor.txt.html(txt);
      },
    },
    mounted() {
      let that = this;
      that.$nextTick(function () {
        that.init();
      });
    },
  };
  </script>
  

然后再父里面

import Editor from '@/components/wangEditor/wangEditor.vue'

components: { Editor },

这个我是简单来的,自己加到正确的地方

这里我把修改也写在这个页面,这个只需要跳转判断一个条件就行了,比如我们把数据放在vuex里面

修改产品
页面跳转
      修改和添加共用同一个页面
         1 点击编辑按钮时跳转到编辑页
         2 携带当前行数据
            1 动态路由
            2 本地存储
            3 vuex
把当前行的数据存入了vuex
       1 store文件夹中新建modules文件夹 ,新建一个product.js
                     export default {
               namespaced: true,
               state: {
                  rowData: {},
                  tite:"商品添加"
               },
               getters: {
                  getRowData(state){
                     return state.rowData;
                  }
               },
               mutations: {
                  setRowData(state, payload) {
                        state.rowData = payload
                  }
               },

            }
       2 store文件夹中的index.js中引入 product.js 并且添加到模块中  
           // 导入product.js 模块
            import product from"./modules/product.js";
               export default new Vuex.Store({
               state: {
               },
               getters: {
               },
               mutations: {
               },
               actions: {
               },
               modules: {
                  product,
               }
            })

然后就是这个页面的导出功能来说下, 

导出为excel文件
     1 安装插件
        npm install -S vue-json-excel
     2 注册插件到 vue 实例
       main.js

       import JsonExcel from "vue-json-excel";
       Vue.component("DownloadExcel", JsonExcel);
     
     3 使用   
      <!-- 
           :data = 数据源  要导出的数据 []
           :fields = 中文对照字段, 数据库中的英文字段对应的中文描述
           :header="title" 表格的标题
           name ="导出的文件名"

         -->
        <DownloadExcel  
        :data="ids"
        :fields="json_fields"
        header="产品列表"
        name="产品信息表"
        >
           
          <el-button   type="primary"     size="small" >导出为excel</el-button>
        </DownloadExcel>
      
       json_fields:{
        // 中文:英文
        "商品编号":"id",
        "商品名称":"title",
        "商品价格":"price",
        "商品类目":"category",
        "添加时间":"create_time",
        "商品卖点":"sellPoint",
        "商品描述":"descs",
      },

      特殊字段的处理
           "订单编号":{
               field:"code",
               callback:value=>{
                  return '&nbsp;'+value;
               }
           },
 

然后来说下登录和全局路由前置守卫

全局路由前置守卫
         /* 
      to: 即将要访问的路由对象
      form:前一个路由对象 
      next:是一个函数继续执行
      */
      router.beforeEach((to, from, next) => {
         //  只有登录之后才能访问 
         console.log("to", to);
         console.log("from", from);
         if (to.path !== "/login") {
            //判断用户是否登录  token ?
            let token = localStorage.getItem("userinfo") ? JSON.parse(localStorage.getItem("userinfo")).token : "";
            if(token){//如果以已经登录
               //放行
               next();
            }else{//没有登录
               router.push("/login")
            }   

         } else {
            next();
         }
      })

 权限
   要求不同的角色进行不同的操作。
   1 可以由后端来实现:
           登录之后,后端程序可以知道当前用户的角色,就可以把当前
         用户可以做的事情(可以访问的路由信息)返回给前端,前端根据返回的数据
         直接生成导航即可。
   2 可以由前端来实现:
         有点难点。要用到很多技术。

这里我来说个简单的方法,首先把主要的路由复制出来,作为处理数据原

给每个路由加个meta,title为名字,roles为权限

然后根据登录的用户来递归遍历出该用户能访问的页面,如果强行访问则是404页面,这个页面自己准备

 


const router = new VueRouter({
  routes:constRoutes
})
console.log(router.options.routes[0].children);

router.beforeEach((to, from, next) => {
  let role = localStorage.getItem('userinfo') ? JSON.parse(localStorage.getItem('userinfo')).role : false
  
  console.log( '1',to);
  console.log('2',role);


  if (to.path == '/' ) {
    next();

   
  } else {


    if (to.path !== '/login') {

if(to.path!='/404'&&!to.meta.roles.includes(role)){
    console.log('404');
    router.push('/404')

  }

      //登录
      let user = JSON.parse(localStorage.getItem('userinfo'))
      if (user) {
        next()
      } else {
        router.push('/login')
        console.log('要登录');
      }
    } else {
      next()
    }
  }

})


//判断当前角色是否可以访问当前路由对象
const hasPermission = (item,role) => {
      // console.log("当前角色:",item);
      // console.log("当前路由对象",role);

      if(item.meta && item.meta.roles){
        //是否可以访问
          return item.meta.roles.includes(role)
      }else{
        return true
      }
}

const caclAccessRoutes = (role,dynamicRoutes) => {
  let result = dynamicRoutes.filter((item) => {
    if (hasPermission(item,role)) {

      //计算当前角色可以访问的子路由
      if(item.children){
         item.children = caclAccessRoutes(role,item.children) //递归
      }
      return true
    }else{
      return false
    }
  })

  // console.log("你能访问的地方result",result);
  return result;
}

const calcMenus = (constRoutes,accessRoutes) => {
    let menus = [...constRoutes,...accessRoutes].filter(item => item.path !="/login"&&item.path !="/404")

    //存入本地
    localStorage.menus = JSON.stringify(menus)
    // console.log('menus',menus);
    return menus
} 
export const createDynamicRoutes = () => {
  console.log('生成动态路由');
  let role = localStorage.getItem('userinfo') ? JSON.parse(localStorage.getItem('userinfo')).role : false
  if (!role) {
    return;
  }
  let accessRoutes = caclAccessRoutes(role,dynamicRoutes)
  // console.log('你能访问的地方',accessRoutes);
  //计算当前的权限
  calcMenus(constRoutes,accessRoutes)
  
}

createDynamicRoutes()
export default router

然后根据不同的用户就可以看见不同的页面了

这是普通用户的看见的页面(测试用的)

如果强制访问就会

但如果是管理员就可以访问所有,不同人有不同人的方法来呈现,左边的显示通过获取可以访问页面的数据来进行遍历 

最后一次行展示一些页面吧

 

 

 

 总结结束

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值