前端常用code归纳


任何一种艺术 不管是否重要 如果你想要在该领域出类拔萃 就必须全身心投入

前端常用code归纳

在这里插入图片描述





一、HTML





二、CSS


1. 样式绑定


1) . 三目运算符

“判断公式 ? “true 时执行” : “false 时执行””

        <a
          class="style1"
          :class="this.type == false ? 'style2' : ''"
        >

多目运算:

“判断公式 ? “true 时执行” : (“判断公式” ? true 时执行 : false 时执行)”

            <div
              class="noData"
              :style="
                (this.List != '' && this.tab == false) ?
                  'display:none' :
                  ((this.List != '' && this.tab == true) ? 'display:none' : '')
              "
            >
              <img src="@/images/noData.png" />
              <p>暂无数据</p>
            </div>


2.常用样式

1). 文本

①. 文字溢出
/* 文字溢出 */ 
.textOverflow {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  width: 230px;
}

/* 多行文本溢出 */
.intwolines{
  display: -webkit-box !important;
  overflow: hidden;

  word-break:break-all ;
  text-overflow: ellipsis;

  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;  
  /*  -webkit-line-clamp: num  想要几行展示都可设置 */
}


①. 滚动条
/* 滚动条 */
.tree-box::-webkit-scrollbar {
  width: 6px;
  overflow-y: scroll;
}
.tree-box::-webkit-scrollbar-thumb {
  border-radius: 6px;
  background: rgb(156, 156, 156);
}
.tree-box::-webkit-scrollbar-track {
  background: #cccbcb;
}

2).颜色

①. 渐变层
    position: absolute;
    z-index: 2;
    bottom: 0;
    height: 120rpx;
    width: 750rpx;
    opacity: 0.36;
    // 重点是这行
    background-image: linear-gradient(180deg, rgba(0,0,0,0.00) 0%, #000000 100%);

3). 背景

①. 透明
background-color: transparent;
  // border-color: rgba(255, 255, 255, 0.5);

②. 背景图
// css
background-image: url('');

// scss/sass
background: url(’~@/assets/images/jjg/buy/btn_bg@2x.png’) no-repeat center center;
/*background: url("img/2.jpg") 10% 20% no-repeat;!*图片从左往右移动的百分比大小,从上往下百分比大小,重复方式 换成数值同样如此,在这里没有调整大小的方法*!*/
background-position: 10% 40%;
/*这个是按从左往右,从上往下的百分比位置进行调整*/
background-size: 50% 50%;
/*按比例缩放*/
/*background-size: 100px 100px;!*这个是按数值缩放*!*/
background-repeat: no-repeat;
/*还有repeat-x,y等*/


3. CSS 函数

1). calc()函数

calc() 函数用于动态计算长度值。

// calc()函数支持 "+", "-", "*", "/" 运算
width: calc(100% - 100px)



三、JS


1. ES



2. DOM

1) . setTimeout()

setTimeout(要执行的代码, 等待的毫秒数)
setTimeout(JavaScript 函数, 等待的毫秒数)

实例:

    closeRulerTip() { // 关闭提示弹窗
      this.isRulerTip = true
      setTimeout(() => { this.isRulerTip = false }, 2000)
    },

① . 防抖
    judgeEvent(data) { // 防抖
      if (this.timeout) {
        clearTimeout(this.timeout)
      }
      this.timeout = setTimeout(() => {
        this.getData(data)
      }, 600);
    },

2) . setInterval()

可按照指定的周期(以毫秒计)来调用函数或计算表达式

示例:

setInterval('alert("Hello");', 3000)

3) . setInterval()

取消由 setInterval() 函数设定的定时执行操作

setInterval("javascript 函数", milliseconds)

4) . getElementById()

①. 修改classname
	  // 获取对象 id
      let val = document.getElementById("id").className
      if (val == "name1") {
        document.getElementById("id").className = "name2"
      } else {
        document.getElementById("id").className = "name1"
      }

5) . 实例

// 轮询及关闭
methods: {
        getInterval() {
            this.setInt = setInterval(() => { this.getSchemeDetails(this.appSchemeId) }, 5000)
        },
        clearInterval() {
            clearInterval(this.setInt)
        },
}


3. BOM



4. Math()

Math 对象允许您执行数学任务
Math 不是构造函数。Math 的所有属性/方法都可以通过使用 Math 作为对象来调用,而无需创建它


⑴. 方法(部分)

方法描述
abs(x)返回 x 的绝对值
ceil(x)返回 x,向上舍入为最接近的整数
floor(x)返回 x,向下舍入为最接近的整数
max(x, y, z, …, n)返回值最高的数字
min(x, y, z, …, n)返回值最小的数字
pow(x, y)返回 x 的 y 次幂值
random()返回 0 到 1 之间的随机数
round(x)将 x 舍入为最接近的整数
trunc(x)返回数的双曲正切值

⑵. 实例

打乱一个数组的顺序(遍历)

		let arr = [1, 2, 3, 4]
        let newArr = []
        for (let i = 0; i < arr.length; i++) {
            let index = Math.floor(Math.random() * 4)
            newArr.splice(index, 0, arr[i])
        }
        console.log(newArr)





四、ES6 及 新特性


1. 同步异步

1) . async 函数

async 是 ES7 才有的与异步操作有关的关键字,和 Promise , Generator 有很大关联的。

// 语法
async function name([param[, param[, ... param]]]) { statements }
// name: 函数名称。
// param: 要传递给函数的参数的名称。
// statements: 函数体语句。

返回值:

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。

async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

function testAwait(){
   return new Promise((resolve) => {
       setTimeout(function(){
          console.log("testAwait");
          resolve();
       }, 1000);
   });
}
 
async function helloAsync(){
   await testAwait();
   console.log("helloAsync");
 }
helloAsync();
// testAwait
// helloAsync

2) . then 函数

then()方法用于指定当前实例状态发生改变时的回调函数。它返回一个新的Promise实例。

// 语法
Promise.prototype.then(onFulfilled, onRejected);
// onFulfilled: 当前实例变成fulfilled状态时,该参数作为回调函数被调用(承诺完成时执行)。
// onRejected: 当前实例变成reject状态时,该参数作为回调函数被调用(承诺被拒绝时执行)。

2. 语法

1) . set

方法说明
add添加值,返回Set本身
delete删除值,返回是否删除成功
has判断是否拥有这个值,返回true/false
clear清除所有值

示例:

let s = new Set();
s.add(4);
s.add(1);
s.add(3);
s.add(3);
s.add(2);
s.add(2);
console.log(s); // {4, 1, 3, 2}
console.log(s.has(4)); // true
s.delete(4);
console.log(s); // {1, 3, 2}
console.log(s.has(4)); // false
s.clear();

set 去重:

let arr = [4, 1, 3, 3, 2, '2'];
let uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [4, 1, 3, 2, "2"]




五、工程化


1. Git






六、框架


1. Vue

1).


2). 传值

①. 组件传值

父子组件/兄弟组件 传值

②. 本地缓存
㈠ . Window localStorage 属性
// 存储
localStorage.setItem("lastname", "Smith");
// 检索
document.getElementById("result").innerHTML = localStorage.getItem("lastname");

localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。`

window.localStorage
// 保存数据语法:
localStorage.setItem("key", "value");
// 读取数据语法:
var lastname = localStorage.getItem("key");
// 删除数据语法:
localStorage.removeItem("key");

㈡ . Window sessionStorage 属性
// 存储
sessionStorage.setItem("lastname", "Smith");
// 检索
document.getElementById("result").innerHTML = sessionStorage.getItem("lastname");

sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

window.sessionStorage
// 保存数据语法:
sessionStorage.setItem("key", "value");
// 读取数据语法:
var lastname = sessionStorage.getItem("key");
// 删除指定键的数据语法:
sessionStorage.removeItem("key");
// 删除所有数据:
sessionStorage.clear();

③. 监听
㈠. watch
  watch: {
    'selectState': { // 监听 搜索/下拉 状态
      handler(val, oldVal) {
        if (val == 1) {
          this.request.state = ''
        } else if (val == 2) {
          this.request.state = 0
        } else {
          this.request.state = 1
        }
      },
      immediate: true
    },
 }

④. 路由传参

组件中 获取参数的时候是route.params 而不是router

㈠. path

页面刷新数据不会丢失

methods:{
  insurance(id) {
       //直接调用$router.push 实现携带参数的跳转
        this.$router.push({
          path: `/particulars/${id}`,
        })
}

配置对应路由:

// 在path中添加/:id来对应 $router.push 中path携带的参数
{
     path: '/particulars/:id',
     name: 'particulars',
     component: particulars
}

在子组件中可以使用来获取传递的参数值, 另外页面获取参数如下:

this.$route.params.id

㈡. params

页面刷新数据会丢失

// 通过路由属性中的name来确定匹配的路由,通过params来传递参数。
methods:{
  insurance(id) {
       this.$router.push({
          name: 'particulars',
          params: {
            id: id
          }
        })
  }

配置对应路由:

// 这里不能使用:/id来传递参数了,因为组件中,已经使用params来携带参数了
 {
     path: '/particulars',
     name: 'particulars',
     component: particulars
   }

子组件中: 这样来获取参数:

this.$route.params.id

㈢. params

使用path来匹配路由,然后通过query来传递参数

// 这种情况下 query传递的参数会显示在url后面?id=?
methods:{
  insurance(id) {
        this.$router.push({
          path: '/particulars',
          query: {
            id: id
          }
        })
  }

配置对应路由:

{
     path: '/particulars',
     name: 'particulars',
     component: particulars
   }

子组件中: 这样来获取参数:

this.$route.query.id


3). 插件

①. 滚动懒加载
<ul v-infinite-scroll="loadMore">
	<li></li>
	...
	<li></li>
</ul>
 
    // 无线滚动 懒加载
    loadMore() {
      this.page ++
      this.getFileList()
    },

4) .实例方法

①. vm.$forceUpdate()

迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。





七、数据结构


1. 数据类型


1) . 数组转字符串

①. JSON.stringify()

JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。

// 语法:
JSON.stringify(value[, replacer[, space]])

// value:
// 必需, 要转换的 JavaScript 值(通常为对象或数组)。

// replacer:
// 可选。用于转换结果的函数或数组。

// space:
// 可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。

实例:

	// {a, b, c, ...} => {"a", "b", "c", ...}
	name: String(this.groupName),
	// ["name: a, level: 1", "name: n, level: 0", "name: d, level: 2", ... } => [{name: a, level: 1}, {name: n, level: 0}, {name: d, level: 2}, ... }
    userIDList: JSON.stringify(this.userIDList)

2) . 字符串转对象

①. JSON.parse()

JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

// 语法:
JSON.parse(text[, reviver])

// text:
// 必需, 一个有效的 JSON 字符串。

// reviver: 
// 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。

3) . 字符串转数组

①. map()
        let newArr = str.map(item => {
          return { name: item, imgURL: '' }
        })

4) . 对象转数组

①. push()
      let obj = { name: 'jack', age: 12 }
      let arr = []
      // console.log(arr.push(obj))
      // => 1

      arr.push(obj)
      console.log(arr)
      // => Array [ {…} ]

2. 数据结构

1) . 字符串


①. split() 方法

split() 方法用于把一个字符串分割成字符串数组。
stringObject. split(" 指定切割参数","返回数据的最大长度(可选) ")[ 返回切割的第几个值(可选) ]

实例:

var str="How are you doing today?"

document.write(str.split(" ") + "<br />")
// => How,are,you,doing,today?
document.write(str.split("") + "<br />")
// => H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?
document.write(str.split(" ",3))
// => How,are,you

②. replace() 方法

replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

// 语法
stringObject.replace(regexp/substr,replacement)

// regexp/substr:
// 必需。规定子字符串或要替换的模式的 RegExp 对象。

// replacement
// 必需。一个字符串值。规定了替换文本或生成替换文本的函数。

③. parseInt() 函数

只有字符串中的第一段数字会被返回。
开头和结尾的空格是允许的。
如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。
在字符串以"0"为开始时旧的浏览器默认使用八进制基数。ECMAScript 5,默认的是十进制的基数。

// 语法
parseInt(string, radix)
// string	必需。要被解析的字符串。
// radix	可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

// 当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
// 当忽略参数 radix , JavaScript 默认数字的基数如下:
// 如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
// 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
// 如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

实例
// 全局替换
document.write(str.replace(/Microsoft/g, "W3School"))
// 去掉特殊字符(正则)
document.write(str.replace(/["|’|\[|\]|\“|\”|\,]/g, ""))
// 所有单词的首字母都转换为大写:
name = 'aaa bbb ccc';
uw=name.replace(/\b\w+\b/g, function(word){
  return word.substring(0,1).toUpperCase()+word.substring(1)
})

// 字符串去重
let Arr1 = str.split(',') // 切割成数组
let Arr2 = Arr.toString().replace(/[^0-9]/ig,"") // 去掉多余字符
let str = Arr2.filter(item => !Arr1.some(ele => ele.id == item.id)) // 数组去重

2) . 数组


①. slice() 方法

slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

// 语法:
stringObject.slice(start,end)

// start:
// 要抽取的片断的起始下标。
// end
// 紧接着要抽取的片段的结尾的下标。

②. filter() 方法

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

// 语法:
array.filter(function(currentValue,index,arr), thisValue)

// function(currentValue, index,arr)
// 必须。函数,数组中的每个元素都会执行这个函数
// currentValue: 必须。当前元素的值
// index: 可选。当前元素的索引值
// arr: 可选。当前元素属于的数组对象
// thisValue
// 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。

③. concat() 方法

concat() 方法用于连接两个或多个数组。

// 语法:
array1.concat(array2, array3, ..., arrayX)

// array2, array3, ..., arrayX
// 必需。要连接的数组。

④. find() 方法

find() 方法返回数组中第一个通过测试的元素的值(作为函数提供)。

// 语法:
array.find(function(currentValue, index, arr), thisValue)

// 参数同上

⑤. forEach() 方法

forEach() 方法按顺序为数组中的每个元素调用一次函数。

// 语法:
array.forEach(function(currentValue, index, arr), thisValue)

// 参数同上

⑥.join() 方法

join() 方法将数组作为字符串返回。

// 语法:
array.join(separator)

// separator
// 可选。要使用的分隔符。如果省略,元素用逗号分隔。


⑦. map() 方法

map() 方法使用为每个数组元素调用函数的结果创建新数组。

// 语法:
array.map(function(currentValue, index, arr), thisValue)

// 参数同上

⑧. push() 方法

push() 方法向数组末尾添加新项目,并返回新长度。

// 语法:
array.push(item1, item2, ..., itemX)

// item1, item2, ..., itemX
// 必需。要添加到数组中的项目。

⑨. reduce() 方法

reduce() 方法将数组缩减为单个值。

// 语法:
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

// 参数同上

⑩. slice() 方法

slice() 方法以新的数组对象,返回数组中被选中的元素。

// 语法:
array.slice(start, end)

// start
// 可选。整数,指定从哪里开始选择(第一个元素的索引为 0)。
// end
// 可选。整数,指定结束选择的位置。

①. some() 方法

some() 方法检查数组中的任何元素是否通过测试(作为函数提供)。

// 语法:
array.some(function(currentValue, index, arr), thisValue)

// 参数同上

②. splice() 方法

splice() 方法向/从数组添加/删除项目,并返回删除的项目。

// 语法:
array.splice(index, howmany, item1, ....., itemX)

// index
// 必需。整数,指定在什么位置添加/删除项目,使用负值指定从数组末尾开始的位置。
// howmany
// 可选。要删除的项目数。如果设置为 0,则不会删除任何项目。
// item1, ..., itemX
// 可选。要添加到数组中的新项目。

③. toString() 方法

toString() 方法返回包含所有数组值的字符串,以逗号分隔。

// 语法:
array.toString()

④. replace() 方法

replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

// 语法:
string.replace(searchvalue,newvalue)

// 实例:
var str="Visit Microsoft! Visit Microsoft!";
var n=str.replace("Microsoft","Runoob");

// 全局替换:
var str="Mr Blue has a blue house and a blue car";
var n=str.replace(/blue/g,"red");
// => Mr Blue has a red house and a red car

⑤. replaceAll() 方法

replaceAll() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,该函数会替换所有匹配到的子字符串。

// 语法:
const newStr = str.replaceAll(regexp|substr, newSubstr|function)

// 实例:
var str="Visit Microsoft! Visit Microsoft!";
var n=str.replaceAll("Microsoft","Runoob");

// 全局替换:
var str="Mr Blue has a blue house and a blue car";
var n=str.replaceAll(/blue/ig,"red");
// => Mr red has a red house and a red car.

综合实例:

土豆示例数据筛查

实例
// 两个数组过滤相同数据
let newArr = Arr1.filter(item1 => !Arr2.some(ele1 => ele1.itemID === item1.itemID))

// 一个输入加入另一个数组, 去掉相同项
let fileMixed = Arr1.concat(Arr2)
let fileUnion = fileMixed.filter(item1 => !Arr1.some(ele1 => ele1.itemID == item1.itemID))
let newArr = Arr1.concat(fileUnion)

// 删除数组中的属性
let Data = Arr.filter(item => delete item.id)

// 提取文件名(去掉文件后缀)
let tex = _this.localFileName
let pattern = /\.{1}[a-z]{1,}$/
result.modelName = tex.slice(0, pattern.exec(tex).index)

// 数组中的一个属性遍历出来
let idList = this.memberList.map((x) => {
   return x.userID
});
this.idList = idList

// 数组格式 {1026213, 1025521, 1256987, ...} =>
// JSON格式[{userID:1026213 , level:0}, {userID:1026213 , level:0}, {userID:1026213 , level:0}, ...]
this.groupOutsiderArray = this.groupOutsiderArray.map(item => {
	return {userID: item, level: 0}
})

// 过滤数组中相同id 的项
// list: 【{id:1,name:zoe}, {id: 2,name: bom}, {id: 2, name: aim}...】
let newList = list.filter((element, index, self) => {
     return self.findIndex(el => el.id === element.id) === index
})

3) . 数值

①. 保留两位小数

四舍五入

// 四舍五入
let num =2.446242342
num = num.toFixed(2)
// 2.45

// 不四舍五入
先把小数边整数:
Math.floor(15.7784514000 * 100) / 100
// 15.77

//当作字符串,使用正则匹配:
Number(15.7784514000.toString().match(/^\d+(?:\.\d{0,2})?/))
// 15.77,不能用于整数如 10 必须写为10.0000

实例 - 四舍五入保留两位小数:

//四舍五入保留2位小数(若第二位小数为0,则保留一位小数)
function keepTwoDecimal(num) {
 var result = parseFloat(num);
 if (isNaN(result)) {
 alert('传递参数错误,请检查!');
 return false;
 }
 result = Math.round(num * 100) / 100;
 return result;
}
//四舍五入保留2位小数(不够位数,则用0替补)
function keepTwoDecimalFull(num) {
 var result = parseFloat(num);
 if (isNaN(result)) {
 alert('传递参数错误,请检查!');
 return false;
 }
 result = Math.round(num * 100) / 100;
 var s_x = result.toString();
 var pos_decimal = s_x.indexOf('.');
 if (pos_decimal < 0) {
 pos_decimal = s_x.length;
 s_x += '.';
 }
 while (s_x.length <= pos_decimal + 2) {
 s_x += '0';
 }
 return s_x;
}

取后两位 :

// 丢弃小数部分,保留整数部分
parseInt(5/2)

// 向上取整,有小数就整数部分加1
Math.ceil(5/2)

// 四舍五入
Math.round(5/2)

// 向下取整
Math.floor(5/2)

另类方法 :

// 笨方法
function get()
{
 var s = 22.127456 + "";
 var str = s.substring(0,s.indexOf(".") + 3);
 alert(str);
}

// 正则
onload = function(){
 var a = "23.456322";
 var aNew;
 var re = /([0-9]+.[0-9]{2})[0-9]*/;
 aNew = a.replace(re,"$1");
 alert(aNew);
}

// 聪明方法
var num=22.127456;
alert( Math.round(num*100)/100);

// 自动补充零
function returnFloat(value){
 var value=Math.round(parseFloat(value)*100)/100;
 var xsd=value.toString().split(".");
 if(xsd.length==1){
 value=value.toString()+".00";
 return value;
 }
 if(xsd.length>1){
 if(xsd[1].length<2){
 value=value.toString()+"0";
 }
 return value;
 }
}

4) . 正则

①. 去掉非数字字符
 let s ="价格4500元,等级:2"
 let num = s.replace(/[^0-9]/ig,"")
 console.log(num) //45002




3. 特殊数据获取

1). 日期

var myDate = new Date()

语法
myDate.getYear()获取当前年份(2位)
myDate.getFullYear()获取完整的年份(4位,1970-???)
myDate.getMonth()获取当前月份(0-11,0代表1月)
myDate.getDate()获取当前日(1-31)
myDate.getDay()获取当前星期X(0-6,0代表星期天)
myDate.getTime()获取当前时间(从1970.1.1开始的毫秒数)
myDate.getHours()获取当前小时数(0-23)
myDate.getMinutes()获取当前分钟数(0-59)
myDate.getSeconds()获取当前秒数(0-59)
myDate.getMilliseconds()获取当前毫秒数(0-999)
myDate.toLocaleDateString()获取当前日期
var mytime=myDate.toLocaleTimeString()获取当前时间
myDate.toLocaleString()获取日期与时间

获取第n天的日期

    // 获取第n天的日期
    fun_date(num) { 
      let today = new Date()
      let time1 = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate()
      console.log("time1 =>", time1)
      let beforeDay = new Date(today)
      beforeDay.setDate(today.getDate() + num)
      //num是正数表示之后的时间,num负数表示之前的时间,0表示今天
      let time2 = beforeDay.getFullYear() + "-" + (beforeDay.getMonth() + 1) + "-" + beforeDay.getDate();
      return time2
    },
	// 获取100年后日期
	get_data() {}
	    var date1 = new Date()
        let time3 = (date1.getFullYear() + 100) + "-" + (date1.getMonth() + 1) + "-" + date1.getDate()
        console.log("time3=>", time3)
    }
    // !!获取第n月的日期... 会出现跨年问题(待解决)

获取指定日期是周几

function fun_week(datestr){
    var weekArray = new Array("周日", "周一", "周二", "周三", "周四", "周五", "周六");
    var week = weekArray[new Date(datestr).getDay()];
    console.log(week);
    return week;
}
 fun_week('2019-6-28') //周五

获取近一个月时间

var end = new Date();
var year = end.getFullYear();
var month = end.getMonth() + 1;//0-11表示1-12月
var day = end.getDate();
var dateObj = {};
dateObj.end = year + '-' + month + '-' + day;
var endMonthDay = new Date(year, month, 0).getDate();    //当前月的总天数
if(month - 1 <= 0){ //如果是1月,年数往前推一年<br>    
    dateObj.start = (year - 1) + '-' + 12 + '-' + day;
}else{
    var startMonthDay = new Date(year, (parseInt(month) - 1), 0).getDate();
    if(startMonthDay < day){    //1个月前所在月的总天数小于现在的天日期
        if(day < endMonthDay){        //当前天日期小于当前月总天数
            dateObj.start = year + '-' + (month - 1) + '-' + (startMonthDay - (endMonthDay - day));
        }else{
            dateObj.start = year + '-' + (month - 1) + '-' + startMonthDay;
        }
    }else{
        dateObj.start = year + '-' + (month - 1) + '-' + day;
    }
}
console.log(JSON.stringify(dateObj))
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.

日期转换成毫秒值

    var startDate ='2018-07-09 14:13:11';
    startDate= startDate.replace(new RegExp("-","gm"),"/");
    var startDateM = (new Date(startDate)).getTime(); //得到毫秒数

4. 实例

1). 数组

// 两个数组 去重
let newArr = arr1.filter(item => !arr2.some(ele => ele.id === item.id))

// 删除数组中的属性
let newArr = arr.filter(item => delete item.itemId)

5. 接口请求

    async submit () {
      this.getUserIdList()
      try {
        // 接口请求
        const { data } = await this.$http.teamGroup.RemoveUser({
          itemCode: String(this.itemCode),
          userIDList: String(this.userIDList)
        })
        if (data.status.code != 1) {
          console.log('%c 🥐 移出成员接口错误: ', 'font-size:20px;background-color: #E41A6A;color:#fff;', data.message)
          this.checkMemberList = []
          this.isRemove = false
          this.$message({
            type: 'info',
            message: '移出成员失败, 请联系管理员'
          })
        } else {
          this.checkMemberList = []
          this.isRemove = false
          this.$message({
            type: 'success',
            message: '已成功移出成员'
          })
        }
      } catch (error) {
        console.log('%c 🥐 移出成员失败: ', 'font-size:20px;background-color: #E41A6A;color:#fff;', error)
        this.checkMemberList = []
        this.isRemove = false
        this.$message({
          type: 'info',
          message: '移出成员失败, 请刷新后重试'
        })
      }
    },




八、浏览器


1. 监听


1). 监听鼠标滚动

  mounted() {
	// 监听鼠标滚动
    window.addEventListener('mousewheel', this.handleScroll, false)
    // firefox
    window.addEventListener("DOMMouseScroll", this.handleScroll, false)
  },
  methods: {
    handleScroll(e) { // 获取鼠标滚动 隐藏右侧版本下拉框
      console.log('%c 🍻 e: ', 'font-size:20px;background-color: #E41A6A;color:#fff;', e);
      if (this.timerScroll) {
        return
      }
      this.timerScroll = true
      this.$refs['multiSelect' + item.fileName][0].blur() // 隐藏弹窗 失去焦点
      setTimeout(() => { this.timerScroll = false }, 1000)
    },

1). 监听键盘回车

// 回车检索
@keyup.enter="searchEnter"

2. DOM


1). Document.title

title 属性可返回当前文档的标题( HTML title 元素中的文本)。

alert(document.title); // 显示 "Hello World!"
document.title = "Goodbye World!";
alert(document.title); // 显示 "Goodbye World!"

3. Browser


1). Window open() 方法

open() 方法用于打开一个新的浏览器窗口或查找一个已命名的窗口。

// 语法
window.open(URL,name,specs,replace)
// URL
// 可选。打开指定的页面的URL。如果没有指定URL,打开一个新的空白窗口
// name
// 可选。指定target属性或窗口的名称。支持以下值:
// specs
// 可选。一个逗号分隔的项目列表。支持以下值:
// replace
// Optional.Specifies规定了装载到窗口的 URL 是在窗口的浏览历史中创建一个新条目,还是替换浏览历史中的当前条目。支持下面的值:

4. 滚动条

1). 置顶 / 置底


<div class="middle"></div>

// methods
toEnd(){//滚动到底部
    this.$nextTick(() => {
      let middle= this.$refs["middle"]
      middle.scrollTop = middle.scrollHeight
   })
}

toTop() {
	setTimeout(() => {
      window.scrollTo(0, 0)
    })
}






九、插件


1. lodash

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

// npm 安装
$ npm i --save lodash

// 引用
import * as _ from "lodash"

1). 深拷贝

var objects = [{ 'a': 1 }, { 'b': 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false


2. dayjs

Day.js是一个极简的JavaScript库,可以为现代浏览器解析、验证、操作和显示日期和时间。

// 安装
npm install dayjs --save

// 项目使用
var dayjs = require('dayjs')
//import dayjs from 'dayjs' // ES 2015
dayjs().format()

3. 富文本编辑器

⑴. Vue-Quill-Editor

// 下载
npm install vue-quill-editor -S
// 安装依赖
npm install quill -S

4. 其他

1). 复制文字

<p class="name">
    {{ item.name }}
<!-- <i class="ico-copy" title="复制" @click="copyName(item)" /> -->
</p>
<!-- 辅助 复制按钮使用 -->
<input id="input" v-model="item.name" type="text" style="height: 0; background: #000;">
copyName(item) { // 复制应用标题(已被废弃,但是我舍不得删)
   let e = document.querySelector('#input')
   e.value = item.name
   e.select()
   document.execCommand('copy')
   this.$message.closeAll()
   this.$message.success('复制应用标题成功')
},




十、Node






十一、泛客户端






十二、组件


1. elementUI


1). DatePicker 日期选择器

①. 禁用今天之前的日期
           <el-date-picker
            v-model="examine.date"
            type="date"
            placeholder="选择日期"
            size="small"
            style="margin-top: 10px;"
            :disabled="this.forverTime == 1"
            value-format="yyyy-MM-dd"
            :picker-options="pickerOptions"
          ></el-date-picker>
  data() {
    return {
      // 禁用当前之前的日期
      pickerOptions: {
        disabledDate: (time) => {
          return time.getTime() < Date.now() - 8.64e7
        }
      },
    }
  }

②. 动态禁用日期(两个日期选择器互相限制)

在这里插入图片描述

选择完生效日期后,失效日期的时间的日期选择会被限制

		  <!-- 表单 -->
          <el-form-item label="生效日期" prop="startTime">
            <el-date-picker
              v-model="lineData.startTime"
              align="right"
              type="date"
              placeholder="请选择生效日期"
              value-format="yyyy-MM-dd"
              :picker-options="pickerOptionStartTime"
            ></el-date-picker>
          </el-form-item>
          <el-form-item label="失效日期" prop="endTime">
            <el-date-picker
              v-model="lineData.endTime"
              align="right"
              type="date"
              placeholder="请选择失效日期"
              value-format="yyyy-MM-dd"
              :picker-options="pickerOptionEndTime"
            ></el-date-picker>
          </el-form-item>
  computed: {
    pickerOptionEndTime() {
      // 校验失效日期
      let _this = this;
      return {
        disabledDate(time) {
          return time.getTime() < new Date(_this.lineData.startTime).getTime();
        },
      };
    },
    pickerOptionStartTime() {
      // 校验生效日期
      let _this = this;
      return {
        disabledDate(time) {
          return time.getTime() > new Date(_this.lineData.endTime).getTime();
        },
      };
    },
  },


2). pagenation 分页器

①. 调用
          <!-- 分页器 -->
          <div v-show="this.paginaton.total >= this.paginaton.pageSize" class="paginaton">
            <el-pagination
              :current-page="this.paginaton.page"
              background
              prev-text=" 上一页 "
              next-text=" 下一页 "
              :page-size="this.paginaton.pageSize"
              :page-sizes="[15, 30, 60]"
              layout="sizes, prev, pager, next, total, jumper"
              :total="this.paginaton.total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
            <div class="next-button" @size-change="handleCurrentChange">确定</div>
          </div>

			// methods
		    handleCurrentChange(val) { // 翻页 当前页
		      this.paginaton.page = val
		      this.request.page = this.paginaton.page
		      this.judgeRequest()
		    },
		    handleSizeChange(val) { // 翻页 每页条数
		      this.paginaton.page = 1
		      this.request.page = this.paginaton.page
		      this.paginaton.pageSize = val
		      this.request.pageSize = this.paginaton.pageSize
		      this.judgeRequest()
		    },

②. 分页逻辑(获取全部数据分页)
    getPage() { // 分页
      this.pagination.total = this.memberList.length
      if (this.pagination.currentPage > 1 && this.pagination.total <= (this.pagination.currentPage - 1) * 10) {
        this.pagination.currentPage--
      }
      this.showMeberList = this.memberList.slice((this.pagination.currentPage - 1) * 10, this.pagination.currentPage * 10)
    },

③. 样式
/* 分页器 */
.paginaton {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}
.paginaton >>> .el-pagination span {
  padding: 0 10px;
}
.next-button {
  display: inline-block;
  padding: 0 10px;
  height: 30px;
  line-height: 30px;
  font-size: 14px;
  color: #fff;
  border: 0;
  background: #3564f9;
  border-radius: 3px;
  cursor: pointer;
  outline: none;
  margin-left: 10px;
}

// 位置调整
.paginaton >>> .el-pagination span {
  padding: 0 10px;
}
.tc-box.add-person-tc .el-pagination {
  padding-top: 0;
}
.paginaton >>> .el-pagination__jump {
  margin-left: 0;
}
.paginaton >>> .el-pagination__total {
  margin-right: 0;
}


3). el-table

		  <!-- tree 表格树形结构 -->
          <!-- default-expand-all -->
          <el-table
            v-if="!tab"
            :data="distributeList"
            style="width: 100%; margin-bottom: 20px;"
            row-key="id"
            height="calc(106vh - 240px)"
            :row-style="{ height: '62px' }"
            :tree-props="{ children: 'childs', hasChildren: 'hasChildren' }"
            :header-cell-style="{ height: '36px', background: '#eff4f9', color: '#7d7e8a' }"
          >
            <el-table-column prop="name" label="文件名称" min-width="230">
              <template slot-scope="scope">
                <img
                  v-if="scope.row.isFolder == '1'"
                  class="fileType-icon"
                  src="@/images/ico-fileFolder.png"
                  alt
                />
                <img v-else class="fileType-icon" src="@/images/ico-file.png" />
                <span
                  class="fileType-span"
                  v-if="scope.row.isFolder == '1' && (scope.row.receiveState != 0 || tab != true)"
                >{{ scope.row.name }}</span>
                <span
                  class="fileType-span"
                  v-if="scope.row.isFolder != 1 || (scope.row.receiveState == 0 && tab == true)"
                  @click="toPreview(scope.row)"
                >{{ scope.row.name }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="version" label="版本" min-width="100">
              <template slot-scope="scope">
                <span v-show="scope.row.isFolder != 1">V{{ scope.row.version }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="extension" label="格式" min-width="100" />
            <el-table-column prop="receiveState" label="派发状态" min-width="100">
              <template slot-scope="scope">
                <span v-show="scope.row.isFolder != 1 && scope.row.receiveState == 0">未回收</span>
                <span v-show="scope.row.isFolder != 1 && scope.row.receiveState == 1">已回收</span>
              </template>
            </el-table-column>
            <el-table-column prop="viewState" label="查看状态" min-width="100">
              <template slot-scope="scope">
                <img
                  @click="showCheck(scope.row)"
                  v-show="scope.row.isFolder != 1"
                  class="viewState-icon"
                  src="@/images/drawHand-ViewStatus-1.png"
                  alt
                />
                <span
                  @click="showCheck(scope.row)"
                  v-show="scope.row.isFolder != 1"
                  class="viewState-span"
                >{{ scope.row.viewState }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="派发日期" min-width="180">
              <template slot-scope="scope">
                <span>{{ scope.row.createTime }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="recycleTime" label="回收日期" min-width="180" />
            <el-table-column label="操作" min-width="180">
              <template slot-scope="scope">
                <span
                  v-if="scope.row.isFolder != 1 || (scope.row.receiveState == 0 && tab == true)"
                  class="font-blue"
                  style="cursor: pointer;"
                  @click="toPreview(scope.row)"
                >预览</span>
                <span
                  v-if="!tab && scope.row.receiveState == 0"
                  class="font-blue pl20"
                  style="cursor: pointer;"
                  @click="showRecycle(scope.row)"
                >回收</span>
              </template>
            </el-table-column>
          </el-table>
/* 不能使用 scoped 部分 */
/* 表格 */
.drawHand-file .el-table thead .el-table__cell {
  padding: 0;
  /* min-width: 0;
  box-sizing: border-box;
  text-overflow: ellipsis;
  vertical-align: middle;
  position: relative;
  text-align: left; */
}
.drawHand-file .el-table thead .el-table__cell:first-child {
  padding-left: 15px;
}

/* .el-table 自定义展开图标 */
/*1.取消原本展开的旋转动效*/
/deep/.el-table__expand-icon {
  -webkit-transform: rotate(0deg);
  transform: rotate(0deg);
}
/*2.展开按钮未点击的样式是加号带边框*/
/deep/.el-table__expand-icon .el-icon-arrow-right:before {
  content: "\e6d9";
  border: 1px solid #ccc;
  padding: 1px;
}
/*2.按钮已点击展开之后的样式是减号带边框*/
/deep/.el-table__expand-icon--expanded .el-icon-arrow-right:before {
  content: "\e6d8";
}
/* 悬停背景色 */
/deep/ .el-table tbody tr:hover > td {
  background-color: #eff4f9 !important;
}

①. 修改展开 / 折叠 图标
<style lang="scss" scoped>
/* /deeep/样式穿透*/
  /*1.取消原本展开的旋转动效*/
/deep/.el-table__expand-icon{
 -webkit-transform: rotate(0deg);
 transform: rotate(0deg);
}
 /*2.展开按钮未点击的样式是加号带边框*/
 /deep/.el-table__expand-icon .el-icon-arrow-right:before{
   content: "\e6d9";
   border: 1px solid #ccc;
   padding: 1px;
 }
  /*2.按钮已点击展开之后的样式是减号带边框*/
/deep/.el-table__expand-icon--expanded .el-icon-arrow-right:before{
  content: "\e6d8";
}

</style>

②. 点击项也可以选中
    <el-table ref="serveTable" @row-click="rowClick">
    rowClick(row, col, event) { // 点击行也选中
      this.$refs.serveTable.toggleRowSelection(row)
    }

③. resetFields() 失效问题

1.我们需要为每个 form-item 加上 prop 属性,要不然无法清空(大部分的问题就是出在这)
2. resetFields() 方法是重置表单,重置为初始值,而不是设置为空值
3.在 resetFields() 方法之前,如果修改了 data 里的表单默认值,那么重置以后就是你修改以后的值,而不是 data 里的值了

解决:

resetFields() 方法是将 formData 设为初始值,而 formData 是在生命周期 mounted 时被赋值上去的,因此使用 nextTick 方法,初始化数据后赋值即可解决

mounted() {
    this.$nextTick(()=>{
        //赋值
        this.editForm = {...row};
    })
}


4). el-tree


Tree组件_基于elementUI的二次封装及&自己原生开发的轮子

关于 tree 组件 可以看看这篇文章 - - 也是我写的


                  <el-tree
                    class="depart-tree"
                    ref="treeDepartment"
                    show-checkbox
                    highlight-current
                    :accordion="true"
                    :check-strictly="true"
                    :data="departmentList"
                    :props="defaultPropsDepartment"
                    @node-click="nodeClick"
                    @check="checkClick"
                  >
                    <span
                      :title="node.label"
                      class="custom-tree-node"
                      slot-scope="{ node }"
                      style="color: #333333; font-size: 14px"
                    >
                      <span class="textOverflow2">
                        <!-- 图标 -->
                        <i v-if="node.data.isDepart == 1" class="treenode-depart"></i>
                        {{ node.label }}
                      </span>
                    </span>
                  </el-tree>
  data() {
    return {
      // tree 部门文件
      departmentList: [],
      defaultPropsDepartment: {
        children: 'children',
        label: 'name'
      },
    }
  }

①. 回显(默认勾选选中项)

:default-checked-keys=“defaultCheckedKeys”

// tree
ref="rightsTree"
:default-checked-keys="defaultCheckedKeys"
 
// data
defaultCheckedKeys:[]

// methods
this.$nextTick(() => {
   this.$refs.rightsTree.setCheckedKeys(this.defaultCheckedKeys)
})

②. 回显(只勾选子节点)
     this.$refs.attribute.setCheckedKeys(res.checkedKeys)
// 替换成 
     res.checkedKeys.forEach(value => {
        this.$refs.attribute.setChecked(value, true, false)
     })

③. 获取 tree 的节点集合

在这里插入图片描述

// 获取所选节点的 名称
(this.$refs.roleNameTree.getCheckedNodes().map(item => item.name)).toString()

递归获取所有节点的 ID 集合:

    getAllNodes(node = [],arr=[]) {
          for(let item of node) {
              arr.push(item.id)
              let parentArr = []
              if(item.children) parentArr.push(...item.children)
              if(parentArr && parentArr.length) this.getAllNodes(parentArr,arr)
            }
            return arr
    },


5). el-select

                      <el-select
                        v-model="item.versionName"
                        class="inline-select"
                        :ref="'multiSelect' + item.fileName"
                        :placeholder="item.defaultVersion"
                      >
                        <el-option
                          v-for="(itemVersion, indexVersion) in item.versionPath"
                          :value="itemVersion.version"
                          :key="indexVersion"
                          :label="'V' + itemVersion.version"
                        ></el-option>
                      </el-select>
                      
	  // 失去焦点 隐藏下拉框
      let fileFist = this.fileList
      fileFist.forEach(item => {
        this.$refs['multiSelect' + item.fileName][0].blur() // 隐藏弹窗 失去焦点
      })

①. 下拉框隐藏时触发

在这里插入图片描述

@visible-change 函数里面传递两个参数(第一个为回调参数,第二个为自己定义的参数)

@visible-change= "changeValue1( $event ,AREACODE)"

changeValue1:function(callback,vc){
	//只有回调参数为false时才触发 ctx.getAreaListDataSearch(vc,1)这个函数;
    console.log("回调参数"+callback);
    if(!callback){
        var ctx = this;
        ctx.AREACODE2='请选择';
        if(vc!=""){
            ctx.show2 = true;
            ctx.getAreaListDataSearch(vc,1);
        }
    }
}

②. 下拉框值改变时触发

@change=“changeVersion($event, item)”

  • change 事件中,会获取到当前选中的值(因为默认会将event参数传递过去)
  • 如果你想要传递多个值,change ($event,“传递的其他值”),将“选中的当前元素“ 和 ”传递的其他值”一起传递过去。


6). el-input

①. 回车键检索
<el-input v-model="value" type="text" @keyup.enter="search" />

<!-- 方法 2 -->
<el-input v-model="value" type="text" @change="search" />

②. 回车键检索

7). el-scrollbar

这个组件是 elementUI 中没有显示,但是可以用的

<div style="height: 405px; overflow: hidden;">
	<p>msg</p>
</div>


8). el-switch

<el-switch
  style="display: block"
  v-model="value"
  active-color="#13ce66"
  inactive-color="#ff4949"
  active-text="按月付费"
  inactive-text="按年付费">
</el-switch>
<!-- value 是布尔值 -->

①. 传值(布尔改为字符串)
<el-switch
	v-model="lineData.showFlag"
	active-text="可用"
	active-value="1"
	inactive-value="0"
/>


9). el-input(textarea)

<el-input
  type="textarea"
  :rows="2"
  placeholder="请输入内容"
  v-model="textarea">
</el-input>

①. 禁止拖拽大小
textarea {
 resize: none;
}


10). el-form

<!-- 组织 form 表单提交事件 -->
<el-form @submit.native.prevent>


2. 项目组件


1). 云盘项目

①. 弹窗

㈠. 提示弹窗

组件调用:

      <!-- 提示弹窗 -->
      <ruler-tip v-if="isRulerTip" :tipType="tipMsg" />
    closeRulerTip() { // 关闭提示弹窗
      this.isRulerTip = true
      setTimeout(() => { this.isRulerTip = false }, 2000)
    },
    confirm() { // 确认
      if(判断条件) {
        this.tipMsg = 'type1'
        this.closeRulerTip()
        return
      }
      // 下一步
    }

提示弹窗 组件:

<template>
  <div>
		<div class="tsTxt-tc height1" style="display: block;">
			<div class="tsTxt-tc-cnt">
				<p class="txt">{{msg}}</p>
			</div>
		</div>
  </div>
</template>

<script>
import '@/css/css.css'

export default {
  name: 'ruler-tip',
  props: {
    tipType: {
      type: String,
      required: ''
    }
  },
  data() {
    return {
      msg: ''
    }
  },
  mounted() {
    this.judgmentType()
  },
  methods: {
    judgmentType() { // 判断类型(决定显示的提示信息)
      switch (this.tipType) {
        case 'title': this.msg = 'xx不能为空!'
          break
        case 'success': this.msg = '成功!'
          break
        case 'error': this.msg = '失败,请重试!'
          break
        // 返回后端报错反馈
        default: this.msg = this.tipType
      }
    }
  }
}
</script>

<style scoped>
</style>

②. table

㈠. 序号
<td>
	{{ (index + 1) + (paginaton.page * paginaton.pageSize) - paginaton.pageSize }}
</td>

	  // data
      paginaton: {
        page: 1,
        pageSize: 15,
        total: 0
      },

③. input

        <input
          type="text"
          maxlength="50"
          :disabled="this.type == 'edit'"
          required
        />

required: required 属性规定必需在提交表单之前填写输入字段。
required 属性适用于下面的 input 类型:text、search、url、tel、email、password、date pickers、number、checkbox、radio 和 file。


④. textarea

		// html
        <span class="num-word">{{ remarkLong }}/200</span>
        <textarea
          class="note scroll-demo"
          rows="3"
          v-model="examine.remark"
          :disabled="this.type == 'edit'"
        ></textarea>

		// JS
		  watch: {
		    "examine.remark": { // 监听 派发说明
		      handler: function (newd, oldd) {
		        this.examine.remark = newd.replace(/(^\s*)|(\s*$)/g, "");
		        this.remarkLong = newd.length
		        if (newd.length > 200) {
		          this.examine.remark = newd.slice(0, 200);
		        }
		      }
		    },
		 }

⑤. 文件上传

在这里插入图片描述

<el-upload
     class="upload-demo"
     ref="upload"
     action=""
     accept=".zip"
     drag
     :limit="1"
     :auto-upload="true"
     :http-request="upload"
     :file-list="fileList"
 >
     <i class="el-icon-upload"></i>
     <div>将文件拖到此处,或<em>点击上传</em></div>
     <div slot="tip">
         只能上传zip文件,且不超过50MB
     </div>
 </el-upload>
export default {
    name: '',
    data() {
        return {
            fileList: [],
        }
    },
    methods: {
        upload(params) {
            let _file = params.file,
                isLt50M = _file.size / 1024 / 1024 < 50
            let formData = new FormData()
            formData.append('file', _file)
            if (!isLt50M) {
                msg_error('请上传50M以下的.zip文件')
                return false
            }
            let config = {
                headers: { 'Content-Type': 'multipart/form-data' },
            }
            axios
                .post(BASEURL_BASE + '/api/unit/db-operate/importCsv', formData, config)
                .then((res) => {
                    this.$message.success('文件上传成功')
                })
                .catch((err) => {
                    msg_error('抱歉,上传失败!')
                })
        },
    },
}
</script>

⑥. 文件下载
axios.post('your URL', data).then((response) => {
    this.$message.success('数据导出成功')
    let fileData = response.data
    let fileName = decodeURI(response.headers['content-disposition'].split(';')[1].split('=')[1].replaceAll('"', ''))
    let fileType = 'application/octet-stream'
    let blob = new Blob([fileData], { type: fileType })
    let downloadUrl = window.URL.createObjectURL(blob)
    let downloadLink = document.createElement('a')
    downloadLink.href = downloadUrl
    downloadLink.download = fileName
    document.body.appendChild(downloadLink)
    downloadLink.click()
})


未完待续

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后海 0_o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值