1 Star 0 Fork 0

lyc458216 / ES6-ES11语法

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

ES6-ES11 语法

使用 nrm 工具管理 npm 源

安装 nrm:

npm install -g nrm

NRM 常用命令:

# 查看可选源
nrm ls
# 测试 taobao 源响应时间
nrm test taobao
# 切换到 taobao 源
nrm use taobao
# 增加 taobao 定制源,地址为 http:192.168.0.0.1:8080
nrm add taobao http:192.168.0.0.1:8080
# 删除 taobao 源
nrm del taobao

使用 nvm 可以用来管理不同版本的 node.

ES5 中数组遍历方式

reduce() 接收一个函数作为累加器:

// 使用 reduce 进行累加求和
let sum = arr.reduce(function (prev, cur, index, arr) {
  return prev + cur;
}, 0);

// 求出数组中最大值
let max = arr.reduce(function (prev, cur) {
  return Math(prev, cur);
});

// 数组去重
let res = arr.reduce(function (prev, cur) {
  prev.indexOf(cur) == -1 && prev.push(cur);
  return prev;
}, []);

ES6 中新增数组方法

新增的数组遍历方法 for of:

// 遍历数组的值
for (let item of arr.values()) {
  console.log(item);
}
// 遍历数组的索引
for (let item of arr.keys()) {
  console.log(item);
}
// 索引和值都要
for (let [index, item] of arr.entries()) {
  console.log(index, item);
}

数组中的元素替换 fill:

let arr = [1, 2, 3, 4, 5];
arr.fill("imooc", 1, 3);
console.log(arr); // [1, "imooc", "imooc", 4, 5]

可以使用 includes 查找数组中是否含有 NaN:

let arr = [1, 2, 3, NaN];
console.log(arr.includes(NaN)); // true
console.log(arr.indexOf(NaN)); // -1

箭头函数 dia

1、不可当做构造函数

2、不可以使用 arguments 对象,但可以使用 rest 运算符获取参数

let foo = (...args) => {
  console.log(args);
};
foo(1, 2, 3);

ES6 遍历对象

let obj = {
  name: "123",
  age: 18,
  school: "xxx",
};
// 方法1
Object.keys(obj).forEach((key) => {
  console.log(key, obj[key]);
});
// 方法2
Object.getOwnPropertyNames(obj).forEach((key) => {
  console.log(key, obj[key]);
});
// 方法3
Reflect.ownKeys(obj).forEach((key) => {
  console.log(key, obj[key]);
});

深拷贝

// 检查类型
let checkType = (data) => {
  return Object.property.toString.call(data).slice(8, -1);
};
// 深拷贝
let deepClone = (obj = {}) => {
  if (typeof obj !== "object" || object == null) {
    // obj 不是对象类型,或者 obj 是对象类型但为 null,直接返回
    return obj;
  }
  // 初始化返回结果
  let result;
  result = checkType(obj) === "Array" ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      result[key] = deepClone(obj[key]);
    }
  }
  return result;
};

ES5 继承

// 父类
function Animal(name) {
  this.name = name;
}
Animal.prototype.showName = function () {
  console.log(`名字是:` + this.name);
};
// 子类
function Dog(name, color) {
  Animal.call(this, name); // 继承属性
  this.color = color;
}

Dog.prototype = new Animal(); // 继承方法
Dog.prototype.constructor = Dog; // 把原型复原

let d1 = new Dog("wangcai", "white");
console.log(d1);
d1.showName();

ES6 继承

class People {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this._sex = -1; // 给类添加静态方法
  }
  get sex() {
    // 静态类属性的获取
    if (this._sex === 1) {
      return "male";
    } else if (this._sex === 0) {
      return "female";
    } else {
      return "error";
    }
  }
  set sex(val) {
    // 静态类属性的设置
    if (val === 0 || val === 1) {
      this._sex = val;
    }
  }
  showName() {
    console.log(this.name);
  }
  static getCount() {
    return 5;
  }
}

let p1 = new People("lyc", 18);
console.log(p1);

p1.sex = 1; // 父类类的静态属性的设置
console.log(p1.sex); // 父类的静态属性的获取
console.log(p1.getCount()); // 报错,实例调用父类静态方法会报错

class Coder extends People {
  constructor(name, age, company) {
    super(name, age);
    this.company = company;
  }
  showCompany() {
    console.log(this.company);
  }
}
let c1 = new Coder("zhangsan", 18, "xxx");
console.log(c1);
c1.showName();
c1.showCompany();
c1.sex = 1; // 实例可以继承和获取父类的 get / set 属性
console.log(c1.sex);
console.log(Coder.getCount()); // 子类可以继承父类的静态方法

symbol()

1、for……in、for……of 循环无法遍历 symbol 属性 2、Object.getOwnPropertySymbols() 只能能获取到 symbol 属性 3、Reflect.ownKeys() 既能获取到普通属性,又能获取到 symbol 属性

// symbol()
let s1 = Symbol("foo");
let s2 = Symbol("foo");
s1 === s2; // false

// symbol.for():在全局定义
let s1 = Symbol.for("foo");
let s2 = Symbol.for("foo");
s1 === s2; // true

使用 symbol() 去耦合

const shapeType = {
  triangle: Symbol(),
  circle: Symbol(),
};
function getArea(shape) {
  let area = 0;
  switch (shape) {
    case shapeType.triangle:
      area = 1;
      break;
    case shapeType.circle:
      ares = 2;
      break;
  }
  return area;
}
console.log(getArea(shapeType.triangle));

set

let s = new Set([1, 2, 3, 2]);

s.add("imooc").add("es"); // 增
s.delete(2); // 删
s.clear(); // 清空
console.log(s.has("imooc")); // 查
console.log(s.size); // 大小(长度)

// 遍历
s.forEach((item) => console.log(item));
for (let item of s) {
  console.log(item);
}
for (let item of s.keys()) {
  console.log(item); // set 的 key 与 value 相同
}
for (let item of s.values()) {
  console.log(item); // set 的 key 与 value 相同
}
for (let item of s.entries()) {
  console.log(item[0], item[1]); // set 的 key 与 value 相同
}

// 使用 set 求交集
let s1 = new Set(arr1);
let s2 = new Srt(arr2);
let result = new Set(arr1.filter((item) => s2.has(item)));
console.log(Array.from(result));

// 使用 set 求差集
let arr3 = new Set(arr1.filter((item) => !s2.has(item)));
let arr4 = new Set(arr2.filter((item) => !s1.has(item)));
console.log([...arr3, ...arr4]);

WeakSet

1、WeakSet 里只能传入对象,可传入多个对象

2、WeakSet 不能被遍历

MAp

let map = new Map([
  ["name", "xxx"],
  ["age", 5],
]);
console.log(map);
// {
//   0: {"name" => "xxx"}
//   1: {"age" => 5}
//   size: {...}
// }
console.log(map.size);
console.log(map.has("name"));
console.log(map.get("age"));
map.set("name", "zhangsan");
console.log(map);
// {
//   0: {"name" => "zhangsan"}
//   1: {"age" => 5}
//   size: {...}
// }

模板字符串

// 带标签的模板字符串
const foo = (a, b, c, d) => {
  console.log(a);
  console.log(b);
  console.log(c);
  console.log(d);
};
const name = "xxx";
const age = 18;
foo`这是${name},他的年龄是${age}岁`;
//  打印: {
//   ["这是", ",他的年龄是", "岁", raw: Array(3)]
//   xxx
//   18,
//   undefined
// }

ES6 新增正则表达式修饰符

ES5 的正则修饰符:i(忽略大小写) m(多行匹配) g(全局匹配)

ES6 新增:y(粘连修饰符),g 是每次匹配剩余的,y 是从剩余的第一个开始匹配

u: unicode 模式匹配

数值的扩展

// 十进制 -> 二进制
const a = 5;
console.log(a.toString(2)); // 101

// 二进制 -> 十进制
const b = 101;
console.log(parseInt(b, 2)); // 5

// ES6 0B二进制 0O八进制
const a = 0b101;
console.log(a); //5

const b = 0o777;
console.log(b); //511

proxy

// 最简易的代理
let obj = {};
let p = new Proxy(obj, {});
p.name = "imooc";
console.log(obj.name); // 'imooc'
for (let key in obj) {
  console.log(key); // 'name'
}

// get 拦截对象属性的读取,比如proxy.foo或proxy['foo']
let dict = {
  hello: "你好",
  world: "世界",
};
dict = new Proxy(dict, {
  get(target, prop) {
    // target:
    // {
    //   'hello': '你好',
    //   'world': '世界'
    // };
    // dict["world"] 时 prop 为 "world"
    // dict["xxx"] 时 prop 为 "xxx"
    return prop in target ? target[prop] : "error";
  },
});
console.log(dict["world"]); // 世界
console.log(dict["xxx"]); // 'error'

// set 拦截对象属性的设置,返回一个布尔值,比如proxy.foo=v,或数组的push、unshift等
let arr = [];
arr = new Proxy(arr, {
  set(target, prop, val) {
    if (typeof val === "number") {
      target[prop] = val;
      return true;
    } else {
      return false;
    }
  },
});
arr[1] = 7;
arr.push(5);
console.log(arr[0], arr[1], arr[2], arr.length); // undefined 7 5 3

// has 拦截 proKey in proxy 的操作,返回一个布尔值
let range = {
  start: 1,
  end: 5,
};
range = new Proxy(range, {
  has(target, prop) {
    return prop >= target.start && prop <= target.end;
  },
});
console.log(2 in range); // true
console.log(9 in range); // false

// ownKeys 拦截属性遍历包括 getOwnPropertyNames、getOwnPropertySymbols、keys、for……in, 返回一个数组
// 前面知识复习:
let obj = {
  name: "imooc",
  [Symbol("es")]: "es6",
};
console.log(Object.getOwnPropertyNames(obj)); // ['name']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(es)]
console.log(Object.keys(obj)); // ['name']
for (let key in obj) {
  console.log(key); // ['name']
}

// ownKeys 使用:
let userinfo = {
  username: "lyc",
  age: 34,
  _password: "***",
};
userinfo = new Proxy(userinfo, {
  ownKeys(target) {
    return Object.keys(target).filter((key) => !key.startsWidth("_"));
  },
});

for (let key in userinfo) {
  console.log(key); // username age
}
console.log(Object.keys(userinfo)); // ['username', 'age']

// deleteProperty 拦截 delete proxy[proxyKey]的操作,返回一个布尔值

// apply 拦截函数调用、call 和 apply 操作
let sum = (...args) => {
  let sum = 0;
  args.forEach((item) => {
    num += item;
  });
  return num;
};
sum = new Proxy(sum, {
  apply(target, ctx, args) {
    return target(...args) * 2;
  },
});
console.log(sum(1, 2)); // 6
console.log(sum.call(null, 1, 2, 3)); // 12
console.log(sum.apply(null, [1, 2, 3])); // 12

// construct 拦截 new 命令,返回一个对象
let User = class {
  constructor(name) {
    this.name = name;
  }
};
User = new Proxy(User, {
  construct(target, args, newTarget) {
    console.log("construct");
    return new target(...args);
  },
});
console.log(new User("imooc"));

Reflect

1、将 Object 属于语言内部的方法放到 Reflect 上

// Object 上的方法
Object.defineProperty();
// Reflect 上的方法
Reflect.defineProperty();

2、修改某些 Object 方法的返回结果,让其变得更合理

// 原始方法判断某个对象的某个属性能否被定义
try {
  Object.defineProperty(); // 如果不能将报错
} catch (e) {}

// 使用 Reflect
if (Reflect.defineProperty()) {
  // 能否被定义将返回布尔类型的值,而不是报错
  // bollean
} else {
}

3、让 Object 操作变成函数行为

// 原始写法判断 Object 里是否有 assign 方法
console.log("assign" in Object); // true
// 使用 Reflect
console.log(Reflect.has(Object, "assign")); // true

4、Reflect 对象的方法与 Proxy 对象的方法一一对应

Promise

// 回调地狱改成 promise
// callback hell
ajax("static/a.json", (res) => {
  console.log(res);
  ajax("static/b.json", (res) => {
    console.log(res);
    ajax("static/c.json", (res) => {
      console.log(res);
    });
  });
});

// promise
new Promise((resolve, reject) => {
  // 请求 a.json
  ajax("static/a.json", (res) => {
    console.log(res);
    resolve();
  });
}).then(res=>{
  console.log('a 成功')
  return new Promise((resolve, reject) => {
  // 请求 b.json
  ajax("static/b.json", (res) => {
    console.log(res);
    resolve();
  });
}).then(res=>{
  console.log('b 成功')
  return new Promise((resolve, reject) => {
  // 请求 c.json
  ajax("static/c.json", (res) => {
    console.log(res);
    resolve();
  });
}).then(res=>{
  console.log('c 成功')
});

// 优化
function getPromise(url){
  return new Promise(resolve, reject){
    ajax(url, res => {
      resolve(res)
    })
  }
}

getPromise('static/a.json').then(res => {
  console.log(res)
  return getPromise('static/b.json')
}).then(res => {
    console.log(res)
  return getPromise('static/c.json')
}).then(res => {
    console.log(res)
})

// promise.all
const imgArr = ['1.jpg', '2.jpg', '3.jpg']
let promiseArr = []
imgArr.forEach(item => {
  promiseArr.push(new Promise(resolve, reject)=>{
    // 图片上传的操作
    resolve()
  })
})
Promise.all(promiseArr).then(res => {
  // 插入数据库的操作
  console.log('图片全部上传完成')
})

// 使用 promise.race 限制请求加载时间
function getImg(){
  return new Promise((resolve, reject) => {
    let img = new Image()
    img.onload = function(){
      resolve(img)
    }
    img.src = 'http://www.xxx.com/xxx.jpg'
  })
}

function timeOut(){
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('图片请求超时')
    }, 2000)
  })
}

Promise.race([getImg(), timeOut()]).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

generator

function* gen(x) {
  let y = 2 * (yield x + 1);
  let z = yield y / 3;
  return x + y + z;
}

let g = gen(5);
console.log(g.next()); // 6
console.log(g.next()); // NaN
console.log(g.next()); // NaN

let g = gen(5);
console.log(g.newxt()); // 6
console.log(g.newxt(12)); // 8 y=24
console.log(g.newxt(13)); // 42 z=13 x=5

// 自增 7 的生成器
function* count(x = 1) {
  while (true) {
    if (x % 7 === 0) {
      yield x;
    }
    x++;
  }
}

let n = count();
console.log(n.next().value); // 7
console.log(n.next().value); // 14
console.log(n.next().value); // 21
console.log(n.next().value); // 28
console.log(n.next().value); // 35

// 使用生成器连续发送请求
function request(url) {
  ajax(url, (res) => {
    getData.next(res);
  });
}

function* gen() {
  let res1 = yield request("static/a.json");
  console.log(res1);
  let res2 = yield request("static/b.json");
  console.log(res2);
  let res3 = yield request("static/c.json");
  console.log(res3);
}

let getData = gen();
getData.next();

Iterator

对于可迭代对象有两种情况: 1、可迭代协议:Symbol.iterator 2、迭代器协议:

// 把不可迭代的对象可迭代化
return {
  next() {
    return { value, done };
  },
};

原生具备 Iterator 接口的数据结构: Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象

function makeIterator(arr) {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < arr.length
        ? {
            value: arr[nextIndex++],
            done: false,
          }
        : {
            value: undefined,
            done: true,
          };
    },
  };
}
let it = makeIterator(["a", "b", "c"]);
console.log(it.next()); // {value: 'a', done: false}
console.log(it.next()); // {value: 'b', done: false}
console.log(it.next()); // {value: 'c', done: false}
console.log(it.next()); // {value: undefined, done: true}

// 数组原生的 iterator
let arr = ["a", "b", "c"];
console.log(arr);
let it = arr[Symbol.iterator]();
console.log(it.next()); // {value: 'a', done: false}
console.log(it.next()); // {value: 'b', done: false}
console.log(it.next()); // {value: 'c', done: false}
console.log(it.next()); // {value: undefined, done: true}

// 让对象可迭代
let courses = {
  allCourse:{
    frontend: ['ES', '小程序', 'Vue', 'React']
    backend: ['Java', 'Python', 'SpringBoot']
    webapp: ['Android', 'IOS']
  }
}

courses[Symbol.iterator] = function(){
  let allCourse = this.allCourse
  let keys = Reflect.ownKeys(allCourse)
  let values = []
  return{
    next(){
      if(!values.length){
        if(keys.length){
          values = allCourse[keys[0]]
          keys.shift()
        }
      }return{
        done:!values.length,
        value:values.shift()
      }
    }
  }
}
// 使用
for(let c of courses){
  console.log(c)
}

// 使用 generator 实现
courses[Symbol.iterator] = function* (){
  let allCourse = this.allCourse
  let keys = Reflect.ownKeys(allCourse)
  let values = []
  while(true){
    if(!values.length){
      if(keys.length){
        values = allCourse[keys[0]]
        keys.shift()
        yield value.shift()
      } else {
        return false
      }
    } else {
      yield values.shift()
    }
  }
}

async 与 await

function timeout() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(1);
      resolve();
    }, 1000);
  });
}
// 使用 await 与不使用 await
// 使用 await
async function foo1() {
  await timeout();
  console.log(2); // 先打印 1 后打印 2
}
// 不使用 await
async function foo2() {
  timeout();
  console.log(2); // 先打印 2 后打印 1
}

// 使用 async await 处理失败的 promise
function timeout() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // resolve('success');
      reject("fail");
    }, 1000);
  });
}

async function foo() {
  return await timeout();
}
foo()
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

// async await 实现 axios 伪代码
async function request() {
  const data = await axios.get("http://xxx.com");
  console.log(data);
}

// 使用 async await 实现 ajax 的异步操作按顺序执行
function request(url) {
  return new Promise((resolve) => {
    ajax(url, (res) => {
      resolve(res);
    });
  });
}
async function getData() {
  const res1 = await request("static/a.json");
  console.log(res1);
  const res2 = await request("static/b.json");
  console.log(res2);
  const res3 = await request("static/c.json");
  console.log(res3);
}
getData();

for await of

// 数组的同步迭代遍历 for……of
const arr = ["es6", "es7", "es8", "es9"];
arr[Symbol.iterator] = function () {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < arr.length
        ? {
            value: arr[nextIndex++],
            done: false,
          }
        : {
            value: undefined,
            done: true,
          };
    },
  };
};
for (let item of arr) {
  console.log(item);
}

// 数组的异步迭代遍历 for await……of
function getPromise(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        value: time,
        done: false,
      });
    }, time);
  });
}

const arr = [getPromise(1000), getPromise(2000), getPromise(3000)];

arr[Symbol.asyncIterator] = function () {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < arr.length
        ? arr[nextIndex++]
        : {
            value: undefined,
            done: true,
          };
    },
  };
};

async function test() {
  for await (let item of arr) {
    console.log(item);
  }
}
test();
// 1 秒后打印 1000
// 再隔 2 秒后打印 2000
// 再隔 3 秒后打印 3000

正则表达式

// 具名组匹配
const reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const groups = reg.exec("2020-02-01").groups;
const { year, month, day } = groups;
console.log(year, month, day);

// 先行断言
const str = "ecmascript";
console.log(str.match(/ecma(?=script)/)); // 匹配后面是 script 的 ecma
// 后行断言
console.log(str.match(/(?<=ecma)script/)); // 匹配前面是 ecma 的 script
console.log(str.match(/(?<!ecma)script/)); // 匹配前面不是 ecma 的 script

Object.fromEntries()

// 过滤对象中大于 80 的项
const course = {
  math: 80,
  english: 85,
  chinese: 90,
};
const res = Object.entries(course).filter(([key, value]) => val > 80);
console.log(Object.fromEntries(res));

数组扁平化

const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
console.log(arr.flat(Infinity)); // arr.flat 传入的参数为扁平化层级

正则表达式的全局匹配

const str = `
<html>
  <body>
    <div>第一个div</div>
    <p>这是p</p>
    <div>第二个div</div>
    <span>这是span</span>
    <div>第三个div</div>
  </body>
</html>
`;
// 使用正则对象的 exec g 匹配全部的 div
function selectDiv(regExp, str) {
  let matches = [];
  while (true) {
    console.log(regExp.lastIndex);
    const match = regExp.exec(str);
    console.log(match);
    if (match == null) {
      break;
    }
    matches.push(match[1]);
  }
  return matches;
}
const regExp = /<div>(.*)<\/div>/g; // 不使用 g 模式匹配,会在每次匹配后重头开始匹配,导致 while 死循环
const res = selectDiv(regExp, str);
console.log(res);

// 字符串的 match 方式实现
console.log(str.match(regExp)); //['<div>第一个div</div>, '<div>第二个div</div>', '<div>第三个div</div>']

// 字符串的 replace 方式实现
function selectDiv(regExp, str) {
  let matches = [];
  str.replace(regExp, (all, first) => {
    matches.push(first);
  });
  return matches;
}
const res = selectDiv(regExp, str);
console.log(res); // ['第一个div, '第二个div', '第三个div']

// 字符串的 matchAll 方式实现
function selectDiv(regExp, str) {
  let matches = [];
  for(let match of str.matchAll(regExp)){
    matches.push(match[1]);
  });
  return matches;
}
const res = selectDiv(regExp, str)
console.log(res); // ['第一个div, '第二个div', '第三个div']

Promise.allSettled

Promise.allSettled([
  Promise.resolve({
    code: 200,
    data: [1, 2, 3],
  }),
  Promise.reject({
    code: 500,
    data: [],
  }),
  Promise.resolve({
    code: 200,
    data: [7, 8, 9],
  });
]).then(res=>{
  const data = res.filter(item => item.status === 'fulfilled')
  console.log(data)
})

vue 实战

async created(){
  const {data} = await axios.get('http://www.xxx.com')
  // 对数据的升序降序进行代理
  this.proxy = new Proxy({},{
    get(target, key){
      if(key === 'asc'){  // 升序
        return [].concat(data).sort((a, b) => a.name > b.name ? 1 : -1)
      }else if(key === 'desc'){ // 降序
        return [].concat(data).sort((a, b) => b.name > a.name ? 1 : -1)
      }else{
        return data
      }
    },
    set(){
      return false
    }
  })
  this.userLst = this.proxy.data.default
},
methods:{
  asc(){
    this.userList = this.proxy.asc
  },
  desc(){[].concat(data this.userList = this.proxy.desc
  },
  reset(){
    this.userList = this.proxy.default
  }
}

多图片上传到云存储:

<div>
  <label for="uploadImg" :class="{upLoading: isUploading}"
    >请选择上传图片</label
  >
  <input
    type="file"
    multiple
    id="uploadImg"
    style="display:none;"
    accept="image/*"
    @change="onChange"
    ref="imgFile"
    :disabled="isUploading"
  />
  <p>提示:一次可选择多张图片,最多不超过9张(单张大小 &lt; 1M)</p>
  <ul class="img-container">
    <li
      v-for="(item, index) in imgList"
      :key="index"
      :style="{background: `url(${item}) no-repeat center/contain`}"
    ></li>
  </ul>
</div>
<script>
  import OSS from "ali-oss";
  export default {
    data() {
      return {
        client: new OSS({
          region: "oss-cn-beijing",
          bucket: "xxx",
          accessKeyId: "自己的id",
          accessKeySecret: "自己的密码",
        }),
        imgList: [], // 存放上传完成的图片的列表
        isUploading: false, // 当前图片是否正在上传
      };
    },
    methods: {
      onChange() {
        // 可选链
        const newFiles = this.$refs?.imgFile?.files;
        // 校验
        if (newFiles.length > 9) {
          alert("最多可以一次选择9张图片");
          return false;
        }
        const files = [];
        for (const file of newFiles) {
          const size = file.size / 1024 / 1024; // 把单位转化成 M
          if (size > 1) {
            alert("请选择1M以内的图片");
            return false;
          }
          files.push(file);
        }
        this.uploadFilesByOSS(files);
      },
      // 上传多图到阿里云OSS
      uploadFilesByOSS(files) {
        this.isUploading = true;
        const uploadRequest = [];
        for (const file of files) {
          new Promise((resolve, reject) => {
            this.client
              .put(`${Math.random()}-${file.name}`, file)
              .then((res) => {
                resolve(res.url);
              })
              .catch((err) => {
                console.log(err);
                reject(err);
              });
          });
        }
        Promise.allSettled(uploadRequest)
          .then((res) => {
            const imgs = [];
            for (const item of res) {
              if (item.status === "fulfilled") {
                imgs.push(item.value);
              }
            }
            this.imgList = imgs;
            this.isUploading = false;
          })
          .catch((err) => {
            console.log(err);
          });
      },

      // 使用 async / await 更优雅的实现上传多图到阿里云OSS
      async uploadFilesByOSS2(files) {
        this.isUploading = true;
        const imgs = [];
        for (const file of files) {
          const result = await this.client.put(
            `${Math.random()}-${file.name}`,
            file
          );
          imgs.push(result.url);
        }
        this.imgList = imgs;
        this.isUploading = false;
      },
    },
  };
</script>
<style>
  .img-container > li {
    list-style: none;
    width: 150px;
    height: 100px;
    float: left;
    margin: 0 30px 30px 0;
    border: 1px solid #ccc;
  }
</style>

webpack 初探

1、Loader:

loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: "raw-loader",
      },
    ];
  }
}

2、Plugin:

loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务,比如打包优化、资源管理、注入环境变量等

const HtmlWebpackPlugin = require("html-webpack-plugin"); // 用于为 html 文件自动引入外部资源
const webpack = require("webpack"); // 用于访问内置插件

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
};

对某一个目录下的文件不进行 webpack 打包编译,直接拷贝过去:

const copyPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new copyPlugin([
      { from: "source", to: "dest" }, // 从 source 目录原方不动的拷贝到 dest 目录下
      { from: "other", to: "public" }, // 从 other 目录原方不动的拷贝到 public 目录下
    ]),
  ],
};

webpack 优化配置

package.json:

"scripts":{
  "start": "webpack-dev-server --mode=development --config ./build/webpack.config.js",
  "build": "webpack --mode=production --config ./build/webpack.config.js"
}

webpack.config.js:

const merge = require("webpack-merge");
const baseConfig = require("./webpack.base.config.js");
const devConfig = require("./webpack.dev.config.js");
const proConfig = require("./webpack.pro.config.js");

module.exports = (env, argv) => {
  // 此处的 argv 参数需要在 package.json 中传入
  const config = argv.mode === "development" ? devConfig : proConfig;
  return merge(baseConfig, config);
};

webpack.base.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              [
                "@babel/preset-env",
                {
                  useBuiltIns: "entry",
                },
              ],
            ],
          },
        },
      },
    ],
  },
};

webpack.dev.config.js:

module.exports = {
  devtool: "cheap-module-eval-source-map",
};

webpack.pro.config.js:

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  plugins: [new CleanWebpackPlugin()],
};

空文件

简介

暂无描述 展开 收起
JavaScript
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/lyc458216/es6-es11-syntax.git
git@gitee.com:lyc458216/es6-es11-syntax.git
lyc458216
es6-es11-syntax
ES6-ES11语法
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891