前言:后台运营管理系统几乎是我这一年来一直在跟进的需求,因为随着产品线扩大,它本来由一个替补或者说增进的使用场景变成一个必不可缺的一部分。

PS,去年回广州重新找工作,告别了待了两年的深圳。还记得当时来到现在这家公司时我没用过工作流,没在实际项目中使用自动化构建,没有在实际项目中使用除Jquery外的开发框架,也因为之前的项目单一即便公司背景不错但换工作的时候还是碰壁。入职前两个月项目组刚建不久,每天和一群后台/客户端小哥哥一起奋战,赶着发版,开始人生中第一次996,累但是很满足。新项目组只有我一个前端,对业务不熟悉时经常跑大部门另一个前端组取经,感谢他们对我的帮助,几乎一周上手。哈哈觉得我的适应能力和学习能力还是棒棒的,这也验证了一句话,实践是检验真理唯一标准,学习一样东西最好的方法是去使用它,恩。

好了,不废话了。

iView

iView是一套基于Vue.JS的高质量UI组件库,官网地址:任意门

整个运营系统是以这套ui框架搭建,我觉得做完一个后台运营系统是基本符合开发需求,当然也不是说可以都照搬,一些特殊功能还是要结合产品需求做变更。

由于基于Vue,所以IE兼容不是很好。所以我在入口index.js中做了IE判断提醒,我觉得这是必须的。

项目基本结构:

  • css:不必多说,就是用来写自定义样式的

  • data:用来存放iview框架,包括css和js

  • html:通用,引入通用链接如JQuery等,配置title等,html代码只有一句 <div id = "app"></div>,到时vue渲染使用

  • js:基本开发都是在这里

    • api:用来存储各个tab的接口请求

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      var dataType = 'json';
      var timeout = 15000;
      var url = '接口通用域名地址';
      var request = function(opt) {
      return $.ajax({
      method: opt.method || 'GET',
      dataType: dataType,
      timeout: timeout,
      url: url + opt.url,
      data: opt.data || null
      });
      };
      module.exports = {
      //数据1
      data1:function(data){
      return request({
      url: '接口详细地址',
      data: data,
      });
      }
      }
    • common

      api.js:这里其实跟上面的api文件夹作用一样,区别在于它全部写在了一个文件里,一开始是直接用的这个,后来随着项目的扩大及接口改版,觉得还是要根据功能单独提取出来比较好,这样也有利于团队一起维护;

      bus.js:这个不用多说,vue-router的中间组件

      routeList.js:这个是用来存储单页应用跳转地址

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      var page1 = require('module/page1/main');
      module.exports = {
      routes: [
      {
      path: '/page1',
      component: page
      },
      {
      path: '*',
      redirect: '/home'
      }
      ]
      }

      tools.js:

      这个是用来区分权限和放一些公用的组件

      1
      2
      3
      4
      5
      6
      7
      var GetMenus =function(){
      ...
      }//tab权限区分
      module.exports = {
      GetMenus: GetMenus,
      ...
      };

      以上4个文件各司其职,可以看为通用组件。

      然后接着看,lib文件夹是我用来放公共组件的,比如一些处理ajax的公共方法,vendor用来放第三方组件,比如vue-qrcode,用来显示二维码,这里是在支付这一块需要用到,比如微信支付。

      然后各个主要需求内容其实都是在module文件里。这里就是可以像平时写vue页面一样,在每个页面写好你的功能就可以。

      整个框架基本就是这样,蛮明朗的。vue+iviewUi,前端+后台的对接,就可以完成这套运营系统了。各个页面的信息基本独立,公共的部分提取出来,一些需要传递的信息可以使用busEvents,无需引用vuex,其次ajax、功能模块单独区分,后期维护和其他人接手的话基本无成本,查找也方便。其他的使用在iview官网都可以找到解决办法,然后接下来介绍下其他特别的地方。

其他

在使用iView有没有遇到问题,当然有…有些是踩到的小坑,有些是iview满足不了你的需求,你要自己解决。

  • <Time-picker format="HH:mm" type="timerange" v-model="timeInterval" placeholder="推荐时间段" style="width: 400px;"></Time-picker>

    当timeInterval定义为字符串timeInterval:''会把页面搞崩,因为动态监听的值类型问题,必须为数组。

  • 二级联动

    iView里有二级联动的组件cascader,但是是在一个选择框进行分级,我的需求是父子选择框是独立的选择框,所以仍然用到select

    所以这里要自己处理逻辑:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    computed: {
    self: function(){
    return this;
    },
    //第二个选择框
    levels:function(){
    var levels =[],selectedDepart = this.$data.category_id;
    this.$data.categorys.forEach(function(d){
    if(d.id == selectedDepart){
    levels = d.levels;
    }
    });
    return levels;
    },
    },
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      <!--父选择框-->
    <Form-item label="选择品类" prop="coefficient">
    <Select v-model="category_id" style="width:350px">
    <Option v-for="item in categorys" :value="item.id" :key="item.id"> {{item.category_name}}</Option>
    </Select>
    </Form-item>
    <!--子选择框-->
    <Form-item label="段位">
    <Select v-model="level1" style="width:350px">
    <Option v-for="item in levels" :value="item.level" :key="item">{{item.name}}</Option>
    </Select>
    </Form-item>
  • 待续…

​ 其实在项目中会遇到各种情况,比如你获取到的数据跟呈现在页面的数据可能是两种形式,中间的处理当然是需要自己写,框架拯救不了你。还有一些东西是可以利用框架来进行拓展,比如Modal弹框你可以用来做查看图片,具体情况具体分析。因为我没使用过elementUI,所以我也不知道具体的区别在哪里,简单看文档的话感觉是很相似的。无论是用iView还是其他,这些说到底都是一种辅助作用,简洁开发流程和优化呈现方式,作为前端应该就算它们提供不了功能也要能自己写出来,不能以框架没有做到为借口。打个很简单的比方,Checkbox可以用于多选,它也提供了一个全选的功能,那如果没有提供的话,我们也应该自己能写得出。

1
2
3
4
5
6
<i-form inline>
<Form-item>
<Checkbox style="margin-left: 10px;" v-model="selectAll" v-if="ifselectAll">本页全选</Checkbox>
<p style="margin-left: 10px;" v-else>已选择{{muchcount}}位</p>
</Form-item>
</i-form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
data: function () {
return {
self: this,
columns: [{
title: '选择',
key: 'choose',
width: 50,
render: function (row, columns, index) {
return '<Checkbox disabled v-model="self.muchids.num' + index + '" @on-change="ifchange(' + row.id + ')" v-if="self.selectAll"></Checkbox><Checkbox v-model="self.muchids.num' + index + '" @on-change="ifchange(' + row.id + ')" v-else></Checkbox>'
}
},
]},
...
...
methods:{
//多选选择判断
ifchange: function (id) {
var self = this;
var index = self.muchList.indexOf(id)
console.log(index)
if (index != -1) {
self.muchList.splice(index, 1)
} else {
self.muchList.push(id);

}
self.ifselectAll = self.muchList.length ? false : true;

self.muchcount = self.muchList.length;
console.log(self.muchList)

},
}

这样我就自己写出了一个全选的功能:

以上只是个栗子,建议可以直接用checkbox即可。框架和工具是为了辅助我们更好的开发,而不是去限制我们开发,这是我在这个过程中意识到的最大的收获。