面试题总结

214 阅读3分钟

前端菜鸟写的不对的地方大家包涵

vue的双向绑定原理

vue通过数据的劫持结合发布者-订阅者模式方式,通过Object.defineProperty()方法劫持各个属性的getter和setter,在数据发生变化时发布给订阅者去触发响应的监听回调。

vue中使用的什么方法可以改变对象中的属性(data中的对象)从而渲染

this.$set("修改的对象key","值");

vue中watch和computed的区别

**计算属性computed**:1:支持缓存,computed属性值会默认走缓存,只有依赖数据发生变化才会重新计算。浏览器刷新,不会重新走里面计算的放法只会默认上次计算后的数据。2:不支持异步,当computed内有异步操作时无效,无法监听数据的变化。3:如果属性是有其他属性计算得来一般用computed,必须return出去而这个值就是我们需要计算的值。
**监听属性watch**:1:不支持缓存,数据变直接会触发相应的操作。2:支持写异步。3:监听数据必须是data中声明过或者父组件传递过来的props中的数据或者computed计算的属性,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

vue中组件的缓存

<keep-alive>是vue内置的组件,能在组件切换过程中将状态保存在内存中,防止重复渲染DOM。
<keep-alive>包裹动态组件时会缓存不活动的组件实例,而不是销毁它们。
include: 字符串或正则表达式。只有匹配的组件会被缓存。
exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
利用include、exclude属性
    <keep-alive include="test-keep-alive">
            <!-- 将缓存name为test-keep-alive的组件 -->
            <component></component>
            </keep-alive>

            <keep-alive include="a,b">
            <!-- 将缓存name为a或者b的组件,结合动态组件使用 -->
            <component :is="view"></component>
            </keep-alive>

            <!-- 使用正则表达式,需使用v-bind -->
            <keep-alive :include="/a|b/">
            <component :is="view"></component>
            </keep-alive>

            <!-- 动态判断 -->
            <keep-alive :include="includedComponents">
            <router-view></router-view>
            </keep-alive>

            <keep-alive exclude="test-keep-alive">
            <!-- 将不缓存name为test-keep-alive的组件 -->
            <component></component>
        </keep-alive>
利用meta属性
    export default[
         {
          path:'/',
          name:'home',
          components:Home,
          meta:{
            keepAlive:true //需要被缓存的组件
         },
         {
          path:'/book',
          name:'book',
          components:Book,
          meta:{
             keepAlive:false //不需要被缓存的组件
         } 
    ]
    <keep-alive>
      <router-view v-if="this.$route.meat.keepAlive"></router-view>
      <!--这里是会被缓存的组件-->
    </keep-alive>
    <keep-alive v-if="!this.$router.meta.keepAlive"></keep-alive>
    <!--这里是不会被缓存的组件-->

es6中promise与 async和await的区别

promise中处理多个异步的时候其中某一个出现报错择下面的代码将不再执行
async中处理多个await的时候其中某一个出现报错后面的会继续执行不受影响

async中处理多个await
promise出现链式的时候用async和await处理会比promise处理后方便直观
    /**
     * 传入参数 n,表示这个函数执行的时间(毫秒)
     * 执行的结果是 n + 200,这个值将用于下一步骤
     */
    function takeLongTime(n) {
        return new Promise(resolve => {
            setTimeout(() => resolve(n + 200), n);
        });
    }
    
    function step1(n) {
        console.log(`step1 with ${n}`);
        return takeLongTime(n);
    }
    
    function step2(n) {
        console.log(`step2 with ${n}`);
        return takeLongTime(n);
    }
    
    function step3(n) {
        console.log(`step3 with ${n}`);
        return takeLongTime(n);
    }
    
现在用 Promise 方式:
    function do() {
        console.time("do");
        const time1 = 300;
        step1(time1)
            .then(time2 => step2(time2))
            .then(time3 => step3(time3))
            .then(result => {
                console.log(`result is ${result}`);
                console.timeEnd("do");
            });
    }
    
    do();
    
    // c:\var\test>node --harmony_async_await .
    // step1 with 300
    // step2 with 500
    // step3 with 700
    // result is 900
    // do: 1507.251ms
输出结果 result 是 step3() 的参数 700 + 200 = 900。do() 顺序执行了三个步骤,一共用了 300 + 500 + 700 = 1500 毫秒,和 console.time()/console.timeEnd() 计算的结果一致。
用 async/await 的方式:
    async function do() {
        console.time("do");
        const time1 = 300;
        const time2 = await step1(time1);
        const time3 = await step2(time2);
        const result = await step3(time3);
        console.log(`result is ${result}`);
        console.timeEnd("do");
    }
    
    do();

vue首屏加载过慢的解决办法

vue-router懒加载

vue-router懒加载也就是路由的按需加载,只有当路由被访问时才会加载对应的组件
    {
        path: "home",
        redirect: "home",
        name: "home",
        //vue异步组件实现路由懒加载
        component:resolve=>(['组件的路径',resolve])
        //es提出的import(推荐使用这种方式)
        component: () => import('组件的路径'),
    },

使用CDN加速

项目中我们会用到许多第三方库,采用CDN加载可以加快速度。具体可以参考 CDN首屏加载

gzip压缩

这里我就说一个Nginx反向代理,配置nginx.conf文件,在http节点下在如下代码
    gzip on;
    gzip_static on;
    gzip_buffers 4 16k;
    gzip_comp_level 5;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    
vue-cli中我们可以使用插件compression-webpack-plugin开启打包压缩

服务端渲染

vue中nextTick的使用简单说一下

$nextTick是在下次DOM更新循环结算书之后执行延迟回调,在修改数据之后使用$nextTick,则可以在回调中获取更新后的DOM,也就是说你可以在这个回调函数中操作DOM。一般该函数用在生命周期的created中使用。

vuex中刷新页面数据丢失怎么处理

将vuex中的数据保存在浏览器缓存中(sessionStorage,localStorage,cookie)
localStorage -- 是永久存储在本地,除非你主动去删除,浏览器关闭也会存在;
sessionStorage -- 是存储到当前页面关闭为止,和其他tab页没关联;
cookie -- 则根据你设置的有效时间来存储,但缺点是不能储存大数据且不易读取,会和后台进行交互。

vue的优缺点

vue优点:
  • 简单易用
  • 轻量高效
  • 灵活渐进式
  • MVVM
  • 组件化 vue缺点:
  • 不支持IE8及以下浏览器
  • 生态环境不如angular和react vue的特性
  • 轻量级框架
  • 双向数据绑定
  • 指令
  • 插件化

单页面开发和多页面开发的区别

单页面开发(spa): 只有一个HTML页面,所以跳转的方式是组件之间的切换。跳转流畅,组件化开发,开发便捷但是首屏加载过慢,seo优化不好 多页面开发(mpa) 有多个页面跳转方式是页面之间的跳转。首屏加载快,seo优化好但是跳转不流畅

简单陈述一下url回车后的过程

1:读取缓存:搜索自身的CNS缓存,如果在CNS缓存中找到对应的ip地址那么直接访问改ip地址,跳过了接下来查找ip地址的步骤
2:DNS域名解析,拿到域名对应的ip地址,用该ip地址访问服务器
3:TCP连接:TCP的三次握手后建立TCP连接
            客户端:服服务器你在么?
            服务器:客户端我在,你要连接么?
            客户端:服务器我要连接。
            连接打通,可以开始请求
4:建立连接后,浏览器发送http请求
5:服务器处理请求并返回http请求报文
6:浏览器解析渲染页面
7:浏览器与服务器断开连接(TCP的第四次握手)