工作问题总结

每天解决一个问题,也会使自己进步一小步.

  1. 用新变量接收对象的时候是指针复制,当原对象的内容改变的时候新变量的指向虽然没变但是值已经变了,会导致值得错误。
    解决办法: 深拷贝
    具体代码:

    1
    JSON.parse(JSON.stringify(object))
  2. 如何检测vueRouter的参数变化?
    解决办法: 1.用watch监听$route对象

    2.使用beforeRouterUpdate(导航卫士),表示路由正在发生变化。

    具体代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 方法一
    watch:{
    $route(to, from){
    this.newPath = to
    this.newParams = this.$route.query.oldValue
    }
    }

    // 方法二 此方法知能监听路由路径
    // to: Route: 即将要进入的目标 路由对象
    // from: Route: 当前导航正要离开的路由
    // next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    beforeRouterUpdate(to, from, next){
    this.newPath = to
    }
  3. 关于img的src路径问题:获取到的路径是绝对路径直接填入了img的src中,控制台报错,不允许直接读取本地文件。
    问题原因:前端不能通过浏览器直接访问硬盘上的文件,这样会有安全问题。
    引申概念: file协议:读取本地文件用到的协议,对标http(s),http是加载网路资源用到的,速度慢。file协议是加载本地文件用到的速度快。

  4. 数组的:indexOf、includes、find、findIndex、lastIndexOf。这几个知道是干什么用的但是返回值又忘了,加深记忆一下。
    返回值区别: indexOf 存在返回下标,不存在返回-1

    includes 包含返回true,不包含返回false
    find 返回满足填入函数的第一个值,否则返回false
    findIndex 返回满足填入函数的第一个值的下标,否则返回-1
    lastIndexOf 返
    回指定元素在数组中的最后一个的位置。不存在则返回-1。(查找顺序从后向前查找,但是下标还是从头开始算起)
  5. BEM,Block(块)、Element(元素)、Modifier(修饰符)
    BEM命名规范:

    - : 中划线。仅作为连字符使用,表示某个块或者元素之间多个单词的连接记号
    __ : 双下划线。用来连接块和块的子元素
    _ : 单下划线。用来描述一个块或者块的子元素的一种状态。 

    例: .block__element–midifier

  6. 如何获取到Object的key
    API: Object.keys() 。返回的是由key组成的一个数组。

    1
    Object.keys(obj) // obj要被枚举自身属性的对象
  7. vue里的mixin(混入)功能经常导致变量赋值的位置不好确定。

  8. for…in 和 for…of的区别:
    for…in是ES5的语法,遍历对象属性的时候,使用。
    for…of是ES6的语法,遍历数组时候使用。不能循环普通的对象。

    for of 只能遍历可迭代的可迭代属性,不可迭代的属性被忽略了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Object.prototype.objCustom = function () {};
    Array.prototype.arrCustom = function () {};
    let iterable = [3, 5, 7];
    iterable.foo = "hello";
    for (let i in iterable) {
    console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
    }
    for (let i of iterable) {
    console.log(i); // logs 3, 5, 7
    }
  9. URL编码解码:

    • encodeURI:除了空格其他字符不做转译,空格转译成%20
      decodeURI:翻译encodeURI转译后的字符串
    • encodeURIComponent:除了字母数字以外的全部转译
      decodeURIComponent:翻译encodeURIComponent的字符
  10. 函数的length属性是形参的个数,内部arguments的length是实参(实际调用时候传参的个数)

    1
    2
    3
    4
    5
    function a(a,b,c){
    return arguments.length
    }
    console.log(a.length) // 3 因为有三个形参
    console.log(a(1,2)) // 2 因为有两个实参
  11. 判断函数是不是通过new 创建的。
    通过ES6的元属性(new.target)来判断。元属性指的是非对象的属性。
    当调用函数的Construct方法时,new.target被赋为new操作的目标,通常是新创建的对象实例。也就是函数体内部的this。
    如果调用Call方法,则new.target的值为undefined。
    代码:

    1
    2
    3
    4
    5
    6
    7
    function Person(name) {
    if(typeOf new.target === Person){
    this.name = name
    } else {
    console.log('不是通过new调用的')
    }
    }
  12. Unexpected side effect in “xxx” computed property
    原因:在computed里改变了data里的属性
    解决办法:在computed里新建一个变量,操作新建的变量。

  13. ES6深拷贝数组:
    代码:

    1
    2
    let array = [1,2,3,4,5]
    let [...newArray] = array // 此时的newArray就是深拷贝
  14. vue里的computed(计算属性)里不能调用异步方法

  15. 箭头函数
    特性:没new.target属性,不能当构造函数,this指向外部调用者,没有construct属性,没有argument对象。

  16. 尾调用优化条件:

    • 不调用栈帧(stack frame)里的局部变量
    • 函数调用是否在尾部发生
    • 最后retrun的是否是函数
      能优化的点:
      递归函数
  17. vue 子组件更新父组件的值,emit和sync

    1
    2
    3
    4
    // 子组件内,想要修改父组件内自己的显隐
    this.$emit('update:visible',false)
    // 父组件内的子组件生命的属性里 ,最终结果dialogVisible为false
    :visible.sync = 'dialongVisible'
  18. 响应式原理——对象部分。在methods尝试给data里的一个对象添加新的属性,然后发现watch监听不到变化
    原因:看了一下文档的’深入响应式原理’关于对象的部分。主要是因为vue无法监听property的添加或者移除,vue只会在初始化实例的时候对property执行setting和getting,所以property只有在data上存在才是响应式的。
    解决办法:

    1. 提前在data的对象中声明这个属性,给个默认值。
    2. 使用Set方法:
      1
      this.$Set(this.object, newKey, value)
  19. 响应式原理补充——数组部分
    无法检测的操作:

    • 根据下标直接设置项
    • 设置数组长度
      1
      2
      3
      4
      5
      6
      7
      8
      //引用官网例子
      var vm = new Vue({
      data: {
      items: ['a', 'b', 'c']
      }
      })
      vm.items[1] = 'x' // 不是响应性的
      vm.items.length = 2 // 不是响应性的

    解决办法:

    1. 还是set:
      this.$Set(this.array, index,newValue)
    2. splice方法
      this.array.splice(index, 1,newValue) 修改值
      this.array.splice(newLength) 修改长度
  20. 对象的深拷贝:
    方法: Object.assign(target,…source).
    注意点:属性限定简单类型。同名的属性会被覆盖(调用target的set和source的get)。

  21. box-sizing: 设置宽高是否包含border和padding
    属性:

    1. content-box:width和hight的属性只是content的部分,padding和border的单独算
    2. border-box:width和hight是content+padding+border的值。
  22. margin和span标签:今天遇到的是想给span标签添加marign-bottom没生效。
    原因:span标签是行内元素,

    - 直接设置margin-bottom和margin-top不生效。
    - margin-left和margin-right生效。

    解决办法:

    对应的css属性内加入 'display:block',之后top和bottom就会生效。
  23. 元素居中解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    flex布局
    #XXX{
    display:flex;
    justify-content:center;
    }
    IE8-9
    #XXX{
    margin:0 auto;
    }

    以上属性全部设置到父元素上
  24. 在watch中函数定义不能使用箭头函数.

  25. 用watch监听变量做到在mounted时候就能监听变化,需要加上immediate属性。

  26. 需要从后面匹配路径包含固定格式和固定单词

    1
    2
    // 用到的符号 *匹配零次或者多次、  | 或者、 符号转译需要在前面加 \、 匹配固定单词用\b 
    let regExp = /\/(a-z)*+\.(a-z)+\/(\bxxnnn\b|\bsss\b)$/ // /xx.xx/xxnnn or /xx.xx/sss
  27. 正则表达式有效率问题,写完表达式注意测试用时。

  28. 文字过长处理方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // html 部分
    <span class="demo">1111<span>

    // css 部分
    .demo {
    display: inline-block;
    width: 100px
    white-space: nowrap; // 不让文字换行
    overflow: hidden; // 过长部分的处理方式
    text-overflow: ellipsis; // 如何处理溢出部分
    }
    // 多行文字情况
    .demo {
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: 2; // 文字行数
    -webkit-box-orient: vertical;
    }
  29. 复习:v-if更高的切换开销,v-show更高的初始化渲染开销。 v-if是惰性的,初始化条件为假的时候则什么也不做直到条件变为真,才会渲染条件块。

  30. v-html使用注意点

    1. <div v-html="html"></div>
    2. 等同于js原生的element.innerHTML()方法,可以插入html标签
    3. 不再用户能输入的地方使用,方式xss攻击(注入脚本)
    4. 组件内scope的样式,在v-html中不会生效因为没内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。
  31. result | 0 超过32位的整数转换结果不等于自身,可用作溢出判断

  32. parseInt() 字符串转换数字。leetcode刷题用到的 字符串里有数字和字母。用这个提取数字。具体用法查询mdn的API。

  33. 给变量设置默认值写法

    1
    let variableA = variableB || ''  // 变量variableB隐形转换为false时,赋给variableA默认值为空字符串
  34. 小优化点:当用for查找某个条件时:查找到直接使用break跳出。减少循环次数。

  35. request method: options (个人理解:预请求)
    意义:在浏览器的某些请求中,在正式通讯之前会增加一次HTTP查询请求,称为”预检”请求。通过这个方法客户端可以决定对该资源采取何种措施,或者了解服务器性能。只有得到肯定答复浏览器才会发送正式的请求。

  36. $refs只会在模板渲染完成后才生效且不是响应式的。应该避免在模板和计算属性中访问$refs

  37. 封装组件时,对功能有局限性的数据或者逻辑应该交给父组件传入或者处理,这样以后封装出来的组件更加的通用且好扩展。

  38. 时间相关的API: moment.js

  39. Object.keys(obj) 返回obj的key组成的数组。

  40. 原型链:每个实例对象都有一个私有属性proto,他指向他的构造函数的原型对象(prototype),该原型也有自己的proto,层层向上指直到null,null是原型链的最后一环。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function f(){
    this.a = 1
    this.b = 2
    }
    let o = new f()
    // 在f函数的原型上定义属性
    f.prototype.b = 3
    f.prototype.c = 4
    //整个原型链如下:
    // {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null

    console.log(o.a); // 1
    // a是o的自身属性吗?是的,该属性的值为 1

    console.log(o.b); // 2
    // b是o的自身属性吗?是的,该属性的值为 2
    // 原型上也有一个'b'属性,但是它不会被访问到。
    // 这种情况被称为"属性遮蔽 (property shadowing)"

    console.log(o.c); // 4
    // c是o的自身属性吗?不是,那看看它的原型上有没有
    // c是o.[[Prototype]]的属性吗?是的,该属性的值为 4
    console.log(o.d); // undefined
    // d 是 o 的自身属性吗?不是,那看看它的原型上有没有
    // d 是 o.[[Prototype]] 的属性吗?不是,那看看它的原型上有没有
    // o.[[Prototype]].[[Prototype]] 为 null,停止搜索
    // 找不到 d 属性,返回 undefined
  41. 获取数组中数字的最大最小值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let array = [1,2,3,4,5,6,7]
    function maxNumber(arr){
    return Math.max.apply(null, arr)
    }
    function minNumber(arr){
    return Math.min.apply(null, arr)
    }
    maxNumber(array)
    minNumber(array)
  42. 最近开始接触适配不同分辨率的情况。使用媒体查询分别设置不同情况的样式。

    1
    2
    3
    @media screen and(min-width: 1366px) and (max-width: 1920px){
    // style
    }
  43. clip-path 和 box-shadow 连用不会有阴影。

  44. 终端里的一些指令

    1
    2
    3
    4
    5
    6
    ls // 路径内列表
    cd xxx // 进入某个目录
    touch file // 建立一个新文件
    vim file // 编辑一个文件
    :wq // 在编辑界面内使用,保存并退出
    rm xxx // 删除名字是xxx的文件
1
git config --list // 查看当前文件夹的git配置
  1. a标签嵌套a标签会解析错误
  2. a标签上 target 的几个属性值: tab、 window、iframe,_self: 当前页面加载、_blank: 新窗口打开
  3. ul li 前的点的样式控制 list-style 属性控制, 和overflow:hidden 属性配合可能会导致点消失,可以配合list-style-position: inside; 来解决
  4. 可替换元素: 它们的内容不受当前文档的样式的影响。CSS 可以影响可替换元素的位置,但不会影响到可替换元素自身的内容。(img iframe video)
  5. object-fit: 可以指定可替换元素的内容如何适应到其容器的宽和高。
    none: 原有尺寸
    contain: 保持长宽比,填充容器
    fill: 拉伸填充
    cover: 裁剪填充
    scale-down: 缩放
  6. span之间没有样式控制却有个间隙?
    原因: 是span之间的回车符被解析成了空格
  7. 几个坐标的起始位置:
    clientX: 相对于窗口左上角的距离
    offsetX: 触发元素的左上角的距离
    pageX:   相对于整个页面左上角的高度(包含在视窗内的元素以及不在视窗内的元素,滚动条。。)
  8. node-sass版本要和node版本对应,要不会出BUG。
  9. vue-router相关:
    • npm安装之后新建router文件夹、以及内部index.js,在这里配置路由。
    • vue-router配置命名路由时,VueRouter对象里的是 routes 。写成routers不生效。
    • 在main.js里引入index.js文件以及 Vue.use(VueRouter)
    • 在页面中直接 this.$router 使用

感谢您的阅读。 🙏