总结常用方法

# 文本复制

copyText() {
      navigator.clipboard.writeText(this.detailData).then(() => {
        this.$message.success("复制成功");
      });
    },

# 数据筛选

场景:有多个输入框,输入一个及以上的条件,实现数据过滤。

let data = [
  {
    name: "名侦探柯南",
    price: 13,
    num: 108,
    hot: 0,
    status: 1,
  },
  {
    name: "大侦探皮卡丘",
    price: 13,
    num: 151,
    hot: 1,
    status: 0,
  },
  {
    name: "绿皮书",
    price: 13,
    num: 72,
    hot: 1,
    status: 1,
  },
];

//@param condition 过滤条件
//@param data 需要过滤的数据
let filter = (condition, data) => {
  return data.filter((item) => {
    return Object.keys(condition).every((key) => {
      return String(item[key])
        .toLowerCase()
        .includes(String(condition[key]).trim().toLowerCase());
    });
  });
};

//无条件
var condition = { name: "", hot: "" };
var aa = filter(condition, data);
console.log(aa); // [{"name":"名侦探柯南","price":13,"num":108,"hot":0,"status":1},{"name":"大侦探皮卡丘","price":13,"num":151,"hot":1,"status":0},{"name":"绿皮书","price":13,"num":72,"hot":1,"status":1}]

//单条件
var condition = { name: "侦探" };
var bb = filter(condition, data);
console.log(bb); // [{"name":"名侦探柯南","price":13,"num":108,"hot":0,"status":1},{"name":"大侦探皮卡丘","price":13,"num":151,"hot":1,"status":0}]

//多条件
var condition = { name: "侦探", hot: "1" };
var cc = filter(condition, data);
console.log(cc); //[{"name":"大侦探皮卡丘","price":13,"num":151,"hot":1,"status":0}]

# 标准时间转化

// 2022-11-07T11:16:24.000+00:00  ->  2022-11-07 19:16:24
function formatDate(date) {
  if (date) {
    let jsonDate = new Date(date).toJSON();
    return new Date(+new Date(jsonDate) + 8 * 3600 * 1000)
      .toISOString()
      .replace(/T/g, " ")
      .replace(/\.[\d]{3}Z/, "");
  }
}

# 可选链 " ?. "

如果可选链 '?.' 前面的值为 undefined 或 null,则停止运算并返回 undefined,而非常规写法会报错. ?. 前的变量必须已声明,可选链仅适用于已声明的变量. ?. 语法使其前面的值成为可选值,但不会对其后面的起作用. ?.() 用于调用一个可能不存在的函数 ?.[] 用于读取一个可能不存在的对象上的属性 可以使用 ?. 来安全地读取或删除,但不能写入

obj?.prop —— 如果 obj 存在则返回 obj.prop,否则返回 undefined。 obj?.[prop] —— 如果 obj 存在则返回 obj[prop],否则返回 undefined。 obj.method?.() —— 如果 obj.method 存在则调用 obj.method(),否则返回 undefined。

let user = {};
alert(uesr?.age?.sex); // undefined

let user = null;
alert(user?.address); // undefined
alert(user?.address?.name); // undefined

let html = document.querySelector(".box")?.innerHTML; // 如果不存在,则返回undefined,而不是常规的报错

delete user?.name; // 如果 user 存在,则删除 user.name

# 换行

a = "111" + \
           "\n111:" + arr[1]
b = ("222\n"
            "222" + arr[2])

# js 注释

/**
 * 返回 x 的 n 次幂的值。
 *
 * @param {number} x 要改变的值。
 * @param {number} n 幂数,必须是一个自然数。
 * @return {number} x 的 n 次幂的值。
 */
function pow(x, n) {
  // ...
}

# 导航栏显示与隐藏 (曲线救国)

场景:鼠标移除导航栏,导航栏隐藏,移入则显示

window.onload = function () {
  let nav = document.querySelector(".nav");
  nav.onmouseover = function () {
    nav.style.opacity = "1";
  };
  nav.onmouseout = function () {
    nav.style.opacity = "0";
  };
};

# 内嵌网页

let iframe = document.createElement("iframe");
iframe.src = "https://www.baidu.com";
iframe.width = "100%";
iframe.height = "100%";
document.body.appendChild(iframe);

# 数组扁平化

const nestedArray = [
  [1, 2],
  [3, 4],
  [5, 6],
];
const flattenedArray = nestedArray.reduce((acc, curr) => acc.concat(curr), []);
console.log(flattenedArray); // [1, 2, 3, 4, 5, 6]

# 树结构扁平化

const tree = {
  name: "A",
  children: [
    {
      name: "B",
      children: [
        { name: "D", children: [] },
        { name: "E", children: [] },
      ],
    },
    { name: "C", children: [] },
  ],
};

function flattenTree(tree) {
  return [
    tree,
    ...tree.children.reduceRight((acc, curr) => {
      return [...acc, ...flattenTree(curr)];
    }, []),
  ];
}

const flattenedTree = flattenTree(tree);
console.log(flattenedTree);
// [
//   { name: 'A', children: [...] },
//   { name: 'B', children: [...] },
//   { name: 'D', children: [] },
//   { name: 'E', children: [] },
//   { name: 'C', children: [] }
// ]

# table 表格隐藏网格线

table {
  border-collapse: collapse;
}

# 正则校验

/* eslint-disable no-useless-escape */
/**
 * 验证外链
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

/**
 * 验证网址
 * @param {string} url
 * @returns {Boolean}
 */
export function validURL(url) {
  const reg =
    /^(((ht|f)tps?):\/\/)?[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/;
  return reg.test(url);
}

/**
 * 验证身份证,支持一代、二代
 * @param {string} cardId
 * @returns {Boolean}
 */
export function validCardId(cardId) {
  const reg =
    /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0\d|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/;
  return reg.test(cardId);
}

/**
 * 验证邮编
 * @param {String} str
 * @returns {Boolean}
 */
export function validZipCode(str) {
  const reg = /^[1-9]\d{5}$/;
  return reg.test(str);
}

/**
 * 验证区县代码
 * @param {String} str
 * @returns {Boolean}
 */
export function validDistrictCode(str) {
  const reg = /^[1-8][0-7]\d{4}$/;
  return reg.test(str);
}

/**
 * 验证邮箱
 * @param {string} email
 * @returns {Boolean}
 */
export function validEmail(email) {
  const reg = new RegExp(
    "^([a-z0-9]{3,20})([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$"
  );
  return reg.test(email);
}

/**
 * 验证手机号码
 * @param {string} phone
 * @returns {Boolean}
 */
export function validPhone(phone) {
  const reg =
    /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
  return reg.test(phone);
}

/**
 * 验证国内电话
 * @param {string} callNumber
 * @returns {Boolean}
 */
export function validCallNo(callNumber) {
  const reg = /^0\d{2,3}-?\d{7,8}$/;
  return reg.test(callNumber);
}

/**
 * 验证手机或座机号码
 * @param {string} phone
 * @returns {Boolean}
 */
export function validlandLineOrPhone(phone) {
  return validPhone(phone) || validCallNo(phone);
}

/**
 * 验证护照
 * @param {string} callNumber
 * @returns {Boolean}
 */
export function validPassport(passport) {
  const reg =
    /(^[EeKkGgDdSsPpHh]\d{8}$)|(^(([Ee][a-fA-F])|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\d{7}$)/;
  return reg.test(passport);
}

/**
 * 验证ip(ipv4, ipv6)
 * @param {string} ip
 * @returns {Boolean}
 */
export function validIp(ip) {
  const reg =
    /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i;
  const reg2 = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
  return reg.test(ip) || reg2.test(ip);
}

/**
 * 验证社会统一信用代码
 * @param {string} creditCode
 * @returns {Boolean}
 */
export function validCreditCode(creditCode) {
  const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
  return reg.test(creditCode);
}

/**
 * 验证企业组织机构代码
 * @param {string} creditCode
 * @returns {Boolean}
 */
export function validEntpCode(entpCode) {
  const reg = /[A-Z0-9]{8}-[A-Z0-9]$|[A-Z0-9]{8}-[A-Z0-9]-[0-9]{2}$/;
  return reg.test(entpCode);
}

/**
 * 验证营业执照编号
 * @param {string} creditCode
 * @returns {Boolean}
 */
export function validBizLicense(bizLicense) {
  const reg =
    /(^(?:(?![IOZSV])[\dA-Z]){2}\d{6}(?:(?![IOZSV])[\dA-Z]){10}$)|(^\d{15}$)/;
  return reg.test(bizLicense);
}

/**
 * 验证纯数字
 * @param {number} number
 * @returns {Boolean}
 */
export function validNumber(number) {
  const reg = /<(\w+)[^>]*>(.*?<\/\1>)?/;
  return reg.test(number);
}

/**
 * 验证浮点数
 * @param {number} number
 * @returns {Boolean}
 */
export function validFloatNumber(number) {
  const reg = /^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$/g;
  return reg.test(number);
}

/**
 * 验证浮点数
 * @param {number} number
 * @returns {Boolean}
 */
export function validPositiveFloat(number) {
  const reg = /^([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$/g;
  return reg.test(number);
}

/**
 * 验证整数
 * @param {number} number
 * @returns {Boolean}
 */
export function validInt(number) {
  const reg = /^[-\+]?\d+$/g;
  return reg.test(number);
}

/**
 * 验证正整数
 * @param {number} number
 * @returns {Boolean}
 */
export function validPositiveInt(number) {
  const reg = /^[1-9]+\d*$/g;
  return reg.test(number);
}

/**
 * 验证复杂密码 必须包含数字、字母且长度为8到14位
 * @param {String} str
 * @returns {Boolean}
 */
export function validComplexPassword(str) {
  const reg = /^(?=.*\d)(?=.*[A-Za-z])[\x20-\x7e]{8,14}$/g;
  return reg.test(str);
}

/**
 * 验证字符串
 * @param {string} str
 * @returns {Boolean}
 */
export function isString(str) {
  if (typeof str === "string" || str instanceof String) {
    return true;
  }
  return false;
}

/**
 * 验证数组
 * @param {Array} arg
 * @returns {Boolean}
 */
export function isArray(arg) {
  if (typeof Array.isArray === "undefined") {
    return Object.prototype.toString.call(arg) === "[object Array]";
  }
  return Array.isArray(arg);
}

/**
 * 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性
 * 如果没有传入key这个参数,则判断obj对象是否有键值对
 */
export const hasKey = (obj, key) => {
  if (key) return key in obj;

  const keysArr = Object.keys(obj);
  return keysArr.length;
};

/**
 * @param {*} obj1 对象
 * @param {*} obj2 对象
 * @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串
 */
export const objEqual = (obj1, obj2) => {
  const keysArr1 = Object.keys(obj1);
  const keysArr2 = Object.keys(obj2);
  if (keysArr1.length !== keysArr2.length) return false;
  if (keysArr1.length === 0 && keysArr2.length === 0) return true;
  /* eslint-disable-next-line */ else
    return !keysArr1.some((key) => obj1[key] != obj2[key]);
};

//防xss攻击
export const validXSS = (value) => {
  if (!value) {
    return;
  }
  const reg = /[~@#$%^&*()<>?"{}|.\/'\\[\]~@#¥%……&*——{}|“”]/;
  return reg.test(value) || value.indexOf("script") > -1;
};