Daily summary

h5长按 touch事件

多个域名如何配置axios

1. ES6 Part

const

const 声明的对象改变其属性值,是可以的,因为内存地址没变。

如果要使其对象的属性不能改变,使用 Object.defineProperty 设置不可写,也可使用Object.freeze()进行冻结。

如果冻结嵌套对象可以自定义递归冻结函数。

    function myFreeze(obj) {
        Object.freeze(obj)
        Object.keys(obj).forEach((key) => {
            if (typeof obj[key] === 'object' && typeof obj[key] != null) {
                myFreeze(obj[key])
            }
        })
    }

解构

使用场景

  • 函数传参
    function sum([a,b,c]){
        return a+b+c
    }
    a([1,2,3])
  • 函数返回值
    function sum(){
        return {
            a:1,
            b:2
        }
    }
    let {a,b}=sum()
  • JSON
  • Ajax请求
    axios.get().then(({data})=>{
        console.log(data)
    })

    //等价于
    axios.get().then((res)=>{
        console.log(res.data)
    })

class

class实际上是函数,一个语法糖 

    class People { }
    console.log(typeof People)//function

2. Native JS Part

this

  • 默认绑定

浏览器环境指向Window,node环境指向globle

    let obj1 = {
      print() {
        setTimeout(function () {
          //this === window
          console.log(this)
        }, 250)
      }
    }

    let obj2 = {
      print() {
        setTimeout(() => {
          //this 指向print
          console.log(this)
        }, 250)
      }
    }
  • 隐式绑定

如果函数调用时,前面存在调用它的对象,那么this就会隐式绑定到这个对象上(如:obj.fn() )

如果函数调用前存在多个对象,this指向距离调用自己最近的对象(但不要与原型链概念混淆)

在特定情况下会存在隐式绑定丢失的问题,最常见的就是作为参数传递以及变量赋值。

    // 函数参数
    let name = 'window';
    let obj = {
      name: 'obj',
      fn: function () {
        console.log(this.name);
      }
    };

    function fn1(param) {
      param();
    };
    fn1(obj.fn);//window

闭包

自由变量的查找是在函数定义的地方向上级作用域查找,不是在执行的地方。

  • 函数作为返回值
    function print() {
      let a = 11
      return function () {
        console.log(a)
      }
    }
    let a = 22
    let fn = print()
    fn()//11
  • 函数作为参数
    function print(fn) {
      let a = 2
      fn()
    }
    let a = 1
    function fn() {
      console.log(a)
    }
    print(fn) //1
  • 闭包隐藏数据,只提供API

    function createCache() {
      const data = {}
      return {
        set: function (key, val) {
          data[key] = val
        },
        get: function (key) {
          return data[key]
        }
      }
    }

    let c = createCache()
    c.set('a', 1)
    console.log(c.get('a'))

typeof 运算符

  • 能判断值类型
    let a;//undefined
    const str = 'abc'//string
    const n = 100 //number
    const b = true //boolean
    const s = Symbol('s') //symbol
  • 引用类型。能判断函数,能识别引用类型(但不能再继续识别) 
    typeof null //object
    typeof {} //object
    typeof [] //object
    typeof function(){} //function
    typeof Array //function

深拷贝

    function deepClone(obj = {}) {
      if (typeof obj !== 'object' || obj == null) {
        return obj;
      }

      let result;
      obj instanceof Array ? result = [] : result = {}

      for (const key in obj) {
        // 保证key不是原型上的属性
        // hasOwnProperty不会遍历原型上的属性
        if (obj.hasOwnProperty(key)) {
          result[key] = deepClone(obj[key]);
        }
      }

      return result;
    }

== 运算符

    obj.a == null
    //相当于
    obj.a === null || obj.a === undefined

除了 == null 之外,其余用 === 进行比较判断

    // 以下是falsely变量,除此之外都是truely变量
    !!0 === false
    !!NaN === false
    !!'' === false
    !!null === false
    !!undefined === false
    !!false === false

 Array.prototype.filter()

filter()函数大部分需要return,同时注意箭头函数简写

// 功能正常
arrList = arrList.filter((item) => item.id !== id)
arrList = arrList.filter((item) => { return item.id !== id })

//不加return功能会错误
arrList = arrList.filter((item) => {item.id !== id })
arrList = arrList.filter(function (item) {item.id !== id })

Map() 

    // 为数组对象每一个加一个属性
    // map返回一个新数组,不会更改原数组
    let newArr=this.arr.map((item)=>{
        return {
            ...item,newAttri:newValue
        }
    })

Cookie

    function getCookie(key){
        var arr1=document.cookie.split("; ");
        //由于cookie是通过一个分号+空格的形式串联起来的,所以这里需要先按分号空格截断,变成
        //[name=Jack,pwd=123456,age=22]数组类型;
        for(var i=0;i<arr1.length;i++){
            var arr2=arr1[i].split("=");//通过=截断,把name=Jack截断成[name,Jack]数组;
            if(arr2[0]==key){
                return decodeURI(arr2[1]);
            }
        }
    }

onbeforeunload

关闭页面、刷新页面均会执行 

 // 判断是刷新网页还是关闭网页 
 let beginTime = 0;//开始时间
  let differTime = 0;//时间差

  console.log('我来了')

  window.addEventListener('unload', () => {
    differTime = new Date().getTime() - beginTime;
    
    if(differTime <= 5){
      console.log('进来了1')
      storage.remove(LOGIN_CODE);
    }else{
      console.log('进来了2')
    }
  });

  window.addEventListener('beforeunload', () => {
    console.log('进来了3')
    beginTime = new Date().getTime();
  });

 扁平化数组转换为树形结构

        function toTree(data) {
            let _data = JSON.parse(JSON.stringify(data));

            return _data.filter((p, pi) => {
                const _arr = _data.filter(c => p.id === c.pid);
                _arr.length && (p.children = _arr);
                return p.pid === 0;
            });
        }

 事件委托

例子:ul下有多个li,每个li点击事件,同时li可以新增,如何设计点击事件函数

<ul @click="show">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<script>
    show(e){
        console.log(e.target)
    },
</script>

3. CSS Part

  • word-break (div中英文无法自动换行)

word-break:break-all

  • 神秘的line-height
  • 选择器

相邻兄弟选择器 (+)

兄弟选择符 (~),位置无须紧邻,只须同层级

  • fixed定位在底部问题

// 如果全局样式有最大宽750px 那可能只写bottom:0 width: 100% 时,会在屏幕大于750px时,
// fixed_tabbar宽度最大只有750px
// 所以最好写上left 两个位置的定位才准确
.fixed_tabbar{
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
}

overflow属性

  • overflow:auto; 内容会被修剪,超出设置的宽高后会出现滚动条。
  • overflow:scroll; 内容会被修剪,不管内容是否超出,都会出现滚动条的位置
  • overflow:visible; 这个是默认值,内容不会被修剪,会出现在元素框外面。
  • overflow:hidden; 内容被修剪,多余的内容被隐藏
  • overflow:inherit; 从父元素那里继承overflow的值。

美化ant UI sidebar 滚动条
 

/* style='overflowY: auto' */
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
  ::-webkit-scrollbar{
    width: 7px;
    height: 7px;
    background-color: #F5F5F5;
  }

  /*定义滚动条轨道 内阴影+圆角*/
  ::-webkit-scrollbar-track {
    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
    border-radius: 10px;
    background-color: #F5F5F5;
  }

  /*定义滑块 内阴影+圆角*/
  ::-webkit-scrollbar-thumb{
    border-radius: 10px;
    box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
    background-color: #c8c8c8;
  }
  • rem单位border-radius:50%在安卓手机中画圆变形 

宽高度可以使用px,要不rem出现奇数可能也会导致不圆

使用svg

使用图片

使用transform scale。先把width,height的值放大一倍,然后用transform scale(.5)缩小一倍,接着用transform-origin调整下圆的位置

#calendar_wrap .calendar_days .date_item .date .spot {
  position: absolute;
  bottom: 4rpx;
  left: 50%;
  display:inline-block;
  width:16rpx;
  height:16rpx;
  background-color:#0d7ee1;
  border-radius:50%;
  transform:scale(.5) translateX(-50%);
  transform-origin:0% center;
}

4. BOM

window.location.search

5. Vue

  • vue cli 2跨域

将axios的baseURL注释,请求才会经过proxyTable里面的target

怎么在样式中使用组件中接收的参数?

<template>
  <div class="box" :style="styleVar">
  </div>
</template>
<script>
export default {
  props: {
    height: {
      type: Number,
      default: 54,
    },
  },
  computed: {
    styleVar() {
      return {
        '--box-height': this.height + 'px'
      }
    }
  },
}
</script>
<style scoped>
.box {
  height: var(--box-height);
}
</style>

自定义组件绑定点击事件@click 要使用native来修饰

<my-component @click.native="test"></my-component>

6.  兼容ios

  • input等输入框在iPhone上边框有阴影

    input{
       outline: none;
        -webkit-appearance: none; /*去除系统默认的样式*/
	    -webkit-tap-highlight-color: rgba(0, 0, 0, 0); /* 点击高亮的颜色*/
    }
  • 移动端input框 在手机页面中无法输入文字的问题
    -moz-user-select: none;
    -webkit-user-select: none;
  • position:fixed定位的元素会随着页面的滑动而抖动

7.数组操作

问题:数组的深拷贝

方法:JSON.parse(JSON.stringify(array))、展开运算符[...]、Array.from()、Array.prototype.concat()

问题:数组的并集、交集和差集

方法:Set

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

问题:数组去重

方法:Set、reduce、filter

// 方法一:Set(ES6)
function unique(arr) {
    return Array.from(new Set(arr))
}
// 或者
var unique = arr => [...new Set(arr)]

var arr = [1, 2, 2, 3]
unique(arr); // [1, 2, 3]

// 方法二:reduce
function unique (arr) {
    return arr.sort().reduce((acc, cur) => {
     if (acc.length === 0 || acc[acc.length - 1] !== cur) {
         acc.push(cur);
     }
     return acc
 }, [])}
;

var arr = [1, 2, 2, 3]
unique(arr); // [1, 2, 3]

// 方法三:filter
function unique(arr) { 
    return arr.filter( (element, index, array) => {
     return array.indexOf(element) === index
 })
}

var arr = [1, 2, 2, 3]
unique(arr); // [1, 2, 3]

 问题:数组扁平化

方法:flat、reduce、栈

  • Array.prototype.flat()
  1. 该方法返回一个新的数组,对原数据没有影响

  2. 不传参数时,默认扁平化一层;传入一个整数时,这个整数代码想要扁平化的层数

  3. 传入 <=0 的整数将不进行扁平化,返回原数组

  4. Infinity 关键字作为参数时,无论是多少层嵌套,都会转为一维数组

  5. 如果原数组有空位,会跳过空位

const test = ["a", ["b", "c"], ["d", ["e", ["f"]], "g"]]

// flat不传参数时,默认扁平化一层
test.flat()
// ["a", "b", "c", "d", ["e", ["f"]], "g"]

// flat传入一个整数参数,整数即扁平化的层数
test.flat(2)
// ["a", "b", "c", "d", "e", ["f"], "g"]

// Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
test.flat(Infinity)
// ["a", "b", "c", "d", "e", "f", "g"]

// 传入 <=0 的整数将返回原数组,不扁平化
test.flat(0)
test.flat(-1)
// ["a", ["b", "c"], ["d", ["e", ["f"]], "g"]]

// 如果原数组有空位,flat()方法会跳过空位。
["a", "b", "c", "d",,].flat()
// ["a", "b", "c", "d"]
  • reduce
function flattenDeep(arr) { 
    return Array.isArray(arr)
      ? arr.reduce( (acc, cur) => [...acc, ...flattenDeep(cur)] , [])
      : [arr]
}

// 测试
var test = ["a", ["b", "c"], ["d", ["e", ["f"]], "g"]]
flattenDeep(test)
// ["a", "b", "c", "d", "e", "f", "g"]
  •  栈
function flattenDeep(arr) {
  const result = [] 
  // 将数组元素拷贝至栈,直接赋值会改变原数组
  const stack = [...arr]
  // 如果栈不为空,则循环遍历
  while (stack.length !== 0) {
    const val = stack.pop() 
    if (Array.isArray(val)) {
      // 如果是数组再次入栈,并且展开了一层
      stack.push(...val) 
    } else {
      // 如果不是数组,就用头插法插入到结果数组中
      result.unshift(val)
    }
  }
  return result
}

// 测试
var test = ["a", ["b", "c"], ["d", ["e", ["f"]], "g"]]
flattenDeep(animals)
// ["a", "b", "c", "d", "e", "f", "g"]

问题:字符串去重

方法:Set

[...new Set('ababbc')].join('')
// "abc"

问题:转换为数组

方法:Array.from、展开符[...]

Array.from()可以转换伪数组对象(拥有一个 length 属性和若干索引属性的任意对象),与可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

使用展开符[...]

问题:将数组某个元素移动到最后

方法:arr.push(arr.splice(i, 1)[0]) 

           arr.push(...arr.splice(arr.findIndex(i => i === key), 1));

const moveToLast = (arr) => {
  let y = 0;//定义y用于控制循环结束
  for (let i = 0; y < arr.length; y++) {
    if (arr[i] === 0) arr.push(arr.splice(i, 1)[0]);//循环到是0的位置就删除该元素0并且在arr末尾push进这个元素0,由于splice删除了该位置元素,所以i不用+1,下次循环仍然检查i位置的元素
    else i++;//循环到不是0的位置就继续往后循环
  }
  return arr;//返回操作后的原数组
};
arr.push(...arr.splice(arr.findIndex(i => i === key), 1));

8.对象操作

问题:遍历对象

方法:for in、Object.keys、Object.getOwnPropertyNames(obj)

 问题:合并对象

方法:Object.assign(target, orgin)

const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

9.未分类 Part

上传图片

    // ant UI <a-upload>直接提供了上传form格式 
    // 注意按需要配置name action accept headers data 属性
    // 而vant UI插件不提供,可以使用new FormData(),自行添加form格式数据
    let data = new FormData();
    data.append("img",file.file);  //图片

    axios.post("/api/material/uploadMaterial", data,{
        headers: {'Content-Type': 'multipart/form-data'}
    }).then(res => {
        console.log(res.data);
    }).catch(err=>{
        console.log("失败");
    })

 下载图片

使用URL.createObjectURL(blob)创建出一个本地url

function funcDownload (content, filename) {
      // 创建隐藏的可下载链接
      var eleLink = document.createElement('a');
      eleLink.download = filename;
      eleLink.style.display = 'none';
      // 字符内容转变成blob地址
      var blob = new Blob([content]);
      eleLink.href = URL.createObjectURL(blob);
      // 触发点击
      document.body.appendChild(eleLink);
      eleLink.click();
      // 然后移除
      document.body.removeChild(eleLink);
}

NPM

  • 查看当前地址:

npm config get registry

  • 设置当前地址(设置为淘宝镜像)

npm config set registry http://registry.npm.taobao.org/

  • 设置当前地址(设置为默认地址)

npm config set registry https://registry.npmjs.org/

  • 每次执行命令前加入–registry指定仓库路径

npm --registry https://registry.npm.taobao.org install

简单手写JQuery

    class JQuery {
      constructor(selector) {
        let results = document.querySelectorAll(selector)
        for (let i = 0; i < results.length; i++) {
          this[i] = results[i]
        }
        this.length = results.length
        this.selector = selector
      }

      get(index) {
        return this[index]
      }

      each(fn) {
        for (let i = 0; i < this.length; i++) {
          fn(this[i])
        }
      }
    }
    // 扩展插件
    JQuery.prototype.dialog = function (info) {
      alert(info)
    }

    class MyJQuert extends JQuery {
      constructor(selector) {
        super(selector)
      }

      // 扩展方法
      add() { }
    }

前端基础体系

https://www.jianshu.com/p/3890418ab7cf

https://mm.edrawsoft.cn/template/81442

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值