01 弹性布局。浮动布局 table布局

弹性布局:使用 百分比、rem 、flex 自适应布局
浮动布局:使用 float clear
table布局:一般用于后台显示
自适应布局和响应式布局:一般需要用到media媒体查询完成,需要根据屏幕宽度的不同,写多个css样式文件

02 闭包

闭包定义:闭包就是能够读取其他函数内部变量的函数。
闭包可以就解决全局作用域污染的问题
闭包使用场景,闭包的应用场景:
1.setTimeout
原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。

  1. function f1(a) {
  2. function f2() {
  3. console.log(a);
  4. }
  5. return f2;
  6. }
  7. var fun = f1(1);
  8. setTimeout(fun,1000);//一秒之后打印出1

2.回调
  定义行为,然后把它关联到某个用户事件上(点击或者按键)。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件。

  1. <a href="#" id="size-12">12</a>
  2. <script type="text/javascript">
  3. function changeSize(size){
  4. return function(){
  5. document.body.style.fontSize = size + 'px';
  6. };
  7. }
  8. var size12 = changeSize(12);
  9. document.getElementById('size-12').onclick = size12;
  10. </script>

03 原型 ,原型链,继承的方式

原型:既构造函数的prototype.每个构造函数都有一个prototype属性指向生成这个函数的原型对象,简称原型;
prototype 可以对构造函数进行扩展,既添加构造函数的属性和方法
原型链:每个对象都有一个proto属性, 指向生成改对象的原型对象,这样,我们就可以找到是哪个对象生成了改对象,
原型链一般用于继承
原型链的核心就是依赖对象的proto的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有proto指向了。
因为proto实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype。其中Object.prototype是没有proto属性的,它==null。

  1. function Person(name){
  2. this.name = name;
  3. }
  4. var p = new Person();
  5. //p ---> Person.prototype --->Object.prototype---->null

原型继承

  1. //原型继承的基本案例
  2. function Person(name, age) {
  3. this.name = name;
  4. this.age = age;
  5. }
  6. //1.直接替换原型对象
  7. var parent = {
  8. sayHello : function() {
  9. console.log("方式1:替换原型对象");
  10. }
  11. }
  12. Person.prototype = parent;
  13. var p = new Person("张三", 50);
  14. p.sayHello();
  15. //2.混入式原型继承
  16. console.log(".............混入式原型继承..............");
  17. function Student(name, age) {
  18. this.name = name;
  19. this.age = age;
  20. }
  21. var parent2 = {
  22. sayHello : function() {
  23. console.log("方式2:原型继承之混入式加载成员");
  24. }
  25. }
  26. for ( var k in parent2) {
  27. Student.prototype[k] = parent2[k];
  28. }
  29. var p = new Student("张三", 50);
  30. p.sayHello();

继承的方式:

04 Git常用命令

git init 初始化
git clone 克隆代码库

git config 配置
git add 增加文件到暂存区
git commit 提交暂存区到仓库

git branch 名称 新建分支
git checkout 切换分支

git merge 合并分支
git branch -d 删除分支

git tag 打tag 包
git status 查看状态

git log 查看日志
git diff 查看暂存区和工作区差异
git fetch 下载远程仓库的变动

git pull 取回远程仓库变化,并与本地分支合并
git push 上传本地指定分支到远程仓库

解决冲突:

05 跨域的解决方案

因为前端有同源保护政策,所以,不同源或者说不同的域名和ip之间不能进行访问。

1.jsonp jsonp有什么问题?只能是get方式不能是post方式 jsonp原理:script标签的src属性可以跨域
2.proxy代理 只能是打包前使用,打包后需要后台配置跨域 nginx反向代理
3.后台头部设置 Access-Control-Allow-Origin ,cors
4.其他 方式:
a. document.domain + iframe (只有在主域相同的时候才能使用该方法)
b. location.hash + iframe
c. window.name + iframe
d. postMessage(HTML5中的XMLHttpRequest Level 2中的API)
e. web socket
web sockets是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。

06 http协议详解, http请求方式有, http响应状态码

1.http 特点:
1.支持客户/服务器模式。
2.简单快速:。
3.灵活:
4.无连接:
5.无状态:
2. http请求由三部分组成,分别是:请求行、消息报头、请求正文
请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET 请求获取Request-URI所标识的资源
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求

3.在接收和解释请求消息后,服务器返回一个HTTP响应消息。
HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
3xx:重定向—要完成请求必须进行更进一步的操作
4xx:客户端错误—请求有语法错误或请求无法实现
5xx:服务器端错误—服务器未能实现合法的请求

301 永久移动,请求的资源被永久的移动到新url,返回信息会包括新的url。浏览器会自动定向到新url
302 临时移动,资源只是临时被移动,客户端赢继续使用原有url
304 未修改,所请求的资源未修改,服务器返回此状态码是=时,不会返回任何资源,客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

400 Bad Request //客户端请求有语法错误,不能被服务器所理解,解决方法:修改请求的参数及语法
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 ,
解决方式:即没有启用任何认证方式,只需要在IIS Manager里面启用需要的认证方式即可。
即被Authorization Rule阻挡,则需要分析这个authorization rule是否是否必须来决定对他的更改。
403 Forbidden //服务器收到请求,但是拒绝提供服务
  1、你的IP被列入黑名单。
  2、你在一定时间内过多地访问此网站(一般是用采集程序),被防火墙拒绝访问了。
  3、网站域名解析到了空间,但空间未绑定此域名。
  4、你的网页脚本文件在当前目录下没有执行权限。
  6、以http方式访问需要ssl连接的网址。
  7、浏览器不支持SSL 128时访问SSL 128的连接。
  8、在身份验证的过程中输入了错误的密码。
解决方式: 1、重建dns缓存
  对于一些常规的403 forbidden错误,马海祥建议大家首先要尝试的就是重建dns缓存,在运行中输入cmd,然后输入ipconfig /flushdns即可。如果不行的话,就需要在hosts文件里把主页解析一下了。
  2、修改文件夹安全属性
  3、关于apache导致的403 forbidden错误,需设置Apache的配置文件。
  4、关于HawkHost空间出现403 Forbidden错误需设置htaccess文件。
404 Not Found //请求资源不存在,eg:输入了错误的URL 解决办法:输入正确的url地址
405 请求方式不对 ,比如原本需要post方式请求的,你写了get方式请求

07 ajax是同步还是异步,ajax的流程 *

ajax是异步的,
流程:
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
(3)设置响应HTTP请求状态变化的函数.
(4)发送HTTP请求 .(sned)
(5)获取异步调用返回的数据.(onreadystatechange)
(6)使用JavaScript和DOM实现局部刷新.

08 Web Storage *

特性
Cookie 一般由服务器生成,可设置失效时间,(设置过期时间是小于当前时间)。
如果在浏览器端生成Cookie,默认是关闭浏览器后失效;大小 4K左右
每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 需要程序员自己封装,源生的Cookie接口不友好

localStorage 除非被清除,否则永久保存 大小 5M 仅在客户端(即浏览器)中保存,不参与和服务器的通信
源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除 大小 5M 仅在客户端(即浏览器)中保存,不参与和服务器的通信
源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

09 sass和less区别:

  1. sass和less主要区别在于实现方式: less是基于JavaScript的在客户端处理 所以安装的时候用npm,sass是基于ruby所以在服务器处理。
  2. sass与less的安装
    sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby。
    less 在服务器端最容易的安装方式就是通过 npm(node.js 的包管理器)。less 在客户端使用【.less】(LESS源文件),只需要在官网载一个javascript脚本文件主【less.js】,然后在HTML中引入即可。
    3.变量
    sass 是以五星面试题目 - 图1mainColor: #963;
    less 是以@开头定义的变量,如 @mainColor: #963;
    4.作用域
    sass 没有全局变量,满足就近原则,但是实际中可以将需要定义的全局属性放在base.scss 文件中。注意变量名重复; less 中的作用域和其他程序语言中的作用域非常的相同,他首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往下查找,直到根为止。
    区别详细的课参看以下链接:
    https://www.cnblogs.com/tommymarc/p/11627576.html

10 常用的数组方法 *

join():join(separator): 将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符,该方法只接收一个参数:即分隔符。
push()和pop():push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。 pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
shift() 和 unshift():shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。 unshift:将参数添加到原数组开头,并返回数组的长度
sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面
reverse():反转数组项的顺序。
concat():将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。
slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。
splice():splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。
删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。
插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。
替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入4和6。
splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回一个空数组。
indexOf()和 lastIndexOf() (ES5新增):indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。
这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回1。在比较第一个参数与数组中的每一项时,会使用全等操作符。
forEach() (ES5新增)forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。
map() (ES5新增)map():指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
filter() (ES5新增)filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。
every() (ES5新增)every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
some() (ES5新增)some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
reduce()和 reduceRight() (ES5新增)这两个方法都会实现迭代数组的所有项,然后构建一个最终返回的值。reduce()方法从数组的第一项开始,逐个遍历到最后。而 reduceRight()则从数组的最后一项开始,向前遍历到第一项。
这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。
传给 reduce()和 reduceRight()的函数接收 4 个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。

11 字符串方法 *

charAt() 返回指定索引位置的字符
charCodeAt() 返回指定索引位置字符的 Unicode 值
concat() 连接两个或多个字符串,返回连接后的字符串
fromCharCode() 将 Unicode 转换为字符串
indexOf() 返回字符串中检索指定字符第一次出现的位置
lastIndexOf() 返回字符串中检索指定字符最后一次出现的位置
localeCompare() 用本地特定的顺序来比较两个字符串
match() 找到一个或多个正则表达式的匹配
replace() 替换与正则表达式匹配的子串
search() 检索与正则表达式相匹配的值
slice() 提取字符串的片断,并在新的字符串中返回被提取的部分
split() 把字符串分割为子字符串数组
substr() 从起始索引号提取字符串中指定数目的字符
substring() 提取字符串中两个指定的索引号之间的字符
toLocaleLowerCase() 根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射
toLocaleUpperCase() 根据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射
toLowerCase() 把字符串转换为小写
toString() 返回字符串对象值
toUpperCase() 把字符串转换为大写
trim() 移除字符串首尾空白
valueOf() 返回某个字符串对象的原始值

12 对象方法*

Object.assign() 对象合并

13 vue优点

答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

14 vue项目打包优化

https://segmentfault.com/a/1190000018217393
https://segmentfault.com/a/1190000016558958
https://www.cnblogs.com/llcdxh/p/9778491.html
https://blog.csdn.net/junkaicool/article/details/90906086

15 vue项目优化


##
vue项目优化

长列表优化 。 将 table表格替换成其他标签 ,ul li ;分页和 触底加载下一页;onScroll 防抖节流;
需要看一下防抖节流 防抖和节流的区别和实现

16 vuex

vuex 流程
1.在组件中使用dispatch 将状态值分发action;
2.在actions中将 状态值commit提交到 mutations;
3.在mutations中修改store中的状态值;
4.当状态值发生变化时,自动触发render重新渲染页面。
vuex 属性 state action mutation module getter
vuex action mutation 区别 :action 可以异步, 大数据量的操作;mutation 可以直接更改store中的数据值

vuex getters 作用 相当于vue组件中的计算属性
vuex辅助函数 mapState mapAction mapMutation mapGetter
vuex与缓存区别
vuex刷新后数据就没有了,localStorage刷新后值还存在
vuex是响应式的,localStorage不是响应式的
vuex数据持久化 :vuex-persist

17 Vue生命周期

1.什么是 vue 生命周期?有什么作用?
答:每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。(ps:生命周期钩子就是生命周期函数)例如,如果要通过某些插件操作DOM节点,如想在页面渲染完后弹出广告窗, 那我们最早可在mounted 中进行。
2.第一次页面加载会触发哪几个钩子?
答:beforeCreate, created, beforeMount, mounted
3.简述每个周期具体适合哪些场景
答:beforeCreate:在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法
create:data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作
beforeMount:执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的
mounted:执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步
updated:页面显示的数据和data中的数据已经保持同步了,都是最新的
beforeDestory:Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
destroyed: 这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。

18 Vue的响应式原理

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

整体思路
核心:通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的
要实现mvvm的双向绑定,就必须要实现以下几点:

1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。
我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令(如v-model,v-on)对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。因此接下去我们执行以下3个步骤,实现数据的双向绑定:

1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

2.实现一个订阅者Watcher,每一个Watcher都绑定一个更新函数,watcher可以收到属性的变化通知并执行相应的函数,从而更新视图。

3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显示在视图上,然后初始化相应的订阅者(Watcher)。

Vue3.x是用ES6的语法 Proxy对象来实现的,这个玩意儿也可以实现数据的劫持

相比于vue2.x,使用proxy的优势如下
1 defineProperty只能监听某个属性,不能对全对象监听
2 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
3 可以监听数组,不用再去单独的对数组做特异性操作
vue3.x可以检测到数组内部数据的变化
https://www.cnblogs.com/houjl/p/12775091.html

19 vue组件中data为什么必须是一个函数?

答:因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。
  组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

23.vue常用的修饰符

答:.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡;
.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);
.capture:与事件冒泡的方向相反,事件捕获由外到内;
.self:只会触发自己范围内的事件,不包含子元素;
.once:只会触发一次。

24 vue组件传参

父传子 : props接收

子传父: $emit 手动触发自定义事件 (因为 vue组件间传递数据时单向的)
兄弟: bus vuex(我)

https://blog.csdn.net/kangkang_90/article/details/92798296

http://www.mamicode.com/info-detail-3057151.html

  1. props/$emit

  2. $children/ $parent

  3. provide/ inject

概念:

provide/ injectvue2.2.0新增的api, 简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过inject来注入变量。

注意: 这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据

4.ref / refs

5.eventBus

6.Vuex

7.localStorage / sessionStorage

8.$attrs$listeners

vue2.4中,为了解决该需求,引入了$attrs$listeners , 新增了inheritAttrs 选项。 在版本2.4以前,默认情况下,父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),将会“回退”且作为普通的HTML特性应用在子组件的根元素上

43. vue项目中你做过哪些复杂编写,遇到的问题 ,解决方法

  1. 从详情页返回列表时保存浏览位置
    用到keep-alive来缓存页面
    当详情页中改变列表数据时,配合keep-alive,需要在vue钩子函数activated中,对数据进行更改
    activated keep-alive组件激活时调用。
    deactivated keep-alive组件停用时调用。
    1.用到keep-alive来缓存页面
    2.当详情页中改变列表数据时,配合keep-alive,需要在vue钩子函数activated中,对数据进行更改
    3.在从其他页面进入时,页面要重新加载数据。页面从列表进入其他页面(非详情页)时,销毁当前的vue实例。此时需用到组件内的路由守卫,beforeRouteEnter和beforeRouteLeave
    https://blog.csdn.net/fu983531588/article/details/90321827
    https://www.cnblogs.com/goloving/p/9256212.html

  2. 路由全局守卫 router.beforeEach(to,from,next)
    当从一个路由跳转到另一个路由时触发此守卫,也叫全局前置守卫。
    所以它是跳转前触发的。任何路由跳转都会触发。
    每个守卫都有三个参数:
    to:这是你要跳去的路由对象;
    from:这是你要离开的路由对象;
    next:是一个方法,它接收参数;
    next() 跳转
    next(flase) 中断跳转
    next({path:”/“}) 中断跳转,跳转到一个新的路径
    3. axios拦截器
    使用axios 实现登录功能的流程(拦截器)
    先添加拦截器判断, 利用interceptors 调用request ,判断token 是否存在,如果存在,直接跳转

axios拦截器:
// 请求拦截,可以将请求的配置进行二次处理。
axios.interceptors.request.use(config=>{
// config 是axios的配置信息.
// console.log(config);
if(localStorage.token){
config.headers = {
authorization:localStorage.token //将 token的值在 header中传给后台,在后台判断token是否正确
}
}
store.commit(“CHANGE_LOADING”,true);
config.url = “/ele”+config.url;
return config;
})

// 响应拦截 数据没出来时的旋转小图标,报错码对应的报错信息的提示,正确获取数据,返回 promise对象
axios.interceptors.response.use(({data})=>{
console.log(44444444);
// 返回的值即是axios得到的值
store.commit(“CHANGE_LOADING”,false);
if(data.ok === 2 || data.ok === 3){
store.commit(“OUT_LOGIN”);
}else{
return data;
}

  1. css引用图片打包后找不到文件资源的问题
    css引入图片再打包后,style-loader无法设置自己的publicPath,所以只要改变style-loader中的publicPath即可,一行代码即可以搞定,
    找到build/util.js文件中ExtractTextPlugin的css路径,手动添加publicPath参数,
    if (options.extract) {
    return ExtractTextPlugin.extract({
    use: loaders,
    publicPath: ‘../../‘,
    fallback: ‘vue-style-loader’
    })
    } else {
    return [‘vue-style-loader’].concat(loaders)
    }
    重新build一次,问题解决了
  1. mixin 可以提高代码的复用性,同时减少代码的耦合度,但是另一方面给代码维护造成了不小的困扰,用的时候需要衡量其使用频率。
    比如后台项目:添加 、修改,下拉级联菜单,数据,请把它放到 mixin中,在添加和修改页面中调用就可以了
    前台:好多个页面都有 筛选、分页、上拉夹杂爱更多、排序,只要功能是重复出现的,请封装到mixin中
    3.0时用新的 Composition API 提供了更好的解决方案

  2. 多了解一下vue的生命周期,包括公开的以及未公开的,必要时可以方便写个vue插件,在生命周期函数中注入新的功能,包括新的钩子函数,或者新的业务集成。比如:keep-alive的两个钩子

  1. 如有必要,beforeDestory钩子中手动回收一些变量或者注销一些事件,培养自己垃圾回收的意识,以免出现内存问题。如:定时器、事件的解除绑定、轮播的停止等

  2. 状态需要统一管理时考虑使用 vuex ,项目中哪个地方使用了?购物车、用户登录后的数据(比如:用户名、用户权限、用户的相关信息,)、
    左侧菜单的打开或关闭,从后台获取的异步数据

  1. mounted钩子函数中请求数据导致页面闪屏问题
    其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了

  2. el-input手动获取焦点问题
    情景:输入框一开始是隐藏的,点击按钮显示输入框并获取焦点
    把手动获取焦点那段代码写在$nextTick()就好了
    手动获取焦点这个操作我也记录一下:
    首先给标签加个属性ref=”searchBox”(名字随便起),然后点击按钮把控制显示的字段赋值true,接着写下这几行代码就好了
    this.$nextTick(() => {
    this.$refs.searchBox.focus()
    })
    11. https://www.jianshu.com/p/13d5350c6d16
    https://www.zhihu.com/question/387217498/answer/1153513847

25 小程序优化

1、提高页面加载速度
2、用户行为预测
3、减少默认 data 的大小
4、组件化方案

控制包的大小
提升体验最直接的方法是控制小程序包的大小,基本上可以说,1M的代码包,下载耗时1秒左右。
控制包的大小的措施
压缩代码,清理无用的代码
使用外部图片
采用分包策略

分包预加载
独立分包(版本要求有点高)
除了上面讲的控制包的大小,对异步请求的优化也很重要。
对异步请求的优化
onLoad 阶段就可以发起请求,不用等ready
请求结果放在缓存中, 下次接着用
请求中可以先展示骨架图
先反馈,再请求。比如说,点赞的按钮,可以先改变按钮的样式,再发起异步请求。
提升渲染性能
减少使用data,减少使用setData
合并setData的请求,减少通讯的次数
列表的局部更新,做分页,上拉加载更多页

onPageScroll,考虑使用防抖节流 *
尽可能使用小程序组件
一共可以有10个分包 ,一个分包可以有2M

26 小程序页面间有哪些传递数据的方法

1.使用全局变量实现数据传递
在 app.js 文件中定义全局变量 globalData, 将需要存储的信息存放在里面
2.路由传参使用 wx.navigateTo 与 wx.redirectTo 的时候,可以将部分数据放在 url 里面,并在新页面 onLoad 的时候初始化
3.使用本地缓存 Storage 相关
4.使用模块,创建独立的模块文件,输出对象,
模块的使用,可以使用 封装好的js的对象进行传参 ,比如: utils/util.js
```
module.exports = {
formatTime: formatTime,
ggdata:’测试utils中数据是否能跨页传递’

}
<br />在页面中使用时,用 require引入该模块文件<br />例如:<br />
const util = reqiure(“../../utils/util.js”);
```

27 你是怎么封装微信小程序的数据请求的?

在根目录下创建utils目录及api.js文件和apiConfig.js文件;
在appConfig.js封装基础的get\post\put\upload等请求方法,设置请求体,带上token和异常处理等,
封装了数据没获取过来时,旋转和加载中的提示,及数据返回后,返回promise对象,解决回调地狱问题;
在api.js中引入apiConfig.js封装好的请求方法,根据页面数据请求的urls,设置对应的方法并导出;
在具体页面导入;

小程序支持 ES6 语法 在返回成功的回调里面处理逻辑 Promise 异步 async/await
utils文件夹
http.js 封装 了 request
config.js 做配置
api.js 对获取后台数据的统一管理

28 你说你负责支付环节,那么微信支付的 流程是否可以简单说一下?

临时凭证 获取 wxid
生成repayid
json,返回给小程序,小程序调支付窗口。
支持成功提示 + POST回调。

28 小程序登录

a.使用wx.login获取code值
b.使用wx.request请求后台的api,把code值作为参数发送给后台
后台会根据我们传过去的code值来获取openid和session_key,后台需要调用数据库,将登录的信息进行保存,如果是第一次登录,会生成一条新的注册记录

把微信账号登录态生成一个session id并维护在我们自己的session机制中,然后把登录成功的状态返回到小程序客户端作为已经登录成功的凭证。并且返回token值。
c.把登录成功的状态的session值保存到本地,使用wx.setStorage把token保存到本地,
d.在你需要使用的地方session_id的地方调用wx.getStorage(建议你也可以封装一个方法,就可以很方便的取出你要的数据)
e.登录成功后,需要 if (res.authSetting[‘scope.userInfo’]) {
//如果返回true表示 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
如果授权成功,调用 wx.getUserInfo ,获取用户信息,保存到 this.globalData中
注意:有的网站,登录成功后,还有一个手机绑定的功能,获取该微信的手机号,使用wx.request传到后台,与相应的注册账号进行绑定

29 支付流程

25.1 支付之前的准备工作 ,微信账号是企业级的,需要认证,需要申请小程序支付,并获得小程序支付的后台账号,
并且配置好后台的对公账号,打较少的钱,测试账号是否可用

25.2 首先判断是否是已经登录状态,如果不是就跳转登录
25.3 如果已经登录完,我们根据一个用户表将id和openid联系起来,对应openID的id则是用户的uid,生成token,保存缓存
25.4 调用后台 统一下单接口,获取prepay_id,获取所有的签名信息,保存缓存中
25.5 在小程序中调用后台的 order订单接口,获取订单信息,在后台创建商品订单,在订单中会保存商品的id、名称、数量…;如果订单创建成功,将订单内容保存到缓存;
25.6 如果订单创建成功,使用 wx.request调用后台的支付接口 ‘/pay/pre_order’,进行后台的支付流程;
在 success的回调中 ,调用 wx.requestPayment ,请求小程序的支付,在请求的参数中传递 签名信息和商品信息;如果返回 success,那么表示支付成功;如果失败则提示支付失败,并跳转到 未支付页面

【支付流程】https://blog.csdn.net/qq_38378384/article/details/80882980

[小程序面试题]https://www.cnblogs.com/changxin7/p/12334950.html

30 基本的数据类型

String, Number, boolean, Null, Undefined,Symbol(ES6新增),特点: 存储的是该对象的实际数据,(存放在栈中)

31 Flex弹性布局

32 let const

33 变量的解构赋值

  1. let [a, b, c] = [1, 2, 3];
  2. let [head, ...tail] = [1, 2, 3, 4];
  3. let { foo, bar } = { foo: "aaa", bar: "bbb" };

34 扩展运算符 …

  1. 替代数组的apply方法
  2. // ES5的写法
  3. Math.max.apply(null, [14, 3, 77])
  4. // ES6的写法
  5. Math.max(...[14, 3, 77])
  6. // 等同于
  7. Math.max(14, 3, 77);
  8. 扩展运算符的应用:合并数组 与解构赋值结合 函数的返回值 字符串 实现了Iterator接口的对象 MapSet结构,Generator函数

35 严格模式 ‘use strict’;

重点掌握,重点重点
箭头函数 ES6允许使用“箭头”(=>)定义函数。 箭头函数可以保留this的指向 *
箭头函数注意点:
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。
```

36 set和map数据类型

```
set可以用于数组去重,是无序的,set中不包含重复的元素
map 的key值可以是数组对象字符串等格式
Map类似于一个对象,是键值对的集合,键值可以是字符串,各种类型,对象。

37.1 promise

解决异步回调地狱问题
var promise = new Promise(function(resolve, reject) {
// … some code

if (/ 异步操作成功 /){
resolve(value);
} else {
reject(error);
}
});

.then() Promise实例添加状态改变时的回调函数。
.catch() 用于指定发生错误时的回调函数。
Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。
all中的内容是两个异步操作,只有等到它们的结果都返回了,才会触发pickTopRecommentations这个回调函数。
Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。
Promise.resolve()有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。
Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。
.done()Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到
.finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。

37.2 async await

解决异步回调地域问题,一般和promise一起使用

38 class

语法糖 ;解决了js中没有类的概念,需要使用 function做为构造函数来使用的问题,简化了继承

  1. class ColorPoint extends Point {
  2. constructor(x, y, color) {
  3. super(x, y); // 调用父类的constructor(x, y)
  4. this.color = color;
  5. }
  6. toString() {
  7. return this.color + ' ' + super.toString(); // 调用父类的toString()
  8. }
  9. }

39 模块module

  1. 引入模块 import
  2. 输出模块 export

40 基本的数据类型:

String, Number, boolean, Null, Undefined,Symbol(ES6新增)
特点: 存储的是该对象的实际数据,(存放在栈中)

41 transition:设置元素当过渡效果,四个简写属性为:

42 animation:为元素添加动画,是一个简写属性。

43 Div里面有一个div *

1、有几种方法可以水平,垂直居中
https://www.cnblogs.com/a-cat/p/9019184.html
回答完后会继续问
2、当里面div的框高不固定时,怎么水平垂直居中 https://www.jb51.net/css/56268.html