后台管理系统的技术点

  • \color{pink}{ 路由的基本规划}
var myRouter = new VueRouter({
    //routes是路由规则数组
    routes: [
        //path设置为/表示页面最初始的地址 / ,redirect表示要被重定向的新地址,设置为一个路由即可
        { path:"/",redirect:"/user"},
        { path: "/user", component: User },
        { path: "/login", component: Login }
    ]
})

  • \color{pink}{ 创建公共样式表}
// 首先在src中的assets中创建一个css全局样式表
//为了避免窗口伸缩影响后期的样式,在全局中对窗口进行设置
/* 全局样式表 */
html,
body,
#app {
  height: 100%;
  margin: 0;
  padding: 0;
  min-width: 1366px; //窗口最小宽度为1366px
}

//在入口文件中引入样式表
//此样式表为项目中的路径和名称
import './assets/css/global.css'
  • \color{pink}{axios请求全局封装}
    npm install axios--save
import axios from 'axios'
//在入口index.js中导出axios请求
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
//将其挂载成$http的形式
Vue.prototype.$http = axios

//请求中验证是否有token值
axios.interceptors.request.use(config => {
  // NProgress.start()
  config.headers.Authorization = window.sessionStorage.getItem('token')
  return config
})
  1. axios页面中的使用
//项目中的实际请求案例
//因为返回值为promise,所以使用async和await去简化异步
 async getUserList() {
      const { data: res } = await this.$http.get('users', {
        params: this.queryInfo,
      });

\color{pink}{ 项目中的插件}

  • 时间过滤器
    npm install moment --save
// 在入口index.js中导入格式化时间的模块
import moment from 'moment'

Vue.filter('dateFormat', function (dateStr, formatStr = 'YYYY-MM-DD HH:mm:ss') {
  // 在过滤器的处理函数中,最后,必须 return 一个东西,这样,才是一个合法的过滤器
  return moment(dateStr).format(formatStr)
})

//页面中调用时间过滤器
 <el-table-column label="创建时间" width="180px">
      <template slot-scope="scope">
          // dateFormat 定义的时间过滤器名称
          <span>{{ scope.row.add_time | dateFormat }}</span>
      </template>
 </el-table-column>
  • 富文本编辑器
  1. npm安装
    npm install vue-quill-editor
    2.在安装依赖
    npm install quill
//富文本编辑器
import VueQuillEditor from 'vue-quill-editor'
//富文本编辑器样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css' 
// 将富文本编辑器,注册为全局可用的组件
Vue.use(VueQuillEditor)

3.页面中使用效果

  <quill-editor v-model="addForm.goods_introduce"> </quill-editor>
export default {
  data() {
    return {
      //   添加表单的数据
      addForm: {
        // 商品详情字段
        goods_introduce: '',
      },
  },
  • 绿色进度条NProgress的实现(项目优化功能)
    1.安装
    npm install --save
    2.使用
//导入
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

  // 挂载路由导航
  router.beforeEach((to, from, next) => {
    // 如果是跳转到登录页那么就next
    if (to.path === '/login') return next()
    NProgress.start()
    const tokenStr = window.sessionStorage.getItem('token')
    if (!tokenStr) return next('/login')
    return next()
  })
router.afterEach(() => {
  NProgress.done()
})

  • 树状表格插件
    1.安装
    npm i vue-table-with-tree-grid -S
    2.引入
//注册全局树状表格
import TreeTable from 'vue-table-with-tree-grid'
Vue.component('tree-table', TreeTable)

3.页面使用

   <!-- 表格 -->
      <tree-table
        class="treeTable"
        // *catelist* 商品分类的数据列表
        :data="catelist"
        // 为table指定列
        :columns="columns"
        :expand-type="false"
        :selection-type="false"
        show-index 
        index-text="#"
        border
        :show-row-hover="false"
      >
  • element中组件挂成全局组件
// 挂载成全局事件
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm

//message调用
this.$message.success('需要提示的消息');
this.$message.error('需要提示的消息');
this.$message.warning('需要提示的消息');

//MessageBox调用
async removeById() {
//返回的数据是promise,需要async和await
      const confirmResult = await this.$confirm(
        '此操作将永久删除该文件, 是否继续?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
      ).catch((err) => err);
//使用catch捕捉返回的错误

//对confirmResult 是否等于confirm来判断点击了取消还是确定
if (confirmResult !== 'confirm'){
   return this.$message.error('你取消了删除');
}else{
  //发起axios请求
}
  • 解决element-ui中3.0版本的重复点击菜单报错问题
//在路由配置文件中设置
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
},

  • loadsh的使用
    lodash 是一个 JavaScript 实用工具库,提供一致性,及模块化、性能和配件等功能
    1.安装
    npm i --save lodash
    2.页面引入使用
//此例子为echarts合并问题
<template>
  <div>
    <!-- 卡片视图 -->
    <el-card>
      <div id="main" style="width: 750px;height:500px;"></div>
    </el-card>
  </div>
</template>
<script>
import echarts from 'echarts';
import _ from 'lodash';
export default {
  data() {
    return {
      // 需要合并的数据
      options: {
        title: {
          text: '用户来源',
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            label: {
              backgroundColor: '#E9EEF3',
            },
          },
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
        },
        xAxis: [
          {
            boundaryGap: false,
          },
        ],
        yAxis: [
          {
            type: 'value',
          },
        ],
      },
    };
  },
  created() {},
  async mounted() {
    //   此时页面的dom元素已经渲染完毕了,初始化echarts
    var myChart = echarts.init(document.getElementById('main'));
    const { data: res } = await this.$http.get('reports/type/1');
    if (res.meta.status !== 200)
      return this.$message.error('获取折线图数据失败');
    // 数据配置项
    const result = _.merge(res.data, this.options);
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(result);
  },
};
</script>

3.\color{pink}{ loadsh深拷贝浅拷贝使用}

//此功能为添加商品案例
/* 项目中需要把表单数据中的数据格式修改才能进行axios请求传参,故需要深拷贝来完成此功能 */
  methods: {
    // 添加商品
    add() {
      this.$refs.addFormRef.validate(async (valid) => {
        if (!valid) return this.$message.error('请填写必要的表单项');
        // loadsh cloneDeep(obj)深拷贝
        const form = _.cloneDeep(this.addForm);
        form.goods_cat = form.goods_cat.join(',');
        // 处理动态参数
        this.manyTableData.forEach((item) => {
          const newInfo = {
            attr_id: item.attr_id,
            attr_value: item.attr_vals.join(' '),
          };
          this.addForm.attrs.push(newInfo);
        });
        // 处理静态参数
        this.onlyTableData.forEach((item) => {
          const newInfo = { attr_id: item.attr_id, attr_value: item.attr_vals };
          this.addForm.attrs.push(newInfo);
        });
        form.attrs = this.addForm.attrs;
        // 发起请求,请求数据
       const {data:res}=await this.$http.post('goods',form)
       if(res.meta.status!==201) return this.$message.error('添加商品失败')
       this.$message.success('添加商品成功')
       this.$router.push('/goods')
      });
    },
  },
  • 使用计算属性
  computed: {
  //需要的时候直接使用this.cateId
  //选中的三级分类的id
    cateId() {
      if (this.addForm.goods_cat.length === 3) {
        return this.addForm.goods_cat[2];
      }
      return null;
    },
    // 计算标题
    //动态绑定来使用
    titleText() {
      if (this.activeName === 'many') {
        return '动态参数';
      } else {
        return '静态属性';
      }
    },
   // 如果按钮需要被禁用,则返回true,否则返回false
    isBtnDisabled() {
      if (this.selectCateKeys.length !== 3) {
        return true;
      }
      return false;
    }
  },
  • \color{pink}{webpack打包上线}
    1.将入口文件修改成两个main-dev.js(开发模式),main-prod.js(发布模式)
    2.因为无法找到打包文件,所以自己创建配置文件vue.config.js文件
module.exports = {
    chainWebpack: config => {
        // 发布模式
        config.when(process.env.NODE_ENV === 'production', config => {
            config.entry('app').clear().add('./src/main-prod.js')
            //使用externals设置排除项
            //根据vue ui可视化管理工具进行排除资源大的依赖
            config.set('externals', {
                vue: 'Vue',
                'vue-router': 'VueRouter',
                axios: 'axios',
                lodash: '_',
                echarts: 'echarts',
                nprogress: 'NProgress',
                'vue-quill-editor': 'VueQuillEditor',
                'moment':'moment'


            })
            config.plugin('html').tap(args=>{
                args[0].isprod=true
                return args
            })

        })
        // 开发模式
        config.when(process.env.NODE_ENV === 'development', config => {
            config.entry('app').clear().add('./src/main-dev.js')
        })
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355