美文网首页
2021-6面试

2021-6面试

作者: 焚心123 | 来源:发表于2021-08-04 08:06 被阅读0次

    vue

    • vue中v-if和v-for的优先级那个更高,应该怎么优化提升性能
      1、在vue2.x中v-for的优先级高
      2、可以将v-if写到v-for的外面,也可以将数据在computed计算属性中进行过滤,在循环计算方法就可以了
      3、在vue3.x中v-if的优先级更高

    • vue中data为什么必须是函数,而vue根实例是对象


      image.png

      1、组件中data要不是一个函数的话,那么会进行报错
      2、在多实例的时候,保护状态不被污染,干扰
      3、函数的话,可以让我们每次调用组件都会创建一个新的data实例
      4、要是对象的话,组件调用多次,改变一个,都会进行改变触发,导致状态会被污染,干扰
      5、根实例跟组件不一样,是单例,每次new vue只会创建一次

    • vue中key的作用和工作原理


      image.png

      1、key的作用主要是高效的更新虚拟dom,通过key可以精准的判断两个节点是否是同一个,要是没有加key的话,会认为是相同的,从而进行强制的更新,导致多做一个dom的更新,消耗性能
      2、不加的话,会触发一些隐蔽的bug,还有不加的话,会报错
      3、vue中使用相同标签名元素过渡切换的时候,也会使用到key的属性,目的就是为了让vue可以区分他们,否则vue只会替换内部属性,而不会触发过渡效果

    • 你怎么理解vue中的diff算法(需要看看课程中,对diff算法更深的理解)
      1、必要性,为了降低组件的watcher,一个组件一个watcher,所以要是用diff
      2、深度优先,同层比较(先从根找,有孩子往下找,有的话,继续,没有的话,同层比较,之后在看父节点的,另一边有没有子节点,有往下找,没有同层比较)

    • vue组件化的理解
      1、高内聚、低耦合,提升代码的健壮性
      2、有属性props,自定义事件,插槽等,用于组件通信,扩展等
      3、可复用性
      4、全局组件和局部组件

    • MVVM
      1、解决model和view耦合的问题
      2、model发生改变会自动更新view,减少dom操作,提高开发效率,可读性还保持了优越的性能表现

    • vue性能优化有哪些?
      1、路由懒加载
      2、keep-alive进行缓存页面
      3、v-show和v-if合理的使用
      4、大数据列表,使用虚拟滚动列表(vue-virtual-scroll,vue-virtual-scroll-list)
      5、有定时器的,组件页面销毁前进行清除
      6、图片的懒加载
      7、第三方UI组件库的按需引入
      8、将无状态的UI组件可以标记为函数式组件,在template标签上添加functional就可以了
      9、组件中的方法进行调用多次的时候,使用变量将方法进行保存,这样调用多次的时候,我们只用了这一次的方法

    • vue3.0的新特性了解
      1、更快:虚拟dom的重写,优化slots的生成,静态树的提升,静态属性的提升,proxy响应式系统
      2、更小:摇树优化
      3、更容易维护:ts+模块化
      4、composition Api

    • vuex的使用及其理解
      1、模块

      state mutations getters action modlues(namespace)

    • vue 组件之间的通信方式
      1、props
      2、emit/on
      3、children/parent
      4、provide/inject
      5、attr/listeners
      6、ref
      7、$root
      8、eventbus
      9、 vuex

      • vue-router保护路由的安全
        1、获取组件实例只有组件内守卫可以进行获取到,全局守卫,路由独享都是获取不到的


        image.png

        2、触发顺序


        image.png
    • vue响应式的理解
      1、通过数据响应式加上虚拟DOM和patch算法,可以使我们只需要操作数据就可以达到更新视图,完全不需要操作dom,从而大大提升开发效率,降低开发难度
      2、vue2中的数据响应式机制会根据类型来进行不同的处理,如果是对象的话,使用Obiect.defineProperty()的方式定义数据的拦截和响应,如果是数组的话,通过覆盖数组原型的方法,扩展他的7个变更方法,使这些方法额外的做更新通知,可以很好的解决了数据响应式的问题,但是也有一些缺点:比如初始化时递归 遍历时会造成性能损失,新增或者是删除属性时需要使用vue.set/delete这样的api才能生效,对于es6的新增map,,set结构不支持等问题
      3、为解决这些问题,vue3中利用es6的proxy机制代理响应化的数据,不在需要使用vue.set/delete等api,初始化性能和内存消耗都得到了大幅改善,另外将响应式的代码单独抽离为独立的reactivity包,可以让我们更加灵活的使用他,我们甚至不要要引入vue就可以进行体验

    • vue的双向数据绑定原理
      1、首先通过object.defineProperty()来设置和读取数据
      2、通过监听器Observe监听所有的属性,如果属性发生变化了,就需要告诉订阅者是否更新,因为订阅者有很多,此时我们需要Dep专门进行收集订阅者,然后对监听器Objserve和watcher之间进行统一的管理
      3、当watcher接收到相应的属性变化,就会进行更新对应的函数

    es6的语法总结

    • 深浅拷贝
      1、引用类型的数据直接赋值就是浅拷贝
      2、基本数据类型直接赋值是深拷贝
      3、使用Object.prototype.toString.call()可以检测到当前数据类型,适用于所有数据类型的检测,返回'[objec Object]','[objec Array]','[objec String]' 等
      4、也可以使用Object.getPrototypeOf()进行检测出当前的数据是对象还是数组
      5、使用Object.create(),创建出的对象或者是数组,都是将对方的属性,方法放到了原型上,没有这个属性可以直接从原型上获取,有的话就不会再使用原型中的属性值
      6、如果是对象的话,可以使用Object.assign()进行克隆,但是,当前的对象有多层,也就是说对象中还有对象或者是数组,那么里面的对象或者数组就是浅拷贝
      7、扩展运算符跟6是一样的,单层是深拷贝,多层嵌套就是浅拷贝了
      8、如果是数组的话,可以使用数组中的方法concat,slice等方法,也可以使用Object.assign(),扩展运算符,情况跟6一样

    • 函数的变量提升
      1、函数的变量提升优先于变量的提升

       function test(a,b){
          console.log(a);//function a(){}
          var a=10;
          function a(){}
          console.log(a);//10
          function c(){}
          console.log(b);//undefined
          var b=function b(){}
          console.log(b)//function b(){}
       }
       test(1);
       var a=121;
       console.log(a);//121
       /**
        * 函数的变量提升:
        *     1、函数的变量提升比变量的提升优先级高,在变量的前面
        *     2、找形参和变量,相同的只需要一个就可以了,值为undefined
        *         a:undefined   b:undefined
        *     3、将实参和形参统一
        *         a:1  b:没有传递实参,值为undefined
        *     4、在函数中找函数,将值赋值给函数体
        *         a:function a(){}  b:由于函数中的b是字面量函数,所以值还是undefined
        *     5、在函数的内部开始运行
        *         a:function a(){}----10
        *         b:undefined-----function b(){}
       */
    
          var a = 10 ;
          function a(){
              console.log(a);//function a(){}
              a=20;
              function a(){}
              console.log(a)//20
          }
          a();
          console.log(a)//10
    
          a = 20;
          var a = 10;
          console.log(a);//10  本来a是全局变量20,然后下面有声明了一下,a=10;所以最终输出为10
    
    • 字符串模板
      1、可以进行简单的运算
      2、比字符串拼接好使
     // todo 字符串模板的使用
        const a = 1;
    
        const b = 2;
    
        const c = `${a+b}`
    
        console.log(c);//3
    
        const d = 18;
    
        const e = `小明今年${d}岁`
    
        const f = '小明今年'+d+'岁'
    
        console.log(e);//小明今年18岁
    
        console.log(f);//小明今年18岁
    
    • 判断当前是否有这个字符串
     // 判断当前是否有这个字符串
    
        const str = '我现在正在练习es6';
    
        const str1 = '现在'
    
        const str2 = '我'
    
        const str3 = 'es6'
    
        if(str.indexOf(str1)>-1) console.log('indexOf有返回当前下标,没有返回-1---',str.indexOf(str1));//indexOf有返回当前下标,没有返回-1
    
        if(str.includes(str1)) console.log('includes有返回true,没有返回false---',str.includes(str1));//includes有返回true,没有返回false
    
        if(str.startsWith(str2)) console.log('startsWith头部有返回true,没有返回false---',str.startsWith(str2));//startsWith头部有返回true,没有返回false
    
        if(str.endsWith(str3)) console.log('endsWith尾部有返回true,没有返回false---',str.endsWith(str3));//endsWith尾部有返回true,没有返回false
    
    • 字符串重复多次的写法(复制字符串)
    // 字符串重复多次
            const str = '重复我10次'
            console.log(str.repeat(10));//重复我10次重复我10次重复我10次重复我10次重复我10次重复我10次重复我10次重复我10次重复我10次重复我10次
            let str1 = ''
            for (let i = 0; i < 10; i++) {
               str1+=str;
            }
            console.log(str1);
    
    • Array.from()
      1、可以将对象转化为数组
    // 使用Array.from(),将对象转化为数组
        const obj = {
            0:'key要是用数字',
            1:'必须有length这个属性,否则转化不了',
            length:2
        }
    

    2、可以将伪数组转化为数组
    3、可以将set,map,string等数据结构转化为数组
    4、第二个参数是一个回调函数,相当于数组的map方法,返回一个新的数组,将第一个参数中的数据进行处理

    • Array.of
      1、这个方法不管你是什么数据和类型,都会创建一个新的数组
      2、当我们使用new Array(10);进行声明的时候,这个时候数组的长度是10,在进行传递参数的时候,就会产生一些问题
        const arr = new Array(10);
    
        console.log(arr);//[empty × 10]
    
        arr.push(20);
    
        console.log(arr);//[empty × 10, 20]
    

    3、此时代码中的数组长度就是11了,在添加的时候,前面都是10个空的
    4、而我们使用Aarray.of就可以解决上面的问题了

       const arr = Array.of(10);
    
        console.log(arr);//[10]
    
        arr.push(20);
    
        console.log(arr);//[10, 20]
    
    • Array.fill()填充
     let arr =[1,2,4,5,6,7];
    
         arr.fill(10);//一个参数默认将数组中的数据全部改变为10
    
        //第一个参数是填充的参数,第二个参数是填充的位置,第三个下标是填充的个数,从下标0开始算起
        //  只能是数组内的长度,不能超过数组内的下标或者是长度,
         arr.fill('3',0,1);//["3", 2, 4, 5, 6, 7]
    
         arr.fill('3',1,2);//----[1, "3", 4, 5, 6, 7]
    
         arr.fill('3',1,4);//---- [1, "3", "3", "3", 6, 7],第三个参数是4个但是从下标1开始填充,又是从0开始计算
    
        console.log(arr);
    
    • 判断对象或者是数组中是否有某个值
      1、对象中的检测某个属性使用in或者是object.hasOwnProperty()都可以检测,但是in是从对象的原型和原型链上查找,不太推荐使用
     let obj = {
            id:1,
            title:'1111'
        }
    
        console.log('id' in obj);
    
        console.log(obj.hasOwnProperty('id'));
    
        let arr =[1,2,4,5,6,7];
    
        console.log( 1 in arr);
    
        console.log(arr.indexOf(1)>-1);
    
        console.log(arr.includes(1));
    
        const index = arr.findIndex(item=>item===1)
        console.log(index!==-1)
    
        ....
    
    • object.is()对象比较
     let obj = {id:1,title:'1111'};
    
        let obj2 = {id:1,title:'2222'};
    
        console.log(obj.id === obj2.id);//true
    
        console.log(Object.is(obj.id,obj2.id));//true
    
    • objec.is和===区别
      1、===为同值相等,is()为严格相等
    console.log(+0 === -0);  //true
    console.log(NaN === NaN ); //false
    console.log(Object.is(+0,-0)); //false
    console.log(Object.is(NaN,NaN)); //true
    
    • reduce简单的计算及数组去重
        //reduce 简单的计算,第一个参数是我们传递的初始值,莫有的话,默认是数组的第一个数
        //reduce 第二个参数是数组中的每一项
        //reduce 第三个参数是数组本身
    
     let arr = [1,1,1,1,2,2,3,4,5,5,6,7,8,9];
        // 计算出现的次数
        let arr1 = arr.reduce((pre,next)=>{
            if(next in pre){//可以将in替换为hasOwnProperty()
                pre[next]+=1;
            }else{
                pre[next] = 1;
            }
            return pre
        },{})
        console.log(arr1);//返回的是对象
        arr1.length = 10;//给当前的对象添加一个length属性,可以转化为数组
        console.log(Array.from(arr1));
    
        // 数组去重
        let arr = [1,1,1,1,2,2,3,4,5,5,6,7,8,9];
    
        // 使用双循环进行判断,当前的数值跟下一个数值进行比较,是否相同,相同的话进行去重
        for (let i = 0; i < arr.length; i++) {
           
            for (let j = i+1; j < arr.length; j++) {
               
                if(arr[i]===arr[j]){
                    arr.splice(i,1);
                    i--;
                    j--;
                }
                
            }
            
        }
        console.log(arr);
    
        const arr1 = [...new Set(arr)];//使用new Set 进行去重
    
        console.log(arr1);
    
        let arr2 = arr.reduce((pre,next)=>{
            // if(!pre.includes(next)){//当数组中没有这个值的时候进行添加就好
            //     pre.push(next);
            // }
            // indexOf()有的话返回下标,没有的话返回-1,所以没有的时候进行添加
            if(pre.indexOf(next)===-1){
                pre.push(next);
            }
            return pre;
        },[])
    
        console.log(arr2);
    
        // 简单的计算数组中的和
        let arr = [1,2,3,4,5,6,7];
        let s = arr.reduce((pre,next)=>{
            return pre + next
        },0)
    
        console.log(s);
    
    
    • new Proxy()简单的代理
     let obj = {
            id:1,
            title:'练习proxy代理'
        }
    
        let obj2 = new Proxy(obj,{
    
            get(target,key){
                console.log(`你正在读取obj中的${key}属性`);
                // return target[key];//必须要有返回值
                return Reflect.get(target,key);//一般我们推荐使用这种映射的方式进行返回
            },
    
            set(target,key,val){
                console.log(`你正在对obj的${key}进行设置`);
                // target[key] = val;
                // return target[key];
                return Reflect.set(target,key,val);
            },
    
            has(target,key){
                console.log(`obj中是否有这个${key}属性`);
                return Reflect.has(target,key);
            },
            ownKeys(target){
    
                return Reflect.ownKeys(target);
            },
        })
    
        console.log(obj2.id);
        obj2.name = '张三';
        obj2.id = 333;//设置属性
        console.log(obj2.name);
        console.log(obj2.id);//获取属性
    
        console.log('id' in obj2);//这种方法进行调用has方法
    
       console.log(Object.keys(obj2))//返回所有属性
    
    
    • web安全攻击手段有哪些?
      1、XSS跨站脚本攻击

      • 定义:就是攻击者可以在我们的网站中嵌入恶意脚本,在进行分享出去,当用户进行浏览的时候,会被攻击或者是泄漏隐私
    • 解决办法:设置httpOnly,防止获取我们的cookie信息。可以将我们页面中的input框等可输入的进行代码,特殊符号的转义,还有就是长度进行限制
      2、CSRF跨站请求伪造

    • 定义:就是我们使用localhost:3000进行访问,攻击者可以在localhost:3000进行访问我们的数据及恶意的攻击

    • 解决办法:使用token进行验证。http头中自定义属性进行验证

    • TCP的三次连接

    • 直接举例说明

    • 小明——客户端,小红——服务端
      1、小明给小红打电话,接通了之后,小明说喂,能听到吗,这就是相当于连接建立了
      2、小红给小明回应,能听到,你能听到我说话吗,这就相当于是请求响应
      3、小明听到小红的回应后,好的,这相当于是连接确认,在这之后小明和小红就可以通话/交换信息了

    • TCP的四次挥手

    • 直接举例说明
      1、小明对小红说,我所有的东西说完了,我要挂电话了
      2、小红说,收到,我这边还有一些东西没说
      3、经过若干秒后,小红也说完了,小红说,我说完了,现在可以挂断了
      4、小明收到消息后,又等了若干时间后,挂断了电话

    • 地址栏输入URL发生了什么

    • 首先输入URL之后,去查找域名是否被本地DNS缓存,解析域名,tcp的连接(三次握手,四次挥手),请求服务器,服务器响应,HTML进行重绘和回流,渲染页面

    template 和 JSX的区别

    • 首先他们两个都是render的一种表现形式,最终都会编译成render进行渲染
    • template更加符合我们的视图,结构分离
    • JSX相对于template更加的灵活

    SPA单页面的优缺点

    • 优点:
      1、用户体验好
      2、快
      3、内容的改变不用重新加载整个页面,避免了不必要的跳转到渲染
    • 缺点:
      1、首屏加载慢(loading进行解决/骨架屏)
      2、对seo不友好

    Vue中的data中某一个属性值发生改变,视图会立即更新渲染吗?

    • 不会立即同步更新渲染
    • vue在更新dom的时候是异步执行的,只要侦听到数据的变化,vue将开启一个队列,并缓冲在同一个事件循环中发生的所有数据的变更
    • 如果同一个watcher被多次进行触发,只会被推入到队列中一次。(这种在缓冲时去除重复的数据对于避免不重要的计算和dom操作是非常重要的)
    • 然后在下一次的事件循环tick中,vue刷新队列并执行实际的工作(已经进行去重的数据)

    vue中的watch,computed和methods的区别

    • 首先methods没有缓存,只要调用就会进行触发
    • computed 有缓存,只有里面的数据发生了改变,才会进行更新,不支持异步,只支持data,props
    • watch没有缓存,支持异步的数据,只要数据发生变化就会触发,有两个参数新老值

    如何减少重绘和回流

    • 重绘:就是页面的颜色啥的进行改变,不会影响页面的布局
    • 回流:就是页面的布局发生改变,需要重新进行计算和渲染
    • 使用transfrom替代top等
    • 使用visibility替换display:none;(因为前者只会引起重绘,后者会触发回流)

    url输入到渲染的过程?

    • url解析(是否是合法的http)
    • DNS查询(将http解析为ip地址)
    • tcp链接(三次挥手,4次握手)
    • 向服务器发送请求
    • 服务器响应
    • 页面进行渲染:
      1、解析html,构建dom树
      2、解析css,生成css树
      3、计算html,css元素的尺寸,位置
      4、进行绘制

    rsa加密是非对称加密

    • 非对称加密:就是需要我们知道公钥和私钥,然后通过算法进行加密
    • 对称加密:就是我们只知道公钥,私钥是我们请求的时候进行传递过来的,但是要是被劫持了,那么就会有泄露的风险
    • 总结:一般都是使用非对称加密,安全

    文件的大小

    • 文件的大小我们可以通过file文件中的属性size进行指导,在通过slice进行截取切割,
    • 也可以进行判断文件的大小
    • 要是文件要判断是不是png图片,使用二进制流读取文件前六位,每个文件都是不同的

    Vue组件模板会在某些情况下受到HTML的限制,如在table表格中使用组件是无效的,常见的还有在ul,ol,select中使用组件也是会被限制的

    • 我们为了解决在table表格标签中写上我们的组件,使用is属性来进行挂载
    • 我们也可以使用is这个属性,进行动态的渲染组件,写一个公共的部分,通过绑定is来实现不同的地方进行渲染组件
    <table><thead is="组件名"></thead></table>
    

    插槽

    • 默认插槽:
      1、就是在组件中可以进行写入一些标签,可以在组建的内部进行渲染
      2、直接在组件的内部使用<slot></slot>就可以了

    • 具名插槽:
      1、就是我们要在不同的地方,显示不同数据,这个时候就要显示了
      2、使用name在slot标签上进行起不同的名字
      3、在使用组件插槽的时候,在标签上显示不同的名字就行slot='名字'

    • 作用域插槽:
      1、就是子组件传递数据给父组件,然后在子组件中进行显示
      2、在子组件的slot标签上动态的绑定我们需要的数据,或者是静态的传递
      3、在父组件的子组件标签中使用template标签进行渲染,在template标签上使用v-slot=“随便起一个名字(aa)”,在里面就是aa.传递过来的数据就可以了

    • this.$slot.default 是获取默认的插槽数据

    • this.$slot.head 获取头部slot的数据

    vue3.0的语法的一些总结

    vue2.0 ======================= vue3.0

    beforeCreatec ================ setup

    created ====================== setup

    beforeMount ================== onBeforeMount

    mounted ====================== onMounted

    beforeUpdate ================= onBeforeUpdate

    updated ====================== onUpdated

    beoreDestory ================= onBeforeUnmount

    destory ====================== onUmmounted

    flex弹性盒模型布局

    • display:flex; //申明弹性盒模型,默认水平排列
    • flex-direction:row | row-reverse | column | column-reverse //排列的方向,水平,水平倒序, 垂直, 垂直倒序
    • flex-wrap; nowrap | wrap | wrap-reverse //默认不换行, 换行, 换行倒序
    • flex-flow: <flex-direction> || <flex-wrap> //这是排列和换行的简写 row nowrap 默认水平不换行
    • justify-content: flex-start | flex-end | center | space-between | space-around //水平的对齐方式,头部(左边)对齐,尾部(右边)对齐 中间 两端 均匀对齐
    • align-item: flex-start | flex-end | center | baseline | stretch //垂直对齐方式, 顶部(上) 尾部 (下) 中间 文字对齐 上下占满空间(没有设置高度或auto,占满上下空间)
    • align-content: flex-start | flex-end | center | space-between | space-around | stretch ///这个属性是对多个盒子进行垂直对齐的方式
    • order: 1 - 9999999 //数值越小,排列顺序越往前
    • flex-grow:0-1 //填充,默认是0,有剩余空间,也不放大
    • flex-shrink: 1 // 缩放默认为1,空间不足,可以进行缩小,如果其他都是1,当前为0,其他进行缩小,当前不变
    • flex-basis: auto //默认auto 本来的大小, 分配多余空间之前占据的大小
    • flex: <flex-grow> || <flex-shrink> || <flex-basis> //三者简写

    箭头函数和普通函数的区别

    1、写法不同,箭头函数使用()=>{} ,普通函数使用function(){}
    2、箭头函数都是匿名函数,普通函数可以是匿名函数也可以是命名函数
    3、箭头函数不能使用构造函数,使用new进行声明
    4、箭头函数本身是没有this的,声明时可以捕获上下文的this供自己使用,普通函数的this总是指向调用它的对象
    5、箭头函数没有arguments对象,普通函数有
    6、箭头函数的this永远指向其上下文的this,任何方法都改变不了它的指向,如call,apply,bind都不行
    

    vue和react的相同点和不同点

    • 相同点
      1、使用虚拟dom
      2、都是响应式数据和组件化
    • 不同点
      1、vue是双向数据绑定
      2、react 是单向数据流
      3、vue内置dalailng

    原生的上拉加载和下拉刷新

    • 上拉加载
      image.png
    • 看到上面的图片,大致的意思就是scrollTop+clientHeight >= scrollHeight-触底的距离
    let clientHeight  = document.documentElement.clientHeight; //浏览器高度
    let scrollHeight = document.body.scrollHeight;
    let scrollTop = document.documentElement.scrollTop;
     
    let distance = 50;  //距离视窗还用50的时候,开始触发;
    
    if ((scrollTop + clientHeight) >= (scrollHeight - distance)) {
        console.log("开始加载数据");
    }
    
    • 下拉刷新
    • 首先要经历3个过程,touchstart,touchmove,touchend,确定用户开始触发时候的y轴距离,移动的距离-开始的距离,结束的时候,在进行请求或者是做一些其他的操作
    <main>
        <p class="refreshText"></p>
        <ul id="refreshContainer">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
            <li>555</li>
            ...
        </ul>
    </main>
    
    • touchstart
    var _element = document.getElementById('refreshContainer'),
        _refreshText = document.querySelector('.refreshText'),
        _startPos = 0,  // 初始的值
        _transitionHeight = 0; // 移动的距离
    
    _element.addEventListener('touchstart', function(e) {
        _startPos = e.touches[0].pageY; // 记录初始位置
        _element.style.position = 'relative';
        _element.style.transition = 'transform 0s';
    }, false);
    
    • touchmove
    _element.addEventListener('touchmove', function(e) {
        // e.touches[0].pageY 当前位置
        _transitionHeight = e.touches[0].pageY - _startPos; // 记录差值
    
        if (_transitionHeight > 0 && _transitionHeight < 60) { 
            _refreshText.innerText = '下拉刷新'; 
            _element.style.transform = 'translateY('+_transitionHeight+'px)';
    
            if (_transitionHeight > 55) {
                _refreshText.innerText = '释放更新';
            }
        }                
    }, false);
    
    • touchend
    _element.addEventListener('touchend', function(e) {
        _element.style.transition = 'transform 0.5s ease 1s';
        _element.style.transform = 'translateY(0px)';
        _refreshText.innerText = '更新中...';
        // todo...
    
    }, false);
    
    • vue中父组件监听子组件的生命周期
    • 方法一
    // Parent.vue
    <Child @mounted="doSomething"/>
    // Child.vue
    mounted() {
      this.$emit("mounted");
    }
    
    • 方法二
    
    //  Parent.vue
    <Child @hook:mounted="doSomething" ></Child>
    doSomething() {
       console.log('父组件监听到 mounted 钩子函数 ...');
    },
    //  Child.vue
    mounted(){
       console.log('子组件触发 mounted 钩子函数 ...');
    },     
    // 以上输出顺序为:
    // 子组件触发 mounted 钩子函数 ...
    // 父组件监听到 mounted 钩子函数 ...
    
    • 可以在mounted中监听到beforeDistory生命周期进行清除定时器
    • 参考链接https://blog.csdn.net/T_shiyi/article/details/108668263
    • 重绘和回流
    • 重绘:一般页面中的背景,颜色等变化
    • 回流:页面的宽度,高度等发生变化,需要进行重新计算,渲染
    • 如何减少回流:
      1、用translate替代top改变
      2、使用opacity代替visibility
      3、不要使用table布局,一个小的改动都需要进行重新计算渲染
    • this的指向问题
    • 关于这个this的指向问题,要靠自己的理解,不用死记硬背,但是要多注意看题

    相关文章

      网友评论

          本文标题:2021-6面试

          本文链接:https://www.haomeiwen.com/subject/shryeltx.html