前端面试题,每天总结两道,面试麻溜

972 阅读23分钟

css篇

1. 1px物理像素实现

在移动端web开发中,UI设计稿中设置边框为1像素,前端在开发过程中如果出现border:1px,测试会发现在某些机型上,1px会比较粗,即是较经典的移动端1px像素问题。

设备像素比dpr = 设备像素 / CSS像素(某一方向上) 可以通过window.devicePixelRatio获取设备的dpr值。一般来说,在桌面的浏览器中,设备像素比(dpr)等于1,一个css像素就是代表的一个物理像素。而在移动端,大多数机型都不是为1,其中iphone的dpr普遍是2和3,那么一个css像素不再是对应一个物理像素,而是2个和3个物理像素。即我们通常在css中设置的width:1px,对应的便是物理像素中的2px。手机机型不同,dpr可能不同。

以iphone5为例,iphone5的CSS像素为320px568px,DPR是2,所以其设备像素为640px1136px

解决方案一

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- initial-scale=1.0 缩放比 当为1的时候没用进行任何缩放 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>1px物理像素实现(方案一)</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 0.5rem;
            height: 0.5rem;
            border-bottom: 1px solid #000;
        }
    </style>
    <!-- 像素比 = 物理像素 / css像素 -->
</head>

<body>
    <div id="box"></div>
</body>
<script type="text/javascript">
    window.onload = function () {
        //像素比是什么?针对不同屏幕 dpr不一样
        var dpr = window.devicePixelRatio;
        console.log(dpr);
        //缩放比例
        var scale = 1 / dpr;
        //可视区域的宽度
        var width = document.documentElement.clientWidth;
        //获取mate标签
        var metaNode = document.querySelector('meta[name="viewport"]');
        metaNode.setAttribute('content',"width=device-width, initial-scale='+scale+'");

        //页面中元素的宽度,高度,比例得反向乘回来
        var htmlNode = document.querySelector('html');
        htmlNode.style.fontSize = width * dpr + 'px';

    }
</script>
</html>

解决方案二

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- initial-scale=1.0 缩放比 当为1的时候没用进行任何缩放 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>1px物理像素实现(方案二)</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 200px;
            height: 200px;
            position: relative;
        }

        #box:before {
            content:'';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 1px;
            background: #000;

        }
        @media screen and (-webkit-min-device-pixel-ratio:2) {
            #box:before {
                transform: scaleY(0.5);
            }
        }
        @media screen and (-webkit-min-device-pixel-ratio:3) {
            #box:before {
                transform: scaleY(0.333333);
            }
        }
    </style>
</head>

<body>
    <div id="box"></div>
</body>
<script type="text/javascript">
    window.onload = function () {

    }
</script>
</html>

2. 元素水平居中的方法

方法一

<style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
        }
    </style>

方法二

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:50%;
            left: 50%;
            margin-left:-25px;
            margin-top:-25px;
        }
    </style>

方法三(css3)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50% , -50%);
        }
    </style>

方法四(flex新版本)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
        }
    </style>

方法五(flex老版本)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            display: -webkit-box;
            -webkit-box-pack:center;
            -webkit-box-align: center;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
        }
    </style>

3.如何实现移动端rem适配

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>rem适配</title>
    <style type="text/css">
        #wrap {
            width: 0.5rem;
            height: 0.5rem;
            background:grey;
        }
        /* html 根元素字体大小设置屏幕区域的宽度 */
    </style>
</head>

<body>
    <div id="wrap">
        <div class="box"></div>
    </div>
</body>
<script type="text/javascript">
    window.onload = function () {
        //获取屏幕区域的宽度
        var width = document.documentElement.clientWidth;
        //获取html
        var htmlNode = document.querySelector('html');
        //设置字体大小
        htmlNode.style.fontSize = width + 'px';

    }
</script>
</html>

4.css实现两栏布局,左侧固定宽,右侧自适应的7中方法

www.cnblogs.com/wangzhenyu6…

js篇

1.什么是跨域?解决跨域的方法?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

同源策略

- ——是浏览器安全策略
- ——协议名、域名、端口号必须完全一致
- 举例:
http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行

跨域

- 违背同源策略就会产生跨域

解决方法

- jsonp cors websocket Node中间件代理(两次跨域) ngix反向代理...

1. jsonp方法

所以JSONP的原理其实就是利用引入script不限制源的特点,把处理函数名作为参数传入,然后返回执行语句,仔细阅读以下代码就可以明白里面的意思了。

补充:1) JSONP和AJAX对比

    JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)

2)JSONP优缺点

    SONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
<script>
        //创建 script 标签
        var script = document.createElement('script');
        //设置回调函数
        function getData(data) {
            //数据请求回来被触发的函数
            console.log(data);
        }
        //设置script的src属性,设置请求地址
        script.src = 'http://localhost:3000?callback = getData';
        //让script生效
        document.body.appendChild(script);
    </script>

2.cors的简单请求

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。 浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。 服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。 虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。

只要同时满足以下两大条件,就属于简单请求

条件1:使用下列方法之一:

  • GET
  • HEAD
  • POST

条件2:Content-Type 的值仅限于下列三者之一:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器; XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。

4.websocket

Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。 同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。 原生WebSocket API使用起来不太方便,我们使用 Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

我们先来看个例子:本地文件socket.html向 localhost:3000 发生数据和接受数据

// socket.html
<script>
    let socket = new WebSocket('ws://localhost:3000');
    socket.onopen = function () {
      socket.send('我爱你');//向服务器发送数据
    }
    socket.onmessage = function (e) {
      console.log(e.data);//接收服务器返回的数据
    }
</script>

// server.js
let express = require('express');
let app = express();
let WebSocket = require('ws');//记得安装ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
  ws.on('message', function (data) {
    console.log(data);
    ws.send('我不爱你')
  });
})

总结:CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案 JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。 不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。 日常工作中,用得比较多的跨域方案是cors和nginx反向代理

更多方法参考:juejin.cn/post/684490…

2.什么是闭包?

  1. 密闭的容器,类似于set,map容器,存储数据的
  2. 闭包是一个对象,存放数据的格式:key:value

形成的条件:

  1. 函数嵌套
  2. 内部函数引用外部函数的局部变量

闭包的优点:

  1. 延长外部函数局部变量的生命周期

闭包的缺点:

  1. 容易造成内存泄漏

注意点:

  1. 合理使用闭包
  2. 用完闭包要及时清除(销毁)

segmentfault.com/a/119000000…

3.axios是什么?怎么使用?描述使用它实现登录功能的流程?

(一).axios是什么?

  1. axios 是基于 promise 用于浏览器和nodejs的一个http客户端,主要用于向后台发送请求的,还有就是在请求中做更多控制。
  2. 支持 promise
  3. 提供了一些并发的方法
  4. 提供拦截器
  5. 提供支持CSRF(跨域请求伪造)

(二).axios fetch ajax(jquery)区别

  1. 前两者都是支持promise的语法,后者默认是使用callback方式
  2. fetch 本质上脱离的xhr 是新的语法(有自己的特性 默认不传cookie 不能像xhr这样 去监听请求的进度)

(三).怎么使用?

<script>
    axios.get('').then(function(){
        
    }).catch(function(){
        
    })
    
    axios.post('').then(function(){
        
    }).catch(function(){
        
    })
</script>

(四).描述使用它实现登录功能的流程?

3.const,var,let区别

www.cnblogs.com/zzsdream/p/…

4.new操作符原理解析

www.cnblogs.com/lvmylife/p/…

5.promise的回调机制

juejin.cn/post/684490…

6.阻止冒泡,说说vue中事件的阻止冒泡以及原理

caibaojian.com/javascript-…

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题, Vue.js 为 v-on 提供了 事件修饰符。通过由点(.)表示的指令后缀来调用修饰符。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
 
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
 
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
 
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
 
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
 
<!-- 只当事件在该元素本身(比如不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止元素上的点击。

4.基本数据类型

js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object)。

5.如果判断两个对象是否相等

先判断对象属性的长度是否相等,再判断每个属性的值是否相等 juejin.cn/post/684490…

6.javascript两个变量互换值,你了解多少?

blog.csdn.net/nyflxp/arti…

7.数组去重12种方法?

segmentfault.com/a/119000001…

vue/React/Angular

1.react跟vue的区别?

相同点:

  1. 都有组件化开发和Virtual DOM (提高程序的运行效率)
  2. 都支持props进行父子组件间数据通信
  3. 都支持数据驱动试图,不直接操作真是DOM,更新状态数据界面就自动更新
  4. 都支持服务器端渲染
  5. 都支持natived 的方案,React的React Native, Vue 的Weex, (都支持原生的跨平台运用)

不同点:

  1. 数据绑定:vue实现了数据的双向邦定,react数据流动是单向的
  2. 组件的写法不一样,React推荐的做法是JSX,也就是把HTML和CSS全部都写进Javascript了,即 'all in js', Vue推荐的做法是 webpack + vue-loader的单文件组件格式,即 html,css,js 写在同一个文件
  3. state对象在React应用中不可变的,需要使用setState方法更新状态,在vue中 state对象不是必须的,数据由data属性在vue对象中管理
  4. virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树,而对于React而言,每当应用的状态改变时,全部组件都会重新渲染,所以react中会需要shouComponentUpdata 这个生命周期函数方法来进行控制
  5. React严格上只针对MVC的view层,Vue则是MVVM模式

2.Redux 管理状态的机制

对Redux的基本理解

  1. redux是一个独立专门用于做状态管理的JS库,不是react插件库
  2. 它可以用在 react,angular,vue等项目中,但基本与react配合使用
  3. 作用:集中式管理react应用中多个组件共享的状态和从后台获取的数据

Redux的工作原理

1. redux的结构 三个模块:

  1. store (内部管理着状态)
  2. reducers (根据老的状态生成新的状态)
  3. action creator (专门生成action对象的)

2.store内部管理着state状态, react组件跟 reducers的通信就根据store来的,store相当于桥梁,提供了两个方法,一个读 getState(),一个更新dispatch()

Redux 使用扩展

  1. 使用 react-redux 简化 redux 的编码
  2. 使用 redux-thunk 实现 redux 的异步编程
  3. 使用 Redux DevTools 实现 chrome 中的调试

vue篇

1.说说Vue组件间通信方式

通信种类

  1. 父组件向子组件通信
  2. 子组件向父组件通信
  3. 隔代组件间通信
  4. 兄弟组件间通信

实现通信方式

(一). props

  1. 通过一般 标签 属性实现父向子通信
  2. 通过 *** 函数 *** 属性实现子向父通信
  3. 缺点: 隔代组件和兄弟组件通信比较麻烦
  • 隔代组件得逐层传递
  • 兄弟组件得借助父组件

(二). vue自定义事件

  1. vue内置实现,可以代替函数类型的props
  • 1). 绑定监听:<MyComp @eventName="callback"
  • 2). 触发(分发)事件: this.$emit('eventName',data)
在父组件写入子组件标签时,给它绑定自定义监听,给它指定回调函数,在子组件中分发事件,vue提供了$emit('指定时间名',数据),这时候数据就会从子组件传递给父组件
  1. 缺点: 只适合子向父通信

(三). 消息订阅与发布

  1. 需要引入消息订阅与发布的实现库,如:pubsub-js
  • 1). 订阅消息: PubSub.subscribe('msg',(msg,data)=>{})
  • 2). 发布消息:PubSub.publish('msg',data)
  1. 优点: 此方式可用于任意关系组件间的通信

(四). vuex

  1. 是什么: vuex是vue官方提供的集中式管理vue多组件共享状态数据的vue插件
  2. 优点: 对组件间关系没有限制,且相比于pubsub库管理更集中,更方便

(五). slot

  1. 是什么:专门用来实现父向子传递带数据的标签
  • 1). 子组件
  • 2). 父组件
  1. 注意:通信的标签模板是在父组件中解析好再传递给子组件的

2.关于vue

  1. vue是由饿了么ued团队开发并维护的一个渐进式js框架
  2. vue是一个mvvm的框架

3.如何使用vue去构建项目

  1. 使用vue-cli脚手架工具构建项目
  2. 也可以直接引入vue.js进行项目的构建

4.Vue生命周期函数

vue生命周期分为四个阶段:

  1. 组件创建时(creating)
  2. 模板渲染时(mounting)
  3. 数据更新时(updating)
  4. 组件卸载时(destroying)

vue生命周期完整过程:

5.Vuex 管理状态的机制

  1. 对Vuex基本理解
  • 1). 是什么:Vuex是一个专为Vue.js应用程序开发的状态管理的vue插件
  • 2). 作用:集中式管理vue多个共享的状态和后台获取数据,主要是为了解决组件间状态共享的问题,强调的是集中式管理,主要便于维护,便于解耦,所以不是所有的项目都适合使用vuex。
  1. Vuex的工作原理

6.说出4个vue当中的指令和它的用法

  1. v-if 条件渲染指令,代表存在销毁
  2. v-bind 绑定指令,用来绑定属性(简写方式是:)
  3. v-on 监听事情指令(简写是@)
  4. v-for 循环指令

7.导航钩子有哪些?他们有哪些参数?

  1. 导航钩子其实就是路由的生命周期(vue-router)
  2. 主要分为 全局局部
  3. 全局钩子函数
  • 1). beforeEach: 路由切换开始调用
  • 2). afterEach: 在路由切换离开时调用
  1. 局部到单个路由
  • 1). beforeEnter
  1. 组件的钩子函数
  • 1). beforeRouterEnter
  • 2). beforeRouterUpdate
  • 3). beforeRouterLeave
  1. 参数
  • 1). to:即将进入的目标对象
  • 2). from:当前导航要离开对象
  • 3). next: 是一个函数 调用 resolve 执行一下

8.v-model是什么?Vue中标签怎么绑定事件?

  1. vue中利用v-model来进行表单数据的双向绑定
  2. v-bind 绑定一个value的属性
  3. 利用v-on 把当前的元素绑定到一个事件上
<div id="demo">
    <input v-model="inputValue" />
    <p>{{inputValue}}</p>
    
    <input v-bind:value="inputValue2" v-on:input="inputValue2 = $event.target.value" />
</div>
<script>
    var vm = new Vue({
        el:"#demo",
        data:{
            inputValue:'',
            inputValue2:''
        }
    })
</script>

9.路由懒加载

理解:路由懒加载 也叫延迟加载,即在你需要的时候加载

如何使用:使用到了vue中的异步组件,配合webpack的代码分离,只需要自己返回一个permise函数,resolve中只包含你想要用的那个xxx.vue文件就可以了。

//在router文件的index.js中进行懒加载
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Detail from '@/components/Detail'

function resolveView(view){
    return ()=> import(/*webpack chunk name*/`@/components/${view}.vue`)
}

export default new Router({
    routes:[
        {
            path:'/',
            name:'HelloWorld',
            component: resolveView('HelloWorld')
        },
        {
            path:'/detail',
            name:'Detail',
            component: resolveView('Detail')
        },
    ]
})

10.Vue-loader 解释一下

(一).什么是vue-loader?

  • vue-loader 就是一个加载器,能把.vue组件转化成Javascript模块

(二).为什么我们要转译这个vue组件

  • 可以动态的渲染一些数据
  • 对三个标签都做了优化,script中可以直接使用es6 style 也默认可以使用sass,并且 还提供了作用域的选择
  • 另外开发阶段,还提供了热加载

11.用过插槽码?用的具名插槽还是匿名插槽呢?

含义:

  1. vue中的插槽 是一个非常好用的东西,slot 说白了就是一个占位
  2. 在vue当中 插槽包含三种 一种是默认插槽(匿名插槽),一种是具名插槽,一种是作用域插槽
  • 1). 匿名插槽 :就是没有名字的,只要默认的 都填到这里
  • 2). 具名插槽 :指的是具有名字的
  • 3). 作用域插槽 : 指只作用域当前的slot

举例:

//子组件about.vue
<template>
    <div>
        <h2>关于插槽</h2>
        <slot name="header"></slot>                 /*具名插槽*/
        <slot></slot>                               /*匿名插槽*/
        <slot name="footer" say="hello"></slot>     /*say='hello'传递的参数*/
    </div>
</template>
<script>
    export default {
        name:'about'
    }
</script>

//父组件:helloWorld.vue
<template>
    <div>
        <About>
            <h2>这是HelloWorld组件的内容</h2>
            <div slot="footer" slot-scope="aaa">
                {{aaa}}这是底部
            </div>
            <div></div>
            <div slot="header" slot-scope="aaa">
                {{aaa}}这是头部
            </div>
        </About>
    </div>
</template>
<script>
import About from '@/componts/About';
export defalut {
    name:'HelloWorld',
    components:{
        About
    }
}
</script>

  • 打印结果:

12.说说你对vue虚拟DOM的理解

(一).什么是虚拟dom

  • 说白了 就是以js对象的形式 去添加dom元素
  • 本质上是优化了diff算法
  • 采用了 新旧dom的对比 获取你差异的dom,一次性更新到 你真实的dom上
  • 虚拟dom本身也有自己的缺陷,他更适合批量修改dom
  • 尽量不要跨层级修改dom
  • 设置key 可以最大的利用节点

13.如何理解Vue的MVVM模式

(一). mvvm 和 mvc 之间的区别

  1. mvc 指的是model view controller
  2. mvvm指的是model view viewModel
  3. 而vue专注于view 和 viewModel 的框架

(二). mvc流程

  • 用户输入数据(view) =>给到控制器(controller)=>控制器判断可以把数去传递给model => model传递完数据会再给到view
  • 有时候用户把数据(view)传递给控制期(controller),controller会判断 这个数据不需要经过数据库请求,就可以把数据直接返回给view
  • view 不需要业务处理,只需要数据请求,view 也可以直接像model请求

(三). mvvm流程

14.Vue中keep-alive的作用

(一).什么是keep-alive

  • 说白了 它能让不活动的组件 "活着"
  • 它提供了 includeexclude 两个属性 允许组件有条件的缓存

(二).实现的原理

  • 其实就是在created的时候将需要的缓存的vnode节点 放到 cache 中,在render的时候 根据name进行取出

(三).怎么使用它

  • 在路由的meta中添加 keepAlive 属性
  • 跟 router-view 配合使用的
// router/index.js
export default new Router({
    routes:[
        {
            path:'/',
            name:'HelloWorld',
            component:resolveView('HelloWorld'),
            meta:{
                keepAlive:true
            }
        }
    ]
})
// App.vue
<template>
    <div>
        <keep-alive>
            <router-view v-if="$route.meta.keepAlive" />
        </keep-alive>
    </div>
</template>
  • $route.meta.keepAlive 根据页面的不同情况来缓存

项目中遇到的问题

1.swiper插件从后台获取数据没问题,css代码啥的也没有问题,但是图片不动,应该怎么解决?

(一)主要原因:是 swipter 提前初始化了,而这个时候 数据 还没有完全出来。

(二)解决方法:

  1. 从vue入手:
vue中专门提供了一个方法 nextTick() 用于解决dom的先后执行问题
  1. 从swiper入手(observer属性,observeParents属性):
var myswiper = new Swiper('.swiper-container',{
    autoplay:true,
    loop:true,
    observer:true,      //swiper跟子元素发生变化时,自动初始化
    observeParents:true     //swiper跟父元素发生变化时,自动初始化
})

2.vuejs项目性能优化(打包dist文件过大)

www.jianshu.com/p/41075f1f5…

3.vue项目中遇到的问题

www.bbsmax.com/A/kmzLPblGz…

node篇

1.对于前端来说为什么要学node?

  • 现在前端在写代码的时候并不是像原生那样,是把前端代码当作一个工程来写,而工程要建立在node之上,因为我们在工程里面,比如vue,react代码 实际上这些代码根本无法在浏览器上运行,我们得通过 webpack 这样的工具来编译转换,转换成能在浏览器上运行的代码,而 webpack 是通过 node 来实现的,所以学node主要是理解前端工程化的东西,不然 就不知道npm 是什么,wepack的底层是什么,所以遇到工程化比较深的时候就理解不了了
  • 所以node 前端该学,但是学的主要目的不是为了写后端,主要为了了解前端的工程化

2.Node如何做版本升级?为什么要使用nvm?

(一). 为什么有的时候我们要对node的版本进行升级

  1. 什么情况下需要把 node v8.0 升级到 node v11.0 ?
  • 新的语法可能在老的版本里面不支持
  • (新版本的node比老版本的node的打包效率要高很多) vue-cli 需要 node版本>8.1.0 ,实际上是因为底层的webpack,当我们的项目很复杂的时候,打包的文件特别特别多,打包速度就会非常的慢,webpack 现在已经升级到了4.0了,webpack比较依赖于新的node的api,从而提高它的打包效率
  1. 如何升级node版本?(需要 nvm 的支持)

(二).nvm是什么?

  1. 它允许你在你的电脑上安装不同的node的版本,你可以自由的进行切换
npm install nvm     //安装nvm
nvm ls              //查看安装版本
nvm install v11.0.3 //安装新的版本
nvm use v.11.0.3    //使用某个版本

模块化的差异,AMD,CDM,COMMONJS,ESMONDULE

AMD含义

  • AMD 是依赖前置, 比如angular.js

区别

1. AMD,CDM 没有什么差异

2. COMMONJS 可以理解为是 CMD 的一个具体实现,在耦合性上会强一点, 模块的引入是运行时的引入的机制,是动态的引入,可以放在if else 中去引用。

if (true) {
    const path =  require('path');
} else {
    const path = require('fs');
}

3. ESMONDULE:es这种模块化的引入是要放在最前面,并且不能放在任何逻辑里面,是静态的引入,你要引入什么 是一开始就决定好的。

  • 静态引入的好处:可以做代码的预分析,webpack 里面会有一个 依赖托普,只有你的代码是一个import 的语法引入的时候,才能静态的去帮你分析项目的一个依赖结构,帮助你快速打包,如果你不是import这种语法的话,要想用webpack是不可能的
//错 不能这样写
if (true) {
    import a from 'a';
} else {
    import b from 'b';
}

http篇

1.一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?

1、用户打开URL链接(域名)

2、浏览器查询的URL的DNS地址(IP地址)

3、DNS服务器查询到IP之后返回给浏览器

4、浏览器根据返回的IP地址向web服务器发起请求

5 、web服务器接收请求并处理,之后返回相应的数据(HTML、css、js等信息)给浏览器

6、浏览器接收到返回的数据之后便开始解析数据过程如下:
   a:解析HTML -- 语法分析

   B:构建DOM树

   C:解析CSS文件

   d:布局DOM节点

   浏览器在此过程中还会遇到一些引用的图片,此时还会继续向服务器发出请求,但不会发生阻塞,而是继续往下执行代码;当然还有可能会遇到的JavaScript的标签并执行,此时如果需要发出请求的话,浏览器会发生阻塞,知道请求,解析,执行完了之后才会继续往下执行代码;(原因是浏览器防止JS脚本中出现修改DOM的情况导致需要重新布局DOM节点)

   e:绘制DOM节点(解析到HTML的结束符)---完成

   f:回流,简单来说该步骤的执行是由于dom节点受到了js或者是css的影响导致页面发生重绘。

www.cnblogs.com/dinghuihua/…

2.HTTP常见状态码

下面是常见的HTTP状态码:

200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

www.runoob.com/http/http-s…

3.客户端发送一个HTTP请求到服务器的请求消息包括以下格式

请求行(request line)、请求头部(header)、空行和请求数据

4.HTTP响应也由四个部分组成

状态行、消息报头、空行和响应正文

其他篇

1.token 存在cookie里,过期怎么处理?

  • 过期直接跳到登陆页面中去。

2.工程上的按需加载?

  • 原理是支持require.ensure语法
  • 或者