每日学习总结系列(六)

一、通过v-bind="$attrs"进行透传

有时我们需要对ui框架进行二次封装,例如,我们封装一个Input组件:

<!-- Input 组件 -->
<template>
  <div>
    <el-input v-model="myc"></el-input>
  </div>
</template>

我们需要保证外面能够直接设置el-input的属性,比如placeholder、clearable.

一般,我们可以直接使用外部传入的配置进行配置:

<template>
  <div>
    <el-input v-model="myc"
      :placeholder="configProps.placeholder"
      :clearable="configProps.clearable"></el-input>
  </div>
</template>

但这样感觉不够方便,而且不可能每个属性都写一次,那怎样可以做到更加灵活且方便的把所有参数都包含呢?

<template>
  <div>
    <el-input v-bind="$attrs" ></el-input>
  </div>
</template>

只需要使用v-bind="$attrs"就可以了, 完整的代码示例: v-bind=$attrs例子

二、字符串长度

一个没办法直接获取到长度的,可以这样去获取

const message = 'Hello!';
const smile = '😀';

[...message].length; // => 6
[...smile].length;   // => 1

三、css button hover 圆形效果

我感觉想法很新颖,他弄了个宽度200%的渐变背景,初始显示右边那一块,鼠标放上去显示左边这一块。
圆形效果

<div id="circle-btn">
  <div class="btn-container">
    // 这里有一个svg元素
    <button>Hover me</button>
  </div>
</div>
#circle-btn { 
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.btn-container {
  position: relative;  
}

button {
  border: 0;
  border-radius: 50px;
  color: white;
  background: #5f55af;
  padding: 15px 20px 16px 60px;
  text-transform: uppercase;
  background: linear-gradient(to right, #f72585 50%, #5f55af 50%);
  background-size: 200% 100%;
  background-position: right bottom;
  transition:all 2s ease;
}

svg {
  background: #f72585;
  padding: 8px;
  border-radius: 50%;
  position: absolute;
  left: 0;
  top: 0%;
}

button:hover {
   background-position: left bottom;
}

四、css button hover 边框效果

通过让动画延时达到看起来是一路画了一个边框的动画效果。

边框效果

<div id="draw-border">
  <button>Hover me</button>
</div>
#draw-border {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

button {
  border: 0;
  background: none;
  text-transform: uppercase;
  color: #4361ee;
  font-weight: bold;
  position: relative;
  outline: none;
  padding: 10px 20px;
  box-sizing: border-box;
}

button::before, button::after {
  box-sizing: inherit;
  position: absolute;
  content: '';
  border: 2px solid transparent;
  width: 0;
  height: 0;
}

button::after {
  bottom: 0;
  right: 0;
}

button::before {
  top: 0;
  left: 0;
}

button:hover::before, button:hover::after {
  width: 100%;
  height: 100%;
}

button:hover::before {
  border-top-color: #4361ee;
  border-right-color: #4361ee;
  transition: width 0.3s ease-out, height 0.3s ease-out 0.3s;
}

button:hover::after {
  border-bottom-color: #4361ee;
  border-left-color: #4361ee;
  transition: border-color 0s ease-out 0.6s, width 0.3s ease-out 0.6s, height 0.3s ease-out 1s;
}

五、前端生成excel

json格式数据导出

 let str = ''
  const jsonData = [{ '仓库代码': '', '货号': '', '尺码': '', '条码': '', '切货数量': '', '折扣': '' }]
  console.log(jsonData)
  for (var k in jsonData[0]) {
    str += k + ','
  }
  str = str.slice(0, str.length - 1) + '\n'
  console.log(str)
  // 增加\t为了不让表格显示科学计数法或者其他格式
  for (let i = 0; i < jsonData.length; i++) {
    for (const item in jsonData[i]) {
      str += `${jsonData[i][item] + '\t'},`
    }
    str += '\n'
  }
  // encodeURIComponent解决中文乱码
  const uri = 'data:application/vnd.ms-excel;charset=utf-8,\ufeff' + encodeURIComponent(str)
  // 通过创建a标签实现
  const link = document.createElement('a')
  link.href = uri
  // 对下载的文件命名
  link.download = '订单模板.xls'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)

利用第三方库导出

  • 安装file-saverxlsx

    • npm i file-saver xlsx -s
  • 在要用的组件用中引入

    •   import FileSaver from 'file-saver'
        import XLSX from 'xlsx' 
      
  • 给表格添加一个id

    •   <el-table
           id="table"
           :data="tableData"
           style="width: 100%">
           <el-table-column
             prop="date"
             label="日期"
             width="180">
           </el-table-column>
           <el-table-column
             prop="name"
             label="姓名"
             width="180">
           </el-table-column>
           <el-table-column
             prop="address"
             label="地址">
           </el-table-column>
         </el-table>
      
  • 导出方法

    •   getXlsx() {
           let wb = XLSX.utils.table_to_book(document.querySelector('#table'));
           /* #table 就是表格的id */
           let wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'});
           try {
               FileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), '导出数据.xlsx');
           } catch (e) {
               if (typeof console !== 'undefined'){
                   console.log(e, wbout)   
               }
           }
           return wbout
         }
      

后端返回二进制数据流,前端导出

我之前项目一般都是直接location.href=xxx就行了。
也可以用a标签下载, 将返回结果处理成一个新链接, 通过创建a标签打开, 但是有时候会产生乱码, 数据量太大也可能会导致网络失败,可以使用blob容器可以解决数据量大导致网络失败的问题, 乱码问题在二进制流前拼接字符串\ufeff即可.

 this.$axios({
      method: params.method,
      url: params.url,
      data: params.data,
      responseType: 'blob'  // 指明返回格式, 这里注明一下, 如果导出EXCEL为[object blob]的话, 可以把这段responseType:'blob' 注释掉试一下.  
    }).then(res => {
      console.log(res) // 返回结果
      // 这里尤其需要注意, '\ufeff' 用于解决乱码问题, blob可以解决数据量大导致网络失败.
      const blob = new Blob(['\ufeff' + res.data], { type: 'text/csv;charset=utf-8' })
      const url = window.URL.createObjectURL(blob)
      // 通过创建a标签实现
      const link = document.createElement('a')
      link.href = url
      // 对下载的文件命名, 如果后端返回名称出现乱码, 需要后端编码一下.
      link.download = decodeURI(res.headers['content-disposition'].split('=')[1]) || '发货单导出数据表.csv'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    })
posted @ 2020-08-31 19:14  来亦何哀  阅读(171)  评论(0编辑  收藏  举报