乐趣区

关于vue.js:工作笔记20210615至今

Echarts 篇

根底

所有图都是一个 dom,一个 options 的写法,次要的 options 的配置,太多了

html 局部
<div
    :id="config.id"
    style="width:100%;height: 100%">
</div>

js 局部
import echarts from 'echarts'
import 'echarts-wordcloud' // 词云图,独自引入
Vue.prototype.$echarts = echarts

const myChart = this.$echarts.init(document.getElementById(this.config.id))

myChart.setOption(this.config.option)

词云图

词云图是要另外装置依赖的,echarts 外面并没有蕴含这个性能

"dependencies": {
    "axios": "^0.21.1",
    "core-js": "^3.15.2",
    "echarts": "^4.9.0", // 本地
    "echarts-wordcloud": "^1.1.3",// 就是这个
    "element-ui": "^2.4.5",
    "html2canvas": "^1.0.0-rc.7",
    "vue": "^2.6.14",
    "vue-router": "^3.5.2",
    "vuex": "^3.6.2",
    "xlsx": "^0.16.5"
  },

配置

// 声量情感散布 - 提及内容词云
      wordOption: {
        id: 'wordOption',
        option: {
          series: [
            {
              // 词的类型
              type: 'wordCloud',
              // 设置字符大小范畴,那种字太多的有可能因为最小值太小不显示,能够设大一点
              sizeRange: [16, 58],
              // 每个字的歪斜角度
              rotationRange: [-45, 90],
              textStyle: {
                normal: {
                  // 生成随机的字体色彩
                  color: function () {
                    return 'rgb(' + [Math.round(Math.random() * 160),
                      Math.round(Math.random() * 160),
                      Math.round(Math.random() * 160)
                    ].join(',') + ')'
                  }
                }

              },
              // 不要遗记调用数据
              data: [
                {
                  'name': '花鸟市场',
                  'value': 1446
                },
                {
                  'name': '汽车',
                  'value': 928
                },
                {
                  'name': '视频',
                  'value': 906
                },
                {
                  'name': '电视',
                  'value': 825
                },
                {
                  'name': '动漫',
                  'value': 486
                }
              ]

            }
          ]
        }
      },

柱状图

配置

// 声量情感散布
      volEmotionOption: {
        id: 'volEmotionOption',
        option: {color: ['#32B0F2', '#006699', '#4cabce'], // 这个是色彩
          xAxis: {
            type: 'category',
            data: []},
          yAxis: [
            {
              name: '声量',
              type: 'value'
            },
            {
              name: '占比',
              type: 'value',
              min: 0,
              max: 100,
              axisLabel: {formatter: '{value} %'
              }
            }
          ],
          legend: {
            bottom: '5%',
            data: ['总体', '侧面', '负面']
          },
          series: [
            {
              name: '总体',
              type: 'bar',
              data: [100]
            },
            {
              name: '侧面',
              type: 'bar',
              data: [200]
            },
            {
              name: '负面',
              type: 'bar',
              data: [300]
            }
          ]
        }
      },

柱状图的 xAxis 和 series,legend 的关系有点奇怪,emmm,我笔记懒的具体些了,我就大略说一下
xAxis.data,比方有 3 个,[1,2,3];
series 的每一项的 data 也必须有 3 值,对应每个柱子的内容,留神不是 series 的个数,是 series 每一项的 data 这个个数;

series: [
            {
              name: '总体',
              type: 'bar',
              data: [100,200,300]  // 是这个
            },

legend 是图上面的图例,能够点击让柱子隐没,然而它的 data 的值是对应 series 每一项的值的 name,如果 series 的每一项没 name,你怎么配置 legend 都没用

饼图

配置

officialVol: {
        id: 'officialVol',
        option: {color: ['rgb(114, 143, 223)', 'rgb(106, 203, 148)'],
          tooltip: {trigger: 'item'},

          legend: {bottom: '5%'},
          series: [
            {
              name: '占比',
              type: 'pie',
              radius: '50%',
              data: [{ value: 1048, name: 'PGC'},
                {value: 735, name: 'UGC'}
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        }
      },

漏斗图

配置

// 声量转化剖析
      volConversion: {
        id: 'volConversion',
        option: {
          tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c}%'
          },

          series: [
            {
              name: '占比',
              type: 'funnel',
              top: 60,
              width: '60%', // 大小
              left: '20%', // 跟下面奏够 100,就是左右居中
              bottom: 60,
              min: 0,
              max: 100,
              minSize: '0%',
              maxSize: '100%',
              label: {position: 'right'},

              data: [{ value: 60, name: '拜访'},
                {value: 40, name: '征询'},
                {value: 20, name: '订单'},
                {value: 80, name: '点击'}
              ]
            }
          ]
        }
      },

柱状图 - 沉积

配置

brandInfluence: {
        id: 'brandInfluence',
        option: {color: ['#32B0F2', '#006699', '#4cabce'],
          xAxis: {
            type: 'category',
            data: ['流动前', '流动中', '流动后']
          },
          yAxis: [
            {
              name: '声量',
              type: 'value'
            }
          ],
          legend: {
            bottom: '0%',
            data: ['平安的', '奥运的', '奥运的 2', '奥运的 3', '奥运的 4']
          },
          series: [
            {
              name: '平安的',
              type: 'bar',
              barWidth: 40,
              stack: 'default', // 轻易设置一样字符串
              data: [100, 99, 88]
            },
            {
              name: '奥运的',
              type: 'bar',
              barWidth: 40,
              stack: 'default',// 必须一样,data: [100, 99, 88]
            },
            {
              name: '奥运的 2',
              type: 'bar',
              barWidth: 40,
              stack: 'default',
              data: [100, 99, 88]
            },
            {
              name: '奥运的 3',
              type: 'bar',
              barWidth: 40,
              stack: 'default',
              data: [100, 99, 88]
            },
            {
              name: '奥运的 4',
              type: 'bar',
              barWidth: 40,
              stack: 'default',
              data: [100, 99, 88]
            }
          ]
        }
      }

折线图

配置

// 流动声量变化趋势
      activityVolLine: {
        id: 'activityVolLine',
        option: {color: ['#32B0F2', '#006699', '#4cabce'],
          xAxis: {
            type: 'category',
            data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
          },
          yAxis: [
            {
              name: '声量',
              type: 'value'
            }
          ],
          legend: {
            bottom: '5%',
            data: ['Q3 营销声量', 'Q3 整合营销 & 品牌声量']
          },
          series: [
            {
              name: 'Q3 营销声量',
              type: 'line',
              data: [120, 132, 101, 134, 90, 230, 210]
            },
            {
              name: 'Q3 整合营销 & 品牌声量',
              type: 'line',
              data: [220, 182, 191, 234, 290, 330, 310]
            }
          ]
        }
      },

散点图,气泡图

配置

option = {
    xAxis: {
        name: '真粉数', // 依据你的数据主动生成 x 轴值
         splitLine: {show: false} // 显示格子线
    },
    yAxis: {name: '美誉度 (%)',// 依据你的数据主动生成 y 轴值
        splitLine: {show: false} // 显示格子线
    },
    series: [
        {
            name: '彭于晏',
            data: [['1555',80] // 二维数组, 两个值够了
            ],
            type: 'scatter',
            symbolSize: 40, // 管制气泡大小
            label: {
                normal: {
                    show: true,
                    formatter: function (param) {return '彭于晏'},
                    position: 'top'
                    
                }
            },
            itemStyle: {
                normal: {
                    shadowBlur: 10,
                    shadowColor: 'rgba(120, 36, 50, 0.5)',
                    shadowOffsetY: 5,
                    color: 'red'
                }
            }
        },
        {
            name: '陈小春',
            data: [['1355',60] // 二维数组, 两个值够了
            ],
            type: 'scatter',
            symbolSize: 10, // 管制气泡大小
            label: {
                normal: {
                    show: true,
                    formatter: function (param) {return '陈小春'},
                    position: 'top'
                    
                }
            },
            itemStyle: {
                normal: {
                    shadowBlur: 10,
                    shadowColor: 'rgba(120, 36, 50, 0.5)',
                    shadowOffsetY: 5,
                    color: 'red'
                }
            }
        }
    ]
};

Echarts 罕用配置补充

太多太多太多了,没方法,用到就记一下
(1) 数据视图

toolbox: {
        show: true,
        feature: {
          dataView: {
              show: true,
              title: '名字', // 这个是鼠标悬浮下来的文案
              readOnly: true,
              lang: ['',' 敞开 ',' '] // 这个才是关上后的文案
          }
        }
    },

(2) 缩放
如果图表的数据太多什么的, 全副都挤在一起显示,能够加这个

dataZoom:{
      show: true,
      height: 52, // 高度
       bottom: '0', // 地位,默认在底部
       start: 0, // 不分明
       end: 50, // 不分明
       fillerColor: 'red', // 背景色
       handleColor: 'skyblue' // 左右两边的小块
}

(3) 图例缩放
下面那个是表的缩放,如果是图例的,legend 那个,能够加个

legend:{type: 'scroll'}

(4) tooltip 配置
鼠标悬浮下面的显示,formatter 是自定义

 tooltip: {
              trigger: 'axis', // 触发范畴,个别写这个,不要写 item,item 的话触发面积太小,要点到线或者柱子才行
              axisPointer: {type: 'shadow' // 这个是暗影,hover 成果默认是一根线,加这个就变成暗影},
formatter: function (params) { //params 这个有你须要显示的参数
                return 'lalala'
              }
            },

(5) x,y 轴配置

yAxis: {
              name: '声量',
              type: 'value',
              axisLabel: {formatter: '{value} %' // 如何显示
            },
            axisLine: { // y 轴的连线
              show: true, // 是否要连起来
              lineStyle: {color: 'red'}
            },
            axisTick: { // 刻度,突出来的
              show: true
            },
            splitLine: { // 距离线
              lineStyle: {
                // 距离色
                color: ['skyblue']
              }
            }
          }

(6) 如何在 series 加多点参数
需要是这样 tooltip 要显示一些额定的参数,如果能间接在 format 参数外面拿到就不必额定解决,留神
data 外面的子项肯定是对象能力这样做,如果是[100], 是不行的

series: [
            {
              name: '总体',
              type: 'bar',
              data: [  // 这个 data 肯定是这个格局
                {
                  value: 100,
                  temtemtem: '自定义参数'
                }
              ]
            },
]
// 下面你这样写了之后,你就能够
 tooltip: {
              trigger: 'item',
              formatter: function (params) {return '声量值:' + params.data.temtemtem}
            },

(7) setoptions 第二个参数问题
至多我这边是有遇过,当图表数据从少到多的时候,失常变动,然而,如果是从多变少,比方少一个数据,图表就不失常了,还是变少之前的样子
起因是在第二个参数,设置成 true 就能够,默认是 false

this.myChart.setOption(copyconfig.option, true)

(8) 柱状图柱子间隙
这个应该比拟少用到,不过还是记一下, 情景我很难解释,大略是 legend 和 series 不能同时满足的时候,你必须清掉 xais 的 data 值让它能够失常显示,然而会挤在一起
barGap, 每一个都要设置,而且是一样的值才失效

 xAxis: {data: []
          },
legend: {
            bottom: '5%',
            data: ['总体','侧面','负面']
          },
series: [
            {
              name: '总体',
              type: 'bar',
              
              barGap: '100%',
              data: [
                {value: 100}
              ]
            },
           {
              name: '侧面',
              type: 'bar',
              
              barGap: '100%',
              data: [
                {value: 200}
              ]
            },
            {
              name: '负面',
              type: 'bar',
              
              barGap: '100%',
              data: [
                {value: 300}
              ]
            },
          ]

(9) 双 y 轴
个别双 y 轴,左边的要有另外一组 series 数据,个别是柱状图配折线图我遇到的比拟多
用 yAxisIndex 定位 y 轴

yAxis: [
          {
            name: "互动量",
            type: "value",
            axisLine: {
              lineStyle: {color: "#A9A9A9",},
            },
            splitLine: {
              lineStyle: {
                // 距离色
                color: ["#F5F5F5"],
              },
            },
          },
          {
            name: "贡献度(%)",
            type: "value",
            min: 0,
            max: 100,
            axisLabel: {formatter: "{value} %",
            },
            axisLine: {
              lineStyle: {color: "#A9A9A9",},
            },
            splitLine: {show: false,},
          },
        ],
series: [
          {
            name: "互动量",
            type: "bar",
            barWidth: 40,
            data: [],},
          {
            name: "贡献度",
            data: [],
            type: "line",
            yAxisIndex: 1, // 用这个定位
          },
        ],

(10) 饼图为 0 暗藏显示
这种做法个别有两种,一种就是常见的过滤数据,我上面这种是不过滤的,通过管制 label 和 labelLine
然而通过测试发现,label 的 show 关了后,labelLine 也会关,不过保险起见,两个都写

series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: '50%',
      data: [
        { 
          value: 0, // 不必过滤,0 就 0
          name: 'Search Engine',
          label:{
            show: 0? true:false, // 通过管制 show
            color: 'skyblue'
          },
          labelLine:{
            show: 0? true:false, // 同上
            length: 30,
            lineStyle:{color: 'red'}
          }
          
        }]
}],

(11) 图表的 resize 设置
个别窗口变动的时候,你按 F12 拖动窗口,这个时候如果图表没有设置这个 resize,图表会飘
window 监听 resize 事件,最初一个参数示意要捕捉 true 还是冒泡 false
我原本认为设置同个 resize 会笼罩掉后面那个,其实不会

mounted(){window.addEventListener('resize', this._resizeEventHandler, false)
}
methods:{_resizeEventHandler() {
      // 这里加多个判断,容错
      if (this.myChart) {
        // 这个节流,我是比拟偏向用防抖,这个是我拷贝其余我的项目的做法
        // 外围,this.myChart.resize(), 实例自带的办法,调用一下就行
        this.$common.throttle(this.myChart.resize(), 300)
      }
    },
}
beforeDestroy() {if (this.myChart) {this.myChart.dispose() // 图表实例销毁
    }
    window.removeEventListener('resize', this._resizeEventHandler, false) // 事件移除
  }

element 篇

表格固定第一行

官网的例子是固定最初一行,如何把这一行放到第一行显示呢

.hotList /deep/ .el-table {
  display: flex;
  flex-direction: column;
}
.hotList /deep/ .el-table__body-wrapper {order: 1;}

表格设置自适应

设置 width 为 auto, 你也能够给某一列,比方第一列设死宽度,

<el-table :data="top10Article.tableData" border>
          <el-table-column
            align="center"
            show-overflow-tooltip
            label-class-name="el-th"
            v-for="item in top10Article.colum"
            :key="item.prop"
            :prop="item.prop"
            :width="item.width" // 这个配置
            :label="item.label"
          />
        </el-table>


var TableWidth = "auto";
              if (item === "帖子") {TableWidth = "740";}
              colum.push({
                label: item,
                width: TableWidth,
                prop: item,
              });

Vue 篇

vue 指令

我写了一个简略的图片替换的,就是如果 src 空或者加载失败,就替换默认图
因为指令只能传一个参数,其余参数我不晓得怎么传,所以就用了 data- 这样传

应用
<img :src="item.pic" v-imgload="item.pic" data-imgloadfix='1'>

代码
let imgError = require('@/images/emptyImage.png')
// 局部图片替换须要一些额定的操作
function imgFixHandle(type,el){if(type == 1){
    el.style = 'width:60px;';
    el.parentNode.style = 'background:#eee;text-align:center;'
  }
}
export default {bind(el, binding) {
    let imgUrl = binding.value
    let imgFix = el.getAttribute('data-imgloadfix') 
    // let imgUrl = 'https://cxp-test.yili.com/resources/images/logo-default@2x.png'
    if(!imgUrl){el.setAttribute('src',imgError)

      // 额定操作
      setTimeout(() => {imgFixHandle(imgFix,el)
      },0)

      return 
    }
    let img = new Image()
    img.onload = function(){el.setAttribute('src',imgUrl)
      img = null
    }
    img.onerror = function(){el.setAttribute('src',imgError)

      // 额定操作
      imgFixHandle(imgFix,el)

      img = null
    }
    img.src = imgUrl
  }
}

我就用了一个钩子,其余没用到,只能百度先写下来
钩子 + 参数

bind(el,binding,vnode,oldVnode):首次绑定执行一次,负责初始化
inserted:          被绑定元素插入父节点时候调用,仅保障父节点存在,不肯定已被插入文档
update:            组件 VNode 更新时,可能在其子 VNode 更新前
componentUpdated:  组件 VNode 及其子 VNode 都更新后调用
unbind:            解绑时调用

el:绑定的元素
binding:   绑定对象,蕴含参数值,value 和 oldValue
vnode:     以后虚构节点
oldVnode:  上一个虚构节点,仅在 update 和 componentUpdate 钩子可用

区别
bind 和 inserted

共同点:dom 插入都会调用,bind 在 inserted 之前

不同点:bind 时父节点为 null
    inserted 时父节点存在。bind 是在 dom 树绘制前调用,inserted 在 dom 树绘制后调用

bind: function (el) {console.log(el.parentNode)  // null
    console.log('bind')
},
inserted: function (el) {console.log(el.parentNode)  // <div class="directive-box">...</div>
    console.log('inserted')
}

update 和 componentUpdated
跟 vue 组件的 up,bup 差不多

update(el, binding,vnode,oldVnode){console.log(el.innerHTML);       // <div>!</div>
}

componentUpdated(el, binding,vnode,oldVnode){console.log(el.innerHTML);       // //<div>!!</div>
}

proxytable 的粗浅意识

这个到我的文章,跨域那个看

v-modal 用法

这个是语法糖,有两局部,个别能够这样联想,v-model 是双向绑定,个别演示的时候都是用 input 的,input 的 value 值就是以后值,而后输出的时候,就是监听了 @input 办法,所以

<input type="text" v-model="text">
等同于
<input type="text" :value="text" @input="function(e){text = e.value}">

很多第三方 UI 库用 v -modal 都有用来作显示暗藏, 就是外层传一个 boolean,组件外面不必 emit 进去,让组件本人改这个值,大略这样

// 传一个 temFlag
<PartOne :filterParam="filterParam" v-model="temFlag"/>

// 组件
<div v-if="value"> 测试 v -</div>
// 抛出 input 事件,也是固定死的
<div @click="() => {this.$emit('input',false)}"> 敞开、关上 </div>
<div @click="() => {this.$emit('input',true)}"> 敞开、关上 </div>
    
props: {
    value: { // 肯定叫这个名字,固定死的
      type: Boolean,
      default: true
    },
    filterParam: {
      type: Object,
      default: () => {}
    }
  },

vue 打包的 assetsPublicPath 属性

这个属性是针对资源,也就是 css,img,js 这些资源的引入门路写法,
并且要跟,这个 dist 文件夹,在服务器目录的层级,保持一致,
比方 dist 文件扔在根目录,拜访 xxx.com/index.html
那么 assetsPublicPath 是 / 或者 ./ 都行 ,
如果放了几层目录,xxx.com/ra/ba/cd/index.html, 则这个属性就要变了,要一样
assetsPublicPath: ‘/ra/ba/cd/’

vue 数组用索引批改字符串,数组不失效

这个以前真没留神,数组用索引改是不失效的, 视图不会更新,看了一下如同是数组无奈用 object.defineproperty 劫持 set,get 办法

tem = [1,2,3]
this.tem[1] = 5 // 视图不会更新

vue 组件 style 的关系

style 加了 scoped 属性,会在所有 dom 下面加标识,比方,

data-v-101b773d 这个就是标识
<div data-v-101b773d=""> 数据哦 </div>

而后所有的款式也都是默认加这个

尽管写是这样写,.tem {color:skyblue}
然而编译后,浏览器看到的是这样
.tem[data-v-101b773d] {color:skyblue}

这就是为什么加了这个属性后,不会影响到这个组件外面套入的其余组件,因为其余组件的 dom 没有 data-v-101b773d 这个属性,就算其余组件也加了 scoped,它的 data-v-xxxxxx 也是不同的

而后,持续说一下,组件的 style 是怎么加载的
每个组件的 style 都是按需下载,并且是会插入 html 的 header 标签,不过有点不同,我发现 dev 的时候,是 style 模式插入,而 build 后,是 link 标签下载

我为什么说这个呢

因为我发现如果某个组件的 style 不加 scoped,而后加载的时候,header 标签插入,而后你其余组件的款式,就被它影响了!!

怎么防止
一般来说,不加 scoped 是为了让整个组件的款式都影响外部组件,或者是改 UI 库,比方 elm 的,

  1. 要么你就在类后面加个父类

    .fu .target {}
  2. 要么就不要去掉 scoped,用 /deep/,这个 /deep/ 编译后的原理其实是吧 data- v 放在最开始的类,前面的不会有

    .fu /deep/ .target {}
    
    // 编译后
    .fu[daa-v-xxxxx] .target {}

vue-cli3 打包去掉 consol

这个配置不必额定 install 依赖,自身你用脚手架 3 构建的 vue 我的项目曾经内置了
把这个插到 vue.config.js 就行了

// vue-cli3 内置 webpack 的 TerserPlugin,能够用来解决 js
  chainWebpack(config) {
    // 非开发环境,去掉 console
    config.when(process.env.NODE_ENV !== 'development', config => {config.optimization.minimizer('terser').tap(options => {options[0].terserOptions.compress.drop_console = true
        return options
      })
    })
  },

webpack 打包,锁版本,动态资源抽离进去,html 引入,不参加打包

补充篇

a 标签的下载文件

<a href="./static/cpgnkw.doc" style="cursor:pointer;color:blue;" download="产品概念口味包装测试标准化办法的补充阐明_F.doc">《“产品概念口味包装测试标准化办法”的补充阐明_F》</a>

下载的 href 门路肯定要英语,不能中文,download 写文件名加后缀

dist 缓存,hash 值更新

(1)F12 那里有个 DOC,能够看到以后页面是加载了哪个 html,而后看响应,看它资源 hash 值判断发版有没有失效;

(2)而且通过这个咱们能够发现,咱们本地 run dev,其实做的事件,跟 run build 一样,也是打包了,只是这个打包没有放进去,咱们看不到而已;

(3)ctrl+f5,强制清缓存,清不了 iframe 的,勾 disable cache 加 c +f5,能力革除

(4)打包关掉 sourcemap,体积会小很多

iframe

比方 A 域名嵌套 iframe,B 域名
(1)如果 B 域名跟 A 同域,也就是

A.html
<iframe src="/xxx/xxx/#/"> // 这个是 B 地址

如果是这样写,B 的域名会主动拼接 A 域名的,也就是 A 登陆后的 cookie,在 B 的外面申请的时候,也会主动携带上,在申请头外面,header.cookie: ‘xxxxx’
因为是同域名的申请;

(2)如果不同域名
不同域只能 cookie 拿,而后手动拼到申请头外面,作为 token

// 这个是拿全副的,所有 cookie 的挤在一起,要本人切割拼接
document.cookie

// 大略这个感觉
document.cookie.split(`; ${'_department'}=`)

(3)B 域名如何管制浏览器地址栏
目前遇到的,如果 B 域名携带的 token 过期了,要跳转 A 域名的登录

// window.parent.location.href = '/login'

node 切换

这是个好货色,很多我的项目可能要不同版本的 node 装置依赖能力跑起来,因为 npm 是追随 node 的,node 版本多少,npm 版本也多少,最近我的项目大部分都是 10.0.0 能力失常跑

前端 excel 导出

有插件实现

"dependencies": {"xlsx": "^0.16.5" // 这个},
  
代码
// excel 表格数据格式, 二维数组
            // [// ['题目名']
            // ['表头','表头','表头']
            // ['值','值','值']
            // ]
            // ws 是 sheet 对象,能够操作 sheet 合并单元格,设置单元格宽度等
            let ws = XLSX.utils.aoa_to_sheet(exportData)
            const wb = XLSX.utils.book_new()
            XLSX.utils.book_append_sheet(wb, ws, 'sheet')
            XLSX.writeFile(wb, '营销资源扫描图表数据' + '.xlsx')

html2canvas 纳闷

这个搁置了

申请头字段不辨别大小写

是的,不辨别,headers[‘token’]和 headers[‘TOKEN’]是一样的

对于工夫 new Date 用 - 原来默认是 8 点,只有用 / 才是失常的 0 点

new Date('2021-08-11')
Wed Aug 11 2021 08:00:00 GMT+0800 (中国规范工夫)

new Date('2021/08/11')
Wed Aug 11 2021 00:00:00 GMT+0800 (中国规范工夫)

axios 设置 content-type, 如果不传 data 设置没用

退出移动版