1.根据后台数据动态生成表格的表头

<el-table :data="tableData" border>
        <el-table-column
          v-for="item in tableColumns"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
        >
        </el-table-column>
</el-table>

data () {
   
    return {
   
      tableData: [],
      tableColumns: [ // 已知表头
        {
   
          label: '日期',
          prop: 'tDate'
        },
        ...
      ]
    }
  },
  methods: {
   
    get_tabledata () {
   
      const self = this
      var res = {
   
        status: 200,
        message: 'success',
        data: {
   
          addColumn: [ // 后台动态数据添加到表头
            {
   
              prop: 'groupMoney1',
              label: '渠道组1'
            },
            ...
          ],
          inData: [
            {
   
              tDate: '2020-11-01',
              sumCost: 12312313,
              sumMoney: 12312313,
              sumDAU: 2333,
              IosMoney: 11111,
              androidMoney: 23933,
              groupMoney1: 22222,
              groupMoney2: 67555
            },
            ...
          ]
        }
      }
      self.tableData = res.data.inData
      self.tableColumns = [...self.tableColumns,...res.data.addColumn] // 合并表头数组
    }
  },

2.html2canvas插件实现截图

http://html2canvas.hertzen.com/getting-started

<!--安装插件-->
npm install html2canvas

<!--在script标签中引入实例-->
import html2canvas from 'html2canvas';

<!--在button点击事件或者created事件中画图-->
html2canvas(document.body).then(function(canvas) {
   
    document.body.appendChild(canvas);
});

<!--项目中使用-->
<Button type="primary" ghost @click="explain_handle">输出分析报告</Button>

explain_handle () {
   
      this.explain_modal = !this.explain_modal
      html2canvas(document.getElementById('table_box')).then(function (canvas) {
   
        document.getElementById('img_box').appendChild(canvas)
      })
    },

3.月份选择器设置初始值

/** * @description 用于将获取yyyy-mm-dd格式的当前时间,且是1号 */
export const month_now = () => {
   
  var d = new Date()
  var datetime = ''
  if (d.getMonth() < 9) {
   
    datetime = d.getFullYear() + '-0' + (d.getMonth() + 1) + '-01'
  } else {
   
    datetime = d.getFullYear() + '-' + (d.getMonth() + 1) + '-01'
  }
  return datetime
}

created () {
   
    const self = this
    // 这里的空格''使得生成的中国标准时间的时分秒是00:00:00
    const now = new Date(month_now() + ' ')
    const nowdate = [now]
    // monthtime是时间选择器v-model的时间变量
    self.monthtime = nowdate
    console.log(nowdate)
    self.month_time = month_handle(self.monthtime)
  }

4.vue起服务运行dist

// console命令
npm i -D live-server

// 修改package.json
"scripts": {
   
   "serve": "vue-cli-service serve",
   "build": "vue-cli-service build",
   // 增加一个start命令
   "start": "live-server ./dist -o",
   "lint": "vue-cli-service lint"
 },

5.在项目中按需引入loading指令

  • 去github看element的源码:
  • https://github.com/ElemeFE/element/blob/dev/src/index.js
  • 可以看到它export default了Loading
  • 在自己项目的src/main.js中去按需引入:
// 可以直接写'element-ui'是因为框架就是这么抛出的,用element-ui代表了指定路径,可以去node-modules下面去看看有没有一个名为element-ui的文件夹
// { Loading }这种方式是ES6的解构赋值
import {
    Loading } from 'element-ui'

Vue.use(Loading.directive)
  • 在表格中使用:
 <el-table
       v-loading="tableloading"
       :data="tableData"
       style="width: 100%;"
     >
// 默认值 
data () {
   
   return {
   
     tableloading: false,
     
// 开始请求的时候设置为true,加载动画开始
getYYReportListByGroup (req_obj) {
   
     this.tableloading = true
     
// 拿到数据之后又设置为false,停止加载
this.tableloading = false

6.过滤器使用

  • 在对表格数据进行特定展示时,一般使用filter,这样可以避免直接改变tabledata
  • 方法一:直接写
// monthHandle是方法名,也可以传参
<el-table-column prop="date" label="月份" fixed min-width="82px">
         <template slot-scope="scope">
             <span>{
   {
    scope.row.date | monthHandle }}</span>
           </template>
       </el-table-column>
       
// cell是默认第一个参数(scope.row.date),传过来的参数默认在第二个位置
<script>
export default {
   
 name: 'groupgame_day',
 components: {
   },
 data () {
   
   return {
   }
 },
filters: {
   
   monthHandle (cell) {
   
     return cell.split('-')[1] + '月'
   }
 },
       
  • 方法二:在common/js中创建一个filters.js文件
  • 把这个方法抛出,在main.js中全局引入
// 日期到时月,X月
export function monthHandle (val) {
   
  if (!val) return val
  return val.split('-')[1] + '月'
}

import * as Filter from '@/common/js/filters'

// 全局过滤器
for (const key in Filter) {
   
  Vue.filter(key, Filter[key])
}

7.echarts

peerDependences 强制依赖,vue-echarts强制依赖vue(几十k)和echarts(比较大)

<mark>关于echarts和vue-echarts</mark>

  • 都是扩展包,然后vue-echarts其实就是用vue把echarts封装了一层
  • echarts可能更靠近浏览器,然后vue-echarts可能更靠近es6
  • 在vue项目中使用vue-echarts而不是echarts,如果要使用echarts的话,一般要自己封一层

<mark>区分cli2和cli3</mark>

  • 看有没有vue.config.js文件,如果有的话,就是3,没有的话就是2
  • 而且2比3多了一个build文件

<mark>安装和使用</mark>

https://github.com/ecomfe/vue-echarts/blob/master/README.zh_CN.md

  • 安装指定版本的echarts:npm install echarts@4.2.0-rc.2 --save
  • 安装vue-echarts:npm install echarts vue-echarts
  • 配置项可以去参考echarts的配置项
  • 按需引入不用在入口文件中去引入,全局引入才需要
// 全局引入
import VueECharts from 'vue-echarts' // 在 webpack 环境下指向 components/ECharts.vue
Vue.component('v-chart', VueECharts)

//-----自己抽的组件中按需引入------
// 手动引入 ECharts 各模块来减小打包体积
import ECharts from 'vue-echarts'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/tooltip'

// 以上具体模块的路径可以在node modules里面去看

components: {
   
    'v-chart': ECharts
  },
  • 注意:title/legend/tooltip等等,如果需要使用的话,也都是需要按需引入的
  • 像这样:import ‘echarts/lib/chart/line’
  • 但是需要自己去node modules里面去查看路径
  • appendData添加数据;showLoading加载动画;getDataURL输出为图片;

<mark>没有显示的原因</mark>

  • 先去查看DOM,有可能是高度设置问题

8.循环渲染/动态增删

  • 在需要变化的dom上加v-for
  • :key绑定item.id
  • 循环的时候除了可以拿item,也可以加第二个默认的index参数
  • 即:(item, index) in arr
  • 可以同时使用写死的class和绑定变量的:class,但是这两个分别都最多只能存在一个(https://cn.vuejs.org/v2/guide/class-and-style.html)
  • :class后面可以是class的数组也可以是计算属性(https://cn.vuejs.org/v2/guide/computed.html)
<div class="comBox">
  <div v-for="(item,idx) in com_arr" :key="item.id" class="comcell" :class="{'selcomcell': item.check}" @click="selcom_handle()">
    <span>{
   {
   item.name}}</span>
    <Icon type="md-close-circle" @click.stop="close_com(idx)" />
  </div>
  <button type="text" class="add-btn" @click="addcom_handle()">+添加</button>
</div>

<mark>计算属性和函数的区别</mark>

  • 看上去效果并没有什么区别
  • 但是计算属性是基于响应式依赖进行缓存的,只在相关响应式依赖发生改变时才会重新求值,如果依赖没有发生改变,多次访问计算属性就会立即返回之前的计算结果,不必再次执行函数。
  • 如果不希望有缓存,就用方法代替

9.上传功能实现

http://v1.iviewui.com/components/upload

  • 通过:before-upload来实现手动上传
  • 一般情况会在action里面直接写上传地址,通过接口上传文件和进行返回数据处理的话,一般有两种
  • 一种就是action=“”
  • 另一种就是:before-upload绑定的方法返回false就可以阻止默认上传流程,手动控制文件上传。
<Upload action="" :before-upload="preUpload">
  <el-image class="m-image-box" :src="base64Image" fit="scale-down"></el-image>
</Upload>
  • 上传前操作,可以判断文件类型、文件大小是否符合要求
preUpload (file) {
   
  const {
   size, name, type} = file
  if (!['image/png', 'image/jpeg'].includes(type)) {
   
    this.$Message.error({
   
      closable: true,
      duration: 5,
      content: `上传的文件名 ${
     name} 格式错误!`
    })
    return false
  }
  if (size > 300 * 1024) {
   
    this.$Message.error({
   
      closable: true,
      duration: 5,
      content: `上传的文件名 ${
     name} 超过限制大小`
    })
    return false
  }
  this.uploadFile(file)
  return false
},
  • FileReader这个是原生的文件阅读器,在图片加载完成之后实现一个预览的效果
uploadFile (file) {
   
  const reader = new FileReader()
  const that = this
  reader.readAsDataURL(file)
  reader.onload = function (e) {
   
    that.base64Image = this.result
    that.file = file
  }
},

10.关于请求的三种方式

request.class.js

  • reqData: 一般请求,请求参数为{ key: value }这种模式,而且value一般是字符串格式
    <mark>‘Content-Type’: ‘application/x-www-form-urlencoded’</mark>
  • reqFormData:文件上传的时候就是使用这种模式
  • reqJson:复杂模式,value可以是object类型或者对象嵌套对象(后端处理json类型的参数增加@RequestBody)
    <mark>‘Content-Type’: ‘application/json’</mark>

11.echarts的一些配置

  • 参考线<mark>markLine</mark>,import ‘echarts/lib/component/markLine’
  series: [
    {
   
      name: '趋势',
      type: 'line',
      data: [],
      smooth: true,
      markLine: {
   
        data: [
          {
   type: 'average', name: '平均值'}
        ]
      }
    },
    {
   
      name: '模拟',
      type: 'line',
      data: [],
      smooth: true,
      markLine: {
   
        /* 以下设置一行后,平均线就没有开始和结束标记了(即看不见箭头了) */
        symbol: 'none',
        data: [{
   
          name: '平均线',
          // 支持 'average', 'min', 'max'
          type: 'average',
          lineStyle: {
   
            normal: {
   
              color: 'green',
              width: 2,
              type: 'solid'
            }
          }
        }]
      }
    }
  ]
  • Y轴分割线隐***ark>splitLine, splitLine.show=false
  yAxis: {
   
    type: 'value',
    splitLine: {
   
      show: false
    }
  }
  • 区域缩放<mark>dataZoom</mark>
dataZoom: [
    {
   
      type: 'slider',
      show: true,
      xAxisIndex: [0],
      start: 20,
      end: 100
    }
],
  • 折线变曲线<mark>smooth</mark>,如上smooth: true
  • 虚线<mark>lineStyle</mark>,series-line.lineStyle.type = ‘dashed’
  • 折线图和柱状图切换magicType
import 'echarts/lib/component/toolbox'

toolbox: {
   
    feature: {
   
      magicType: {
   
        type: ['line', 'bar']
      }
    }
},

12.升级项目中iview的版本

  • 4.4.0 -> 4.5.0
  • 执行命令npm install view-design --save
  • 这时候可能会报错找不到XXX文件,只需关闭vscode,重新打开,即可享受新版本的功能