同行兄弟出去面试题的汇总 2020-7-19

1.普通数据类型
(1)普通数据类型有哪些?
​ 字符串型string: 数值型number,:undefined:null,:布尔型boolean
复杂数据类型有Object Array Date
(2如何检测类型?
console.log(typeof data) instanceof Array.isArry()
(3如何转换数据类型?
转字符串
​ 数据.toString()
​ String(数据)
​ 隐式转换:数据+’ ’
Join(‘分割符’)
转数值
Number必须是纯数字(数据) '123aaa’转完之后是NaN
parseInt转整数(数据) '123aaa’转完之后是123
parseFloat转浮点数(小数)
隐式转换:数据* / -
转布尔值
Boolean(数据)
布尔值为false的有undefined, null, ’ ', NaN, true, 0
2.this
(1)this指向
全局中, this 指向 window
函数中,严格模式下, this 指向 undefined ;非严格模式下, this 指向 window
定时任务中, this 指向 window ( setTimeOut , Interval )
绑定事件中, this 指向事件源
对象中, this 指向这个对象
构造函数中this指向new出来的实例

对象:无序键值对的集合

(1) 对象字面量
var obj = { name: ‘wkk’, age: 18, skill: function () {   console.log(‘敲代码’) }}console.log(obj.name)console.log(obj[‘age’])​//遍历对象for (var k in obj ) { console.log(k) console.log(obj[k])}
(2) new Object()
var obj = new Object()obj.name = "wkk"obj.skill = function () {}
(3)构造函数
构造函数中, this 指向 new 出来的实例
//构造函数function Dog (name, color, voice) {   this.name = name           //this指向 new 出来的实例   this.color = color   this.bark = function (voice) {     console.log(voice)   } } var wkk=new Dog(‘wkk’,‘灰色’) console.log(wkk) wkk.bark(‘haha’)
new关键字执行了哪些过程?
(1) 先创建了一个空对象
(2) 然后让 this 指向这个空对象
(3) 给属性赋值,给方法赋值
(4) 把结果return 出来
o
(2)改变this的方法及区别
call 立即执行,第一个参数修改 this 指向,第二个是依次传入的参数 用, 隔开
apply 立即执行,第一个参数修改 this 指向,第二个参数是数组或对象的用[ ]包裹
bind 不会立即执行,第一个参数修改 this 指向,
3.前端模块化
所谓的前端模块化,就是指将应用分成多个模块,例如魔方,
前端在没有模块话的时候,容易出现 命名冲突、文件依赖问题,这些问题都是因为 JavaScript 天生没有模块化
那么为了解决 命名冲突、文件依赖问题,JavaScript 社区就出现了一些所谓的前端模块化
主要流行的有三个
两个前台的 AMD(require.js)、CMD(sea.js – 玉伯)
一个后台的 commonJS(node.js)
例如: commonJS 规定,一个文件,就是一个模块,模块内部的成员外部访问不到,
如果想被外部访问,需要使用 exports 、module.exports 进行导出
如果想使用外部:需要使用 require 导入
在 ES6 中,已经支持了前端的模块化 ……
import导入 模块
export default 来导出模块
7.数组和字符串的内置方法
数组:
翻转(reverse)
排序(sort)
追加(push后加,unshift前加)
删除(pop后删,shift前删)
获取索引(indexof 首次出现的位置从前往后查 ,lastIndexof 最后一次出现的位置从后往前查 )
截取(slice(开始,结束),splice(开始,个数))
拼接数组(concat)
字符串:
​ 根据元素找索引(indexof)
​ 根据索引找元素(charAt)
​ 截取(slice(开始,结束) ,substr(开始,个数))
​ 拼接(concat)
​ 替换(replace)
​ 分割为数组(split)
8.js执行机制
js是单线程的,分为同步任务和异步任务(定时器,ajax,事件绑定),同步任务在执行栈中执行,异步任务在执行队列中.
先执行执行栈中的,然后把执行队列中的放到主线程中执行.
事件委托
要给子元素绑定事件时,可以将事件统一绑定给它的父元素带代理完成事件.
点透问题
层级较高的定位元素绑定 touchstar 事件,会同时触发层级低的元素,发生堆叠.
解决: fastclick js 库(还可以解决 300ms 延时 浏览器预留时间进行鼠标双击)
11.组成,顶级对象,隐式迭代,链式编程
web标准构成: 结构HTML, 表现css, 行为 js
h5: html5, css3 , js
js: ECMAscript , DOM(document), BOM(window)
顶级对象: jquery ($,jquery)
node.js(global)
js入口函数: window.οnlοad=function () {} 结构和全部资源执行完成后执行 目的是为了先加载页面再进行js;
​ DOMContentLoaded 结构完成就执行(图片特别多时使用)
jquery入口函数: $(function () { })
隐式迭代: 隐式遍历的过程,执行相应的方法
链式编程: 节省代码量

12.undefined的情况
变量声明未赋值
访问数值中不存在的索引
访问对象中不存在的属性
函数没有返回值,或返回值不明确
函数的形参匹配不到对应的实参
13.移动端布局
流式布局 百分比布局
把盒子的宽度设置成百分比的形式来对屏幕的宽度进行自适应的伸缩
flex布局 弹性布局
给盒装模型提供最大的灵活
flex-direction:设置主轴的方向
justify-content:设置主轴上的子元素排列方式
flex-start 从头开始
flex-end 从尾部开始
Center 在主轴居中对齐
space-around 平分甚于空间
space-between 先贴两边 在平分剩余空间
flex-wrap:设置子元素是否换行 nowrap 不换行
align-content:设置侧轴上的子元素的排列方式(多行)
flex-start 从头开始
flex-end 从尾部开始
Center 在侧轴居中对齐
space-around 平分甚于空间
space-between 先贴上下 在平分剩余空间
Stretch 子项元素高度平分父元素高度
align-items:设置侧轴上的子元素排列方式(单行)
flex-start 从头开始
flex-end 从尾部开始
Center 在侧轴居中对齐
Stretch 拉伸
flex-flow:复合属性,相当于同时设置了 flex-direction 和 flex-wrap
rem+less+媒体查询布局 / flexible.js+rem
rem :根据html的字体大小来变化,1rem = html的字体大小
em相对于父元素,rem相对于根元素。
媒体查询: 针对不同的媒体类型定义不同的样式 CSS3新语法
​ @media screen and ( min-width: 320px ) { }
Less是一门 CSS 预处理语言,它扩展了CSS的动态特性
Less 使用之变量 @变量名:值;
Less 嵌套 #header {
.logo {
width: 300px;
}
}
Less 运算 @witdh: 10px + 5;
flexible.js+rem flexible是默认将屏幕分为10等分
混合布局
响应式 媒体查询+ bootstarp 即 pc和移动端共用一套网站,只不过在不同屏幕下,样式会自动适配
屏幕或视口自动分为最多12列。
栅格系统:
​ 栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局.
​ 随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。
小于768的为超小屏幕(手机)col-xs-12
768~992之间的为小屏设备(平板)col-sm-6
992~1200的中等屏幕(桌面显示器)col-md-3
大于1200的宽屏设备(大桌面显示器)col-lg-3
.col-md-offset-* 类可以将列向右侧偏移
.col-md-push-* 和 .col-md-pull-* 类就可以很容易的改变列(column)的顺序
响应式需要一个父级做为布局容器,来配合子级元素来实现变化效果。

14.原型链,闭包,递归
原型链:
原型对象也是一个普通的对象,他是对象自带的一个隐性的 proto 属性,原型也有自己的原型对象,当原型对象不为null的时候,就是一个原型链了.

闭包
首先,闭包是一个函数,能访问自己的作用域,还能访问其他函数的作用域。
作用: 延长了变量的作用范围
递归
函数内部自己调用自己,一定要有退出条件,否则会出现死循环.
15.预解析
如果作用域有声明变量和函数的,要提升变量声明(不提升赋值)和★函数声明(不提升函数调用)
16.ES6新语法
const let var
Var 预解析,let const 不存在预解析,没有块级作用域,在同级作用域中可以声明多次,后面会覆盖前面
let: 块级作用域,存在暂时性死区,同级作用域只可以申明一次
const: 常量,块级作用域,值不可以更改, 存在暂时性死区, 声明时必须初始化.
数组的方法
1、构造函数方法:Array.from() – ★★
将类数组或可遍历对象转换为真正的数组
方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
2、实例方法:find() — ★★★★
用于找出第一个符合条件的数组成员,如果没有找到返回undefined
3、实例方法:findIndex() — ★★★★★
用于找出第一个符合条件的数组成员的位置(索引),如果没有找到返回-1
4、实例方法:includes() — ★★★★★
表示某个数组是否包含给定的值,返回布尔值。
5、forEach 迭代(遍历) 数组 — ★★★★★
6、filter 筛选数组 – 返回一个新的数组 – ★★★★★
7、some 查找数组中是否有满足条件的元素 – 返回结果 true 或者 false – ★★★★★
字符串新增的方法
includes() 判断字符串中是否包含特定的字符串
startsWith() 判断字符串是否以特定的字符串开始
endsWith() 判断字符串是否以特定的字符串结束
padStart(),padEnd() 字符串补全长度功能: 对时间、对价格
模板字符串,
模板字符串使用 ${ 变量 } 解析变量。
可以换行 可以调用函数。
箭头函数
1、函数中的this是声明时的对象,不是调用时的对象
2、箭头函数不可以 new,也就是说它不是构造函数
3、函数内部不可以使用arguments,可以用rest参数替代
4箭头函数内部是没有 this 的,内部的 this 指定他定义的区间的 this 指向
扩展运算符 …
…作用就是把数组转成单个的数据项
类 本质上就是构造函数
动态方法:所谓的动态方法就是能被实例调用的方法
静态方法:使用 static 修饰的方法,静态方法只能被 类 进行调用
继承的关键字是使用 extends
解构
在对象和数组中提取值,对变量进行赋值

17.防抖和节流
防抖
场景:搜索时,监听用户输入,或者用户连续点击提交按钮
在一定时间内, 当一个动作连续触发,则只执行最后一次。
防抖函数分为非立即执行版和立即执行版。
简单方法: 若前一个定时任务未执行完,则 clear 掉定时任务,重新定时。
节流
场景: 滑动区域的scroll事件做监听,判断距离底部还有多远,
限制一个函数在一定时间内只能执行一次。
对于节流,一般有两种方式可以实现,分别是时间戳版和定时器版。
简单方法: 在延时的时间内,方法若被触发,则直接退出方法
18.状态码
400: 客服端语法错误
200: 请求成功
404: 请求资源没有找到
500: 服务器错误
19.get 和 post 的区别
get的参数放在URL中,暴露在外边,不能够传递敏感信息
post的参数放在请求体中
它们都是用来发送请求的
20.ajax的创建
var xhr = new XMLHttpRequest()//创建一个ajax对象xhr.open()//告诉ajax请求地址和请求方式xhr.send()//发送请求xhr.onload = function () { console.log(xhr.responseText)//响应请求}xhr.readState   获取状态码
21.cookie,session,token
cookie存在浏览器,不安全;
session存在服务器,可能影响性能;
token身份认证安全性好,是唯一的。若存在第三方,用token,不用session。
22.W3C盒模型 标准盒模型 box-sizing:content-box
Content 内容/ 边框border/
内边距 padding / 外边距margin
外边距合并(外边距塌陷) 就是指两个块级元素上下摆放,上又margin-bottom下有 margin-top 之间距离不是两者之和,而是取最大值 解决:只给一个盒子margin
嵌套块级元素垂直外边距合并(塌陷)解决:overflow:hidden
浮动:特点 1.脱离标准流,在一行显示,不占据位置,会影响下面元素
2.移动到指定位置,用来布局,早期是用来实现文字环绕图片的效果
3.消除了外边距,压不住padding
清除浮动:1.标签法 《div style=”clear:both”>
2.父级添加overfllow:hidden 移除隐藏 auto 添加滚动条 scroll 自动判断添加滚动条 visible默认
3.使用after伪元素清除
.clearfix:after{ content:""; height:0 ;lin-height:0; display:block; visibility:hidden;clear:both;}
.clearfix:after{*zoom:1; /针对IE6/IE7/}
4.双伪元素清除
.clearfix:before,.clearfix:after{ content:"";display:table; }
.clearfix:after{ clear:both;}
.clearfix:after{ *zoom:1;}
定位:position:static默认值
relative 相对定位 占位置,未脱标
absolute绝对定位 无父级,已浏览器可视区域定位
有父级但父级无定位 已浏览器可视区定位
有父级有定位,以父级来定位(子绝父相)
脱标,不占位置,可压住padding
fixed固定定位 脱标 不占位,与父级无关,以浏览器为父级
盒子堆叠顺序:定位布局,盒子重叠,定位的盒子后来者居上,后面的盒子压住前面的盒子 使用Z-index来解决 取值 整数或者0 越大盒子越上
Display : none 隐藏后,不在页面保留位置 block显示,转换为块级元素
Visibility :hidden 隐藏 占据位置,visible显示元素
vertical-align 行内元素盒模型与其行内元素容器垂直对齐,垂直对齐表格单元内容:不能用它垂直对齐块级元素
text-align作为HTML元素属性其主要是用来文本水平居中的
margin:0 auto;可以使盒子居中
23.CSS3 盒模型 移动端
1.box-sizing: border-box 不会因为border padding 撑大盒子
2.视口(viewport)显示页面内容的屏幕区域。 分为布局视口、视觉视口和理想视口
布局视口 layout viewport
视觉视口 visual viewport
理想视口 ideal viewport
/CSS3盒子模型/
box-sizing: border-box;
-webkit-box-sizing: border-box;
/点击高亮我们需要清除清除 设置为transparent 完成透明/
-webkit-tap-highlight-color: transparent;
/在移动端浏览器默认的外观在iOS上加上这个属性才能给按钮和输入框自定义样式/
-webkit-appearance: none;
/禁用长按页面时的弹出菜单/
img,a { -webkit-touch-callout: none; }

24.选择器
1.标签选择器div span
2、类选择器 取class名,以点(.)加class名开头
3、取id名,以#加id名开头,具有唯一性
4、子选择器 以>隔开父子级元素
5、包含选择器 以空格隔开包含关系的元素
6、全局选择器 以开头
7、属性选择器 [attr=” x”] 属性是x 的元素 attr^=x 已x开头 $以x结尾 * 含x
8、伪类选择器 li:first-child()
li:nth-child(数字。odd奇数 even偶数) 不管里面的孩子是否同一种类型
li: nth-of-type 孩子必须是同类型
9、伪元素选择器 ::before 和 ::alfter 必须带一个属性content 内容的前面或者后面插入内容,定义宽高和其他属性时,其实就是一个盒子(必须通过display转换,因为默认是一个行内元素)
24.CSS3 2D转换
1.transform(转换) = tanslate 移动 (x, y) x( )/ y( )
Rotate( 90deg / -90deg) 旋转
scale(x, y) x, y小于1 缩放 大于1放大 不影响其他盒子
skew 倾斜x, y 正值 反方向斜切 x, y 负值 正方向斜切
transition: all 0.2s; /
transition:过渡,有动画过程 ;all代表所有变化属性都做动画*/
23.动画
2. /* 1 声明动画函数 /
3. @keyframes ani_div {
4. 0% {width: 100px;background-color: red; }
5. 50% { width: 150px;background-color: green;}
6. 100% {width: 300px;height: 300px;background-color: yellow;}
7.div { width: 200px; height: 200px; background-color: aqua; margin: 100px auto;
8. /
2 调用动画 / / 持续时间 */
9. animation-name: ani_div; animation-duration: 2s; }
10.动画库animate.css https://www.awesomes.cn/repo/daneden/animate-css
11.3D perspective:1000px(视距) 是给父元素添加的,而transform:translateZ是给子元素添加的
break ,continue ,return 的区别
break :结束当前的循环体(如 for、while)
continue :跳出本次循环,继续执行下次循环(如 for、while)
return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码
24.NODE

Node 必知必会

1、什么是 Node

Node 就是 JavaScript 的一个运行环境
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境

2、Node.js 和 JavaScript 的关系

Node 就是解析 js 的环境,Node 对应的开发语言 JavaScript(ECMAScript)

3、Node.js 和 JavaScript 的区别

Node.js 中没有 DOM 和 BOM
JavaScript 中没有 Node API

4、Node.js 和 JavaScript 的组成部分

Node.js: ECMAScript、Node API
JavaScript: DOM、BOM、ECMAScript

5、Node.js 应用

桌面应用
ruff – 厉哥

Node 解析 js

node 文件名.js

为什么需要模块化

因为 js 没有命名空间的概念,
所以在项目、代码越来越复杂的情况下,js 代码和 js 文件越来越多,并且每个脚本之间有复杂的依赖关系的时候,
就容易产生命名冲突、方法覆盖、文件依赖等等问题
为了解决这个问题了,开始提倡模块化开发,并且出现了很多的模块化规范,
比较出名的有 AMD、CMD、CommonJS 这三大模块化规范
而 Nodejs 就遵循了 CommonJS 规范。

CommonJS 规范是如何定义的

每个文件就是一个模块,有自己的作用域,模块作用域(文件作用域)
在一个文件里面定义的变量、函数、方法,都是私有的,对其他文件不可见。
如果需要把当前模块中的一些私有成员,暴露给其他模块来进行使用,必须使用 exports 这个对象
如果当前的模块需要使用另一个模块中的私有成员,必须使用 require 这个函数
在每个模块内部,都有一个 module 对象,代表当前模块
使用原则:
如果导出单一成员,例如变量、方法可以使用 exports 进行导出
如果导出多个成员,例如类、构造函数,可以使用 module.exports 进行导出

Node 中 没有 window ,它的全局成员是 global

node 中虽然没有 window 全局对象,
在 Node 中,不存在全局作用域的概念,只有模块作用域的概念,
Node 中每个文件就是一个模块,即一个文件就是一个模块,
在这个模块内部定义的对象、属性以及方法,都属于当前的文件模块,外部无法访问
但是有一个类似于 window 的对象,叫 global 对象
可以使用 global 对象,在多个文件模块之间进行共享对象、属性以及方法

global 是 Node 中顶级作用域,
注意在浏览器中,顶层作用域是全局作用域。
在 Node.js 中, 顶层作用域不是全局作用域,作用域只在该模块内
但是容易造成元素覆盖,一般不推荐在 node 中使用 global 进行元素的导出

yarn 是 npm 原团队重新开发的一个依赖管理工具

npm i yarn -g
npm init — yarn init
npm i xx — yarn add xxx
npm uninstall xxx — yarn remove xxx

什么是包

包 就是模块,只不过包是按照一定的规范来进行定义的

node 事件循环机制 、js 异步机制

单线程 + 事件队列
js 是一门单线程语言,从上到下进行解析,
遇到 定时器、ajax、事件,并不会立即执行,会放到 事件队列中
等主线程空了以后,在处理 事件队列中的 定时器、ajax、事件
浏览器:会执行一个事件的循环

js 事件流

事件捕获 --> 处于目标阶段 --> 事件冒泡

什么是中间件

中间件本质函数
中间件,就是用来对数据进行拦截、处理的过程方法,
一个中间件就是一个函数,下一个中间件依赖上一个中间件处理的数据进行逻辑处理
app.use((req, res, next) => {
next()
})

package.json

1、用来管理包,用来管理当前项目中使用的依赖
dependencies – 管理上线以后,需要依赖的模块
devDependencies – 管理开发阶段,需要依赖的模块 – .less .css
JS高级
1、两个编程思想
面向过程与面向对象
2、面向过程式编程
一般也指函数式编程,一个功能一个函数,使用时一个一个调用
关注实现的过程,关注过程中的每一步,什么事情都是亲力亲为
remove() {}
3、面向对象编程
面向过程的一种封装,面向对象就是调用一个对象内部的方法或属性,让其按照封装好的过程,去执行
注意:面向对象是以对象功能处理问题,而不是步骤
4、面向对象的优势是什么 ?
面向对象开发思想中,每个对象都是功能中心,具有明确的分工
面向对象编程具有灵活、代码方便复用、容易维护和开发的优点,适合多人开发的大型软件项目
5、面向对象的三大特性:★★★★★★
封装性、继承性、多态性
封装性
代码高度封装
把过程封装到函数,把函数封装到对象,
你根本不需要关注过程是如何实现的,只需要管结果就可以了
继承性
把代码重复利用
,就是前代把一些东西共享给后生活中的继承代。
在编程中,前辈把代码共享给后辈。
类——分类,从大分类的对象把代码共享给小分类的对象——实现了代码的重复利用
多态性
多种状态—
js本身是不支持多态的
现在只需要知道三大特性里面有一个多态就行,将来学习别的强类型语言的再理解
1、创建类
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
}
var ys = new Person(‘亚瑟’, ‘2’)
2、constructor() 方法
类的构造函数(默认方法),用于传递参数, 返回实例对象,
通过 new 命令生成对象实例时,自动调用该方法。
如果没有显示定义, 类内部会自动给我们创建一个constructor()
3、创建类的流程
(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
(2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
(3) constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
(4) 生成实例 new 不能省略
(5) 最后注意语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function

类的继承
1、 子继父用 extends
2、super 访问和调用父类上的函数。
3、注意: 子类在构造函数中使用super, 必须放到 this 前面
4、继承中的属性或者方法查找原则: 就近原则
1)、继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
2)、继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
使用类三个注意点
1、在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象.
2、类里面的共有属性和方法一定要加this使用.
如果 this 指向发生了改变,那么需要全局定义一个变量 that ,来接收 this ,获取共有属性和方法
3、类里面的this指向问题.
constructor 里面的this指向实例对象, 方法里面的this 指向这个方法的调用者
类中的this指向问题
在 constructor 这个方法内部,this 始终指向的是 实例出来的对象
公共的方法,里面的 this ,谁调用就指向谁
JavaScript 可以在构造函数本身上添加,
也可以在构造函数内部的 this 上添加。称为静态成员和实例成员。
★★★★★★
静态成员(静态方法):在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
实例成员(动态方法):构造函数内部通过this添加的成员,只能由实例化的对象来访问
浅拷贝与深拷贝
浅拷贝出来的数据并不独立,如果被复制的对象改变了,那么浅拷贝的对象也会改变,深拷贝之后就会完全独立,与浅拷贝断绝关系。
22.公司开发流程
1、产品产品提出需求,画出原型图以及需求文档,开需求会议
2、如果通过,设计师开始根据 原型图 进行设计
3、后台开始设计数据库、表,写接口
4、美工把图做好之后,标注好尺寸、以及切好的图片,给我,
5、前端开始写页面、后台接口写好之后,把接口文档丢给我
6、前端开始对接口,
7、上线联调(联合调试) – 我、后台、测试小姐姐一起对项目测试
8、上线
Vue 课程笔记
一、什么是 Token
HTTP 是一种无状态的会话机制,为了保持客户端与服务器端的通信,一般采用三种方式 1. cookie 2. session 3. token
三种保存会话机制的使用区别
不存在跨域问题,可以使用 cookie、session 在客户端保存状态
存在跨域问题,可以使用 token 在客户端保存状态
10.本地存储
sessionstorage
5M 存储在浏览器内存中 离开页面消失 只限当前页面使用
localstorage
20M 存储在计算机硬盘 永不消失 当前浏览器的所有页面使用

生命周期
beforeCreate data 和 methods 还没有被初始化
created data 和 methods 可以进行调用
// 如果以后想最早发送 ajax 请求,获取数据,最早就应该在 created 里面
beforeMount表示代码在内存中已经编译成功,并没有渲染到页面中
mounted表示代码在内存中已经编译成功,并且渲染到页面中,
// ☆☆☆☆☆
// 如果想最早的操作 DOM 元素,获取里面的值,那么最早就应该在 mounted 中进行获取
beforeUpdate页面中显示的数据还是旧的,但是 data 中的数据已经是最新的
Updated // 注意:beforeUpdate 和 update 会根据数据的变化与否有选择的执行 0 次或者 N 次
// 当 执行完 updated ,页面中显示的数据已经是最新的,data 中的数据也是最新的
// 注意:这一步。做了哪些东西呢 ?
// 首页,Vue 根据 data 中的最新的数据生成一份新的 Dom 结构在内存中,
// 当最新的 内存 DOM 树被渲染到 页面中的时候,就完成了 data --> view 成的更新与渲染
beforeDestroy,destroed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据与view的绑定

二、梳理项目结构
1.将多余的文件、文件夹删除
提交空格
三、创建 Login 组件
在 components 文件夹中创建 Login.vue 文件,写创建页面结构
在路由文件中,导入 Login.vue 文件,
在 routes 中配置路由规则
设置重定向
在 App.vue 文件中创建路由占位符
如何构建和优化项目

  1. 如何构建项目
    vue-cli 对项目进行初始化,必要的包进行按需加载
  2. 项目如何优化
    路由懒加载当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
    1.首先安装包:@babel/plugin-syntax-dynamic-import
    在 babel.config.js
    按照如下模式进行更改路由组件
    const Foo = () => import(/* webpackChunkName: “group-foo” */ ‘./Foo.vue’)
    在项目上线之前,使用 babel-plugin-transform-remove-console 按需移除所有的 console.log()
    1.console 需要在开发阶段以及测试阶段打印相关的数据
    console 在发布阶段是不需要打印任何数据的,因为容易打印出敏感数据
    所以需要在发布阶段移除所有的 console ,在开发阶段以及测试阶段不需要移除
    2.为开发模式与发布模式指定不同的打包入口
    1.因为开发模式 是在本地运行开发项目或者测试,并不需要使用CDN 等提高性能的方案
    但是 发布模式 需要将所有的包或者 css 全部转成 CDN 服务,
    那么就需要对 main.js 入口文件进行修改
    为了不造成两个模式的冲突,所以需要给两个模式设置不同的打包入口
    configureWeback - 对象配置
    chainWebpack - 链式操作配置
    通过 externals 加载外部 CDN 资源
    vue-cli 会将依赖项全部进行打包成一个文件:chunk-vendors,会造成这个文件比较臃肿,体积比较大,
    为了解决这个问题,需要 externals 进行加载外部资源
    使用 config.set方式设置不需要打包到 chunk-vendors 中包
    定制首页内容
    开发模式与发布模式共用一个 index.html
    但是开发模式与发布模式入口文件是不一样的
    开发模式所有的资源还在入口文件中,并没使用 CDN
    发布模式所有的资源已经变成了 CDN,并且是在 index.html 文件中进行配置的
    这样就造成资源的浪费另外也容易产生冲突

Vuex
1、Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态(数据)管理库
采用集中式管理的方式处理 Vue 应用中所有需要共享的数据
是基于单项数据流的
2. Vuex 的好处
props
$emit
new Vue
vuex
采用集中式的方式处理数据,方便后期的维护
组件之间传值更高效,从而提高了开发效率
注意事项:
vue – 是双向数据绑定
vuex – 单项数据流
Vuex 核心概念

  1. state
    state 就是唯一定义共享数据的位置
    访问定义的共享数据
    this.$store.state.xxx
    mapState 辅助函数
    mapState 是 Vuex 本身给提供的一个函数
    将 store 中定义的共享数据,转成当前组件的计算属性
  2. mutation
    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
    因为 Vuex 是单项数据流,是不允许直接对 state 中的数据进行修改
    那么如果想修改 state 中的值,必须使用 mutation,
    在 mutation 中定义方法来修改值
    第一种调用的方式
    this.$store.commit(‘xxx’)
    第二种调用方式
    MapMutations

1、var let const 区别 暂时性死区
1、var 声明的变量存在预解析, let、const 不存在预解析

  • 2、var 声明的变量不存在块级作用域的概念, let 声明的变量存在块级作用域的概念
  • 3、var 在同级作用域中可以声明多次,后面的会覆盖前面的, let 在同级作用域只允许声明一次
  • 4、let 声明的变量存在暂时性死区, 在块级作用域内部,必须先声明后使用
  • 5、const 声明的常量,必须在声明的时候,就要进行初始化,否则就会报错
  • 6、在代码块内部,不可以在声明变量之前使用,否则就存在暂时性死区
    2、js 如何实现继承
    1.原型链继承
    将构造函数的原型设置为另一个构造函数的实例对象,这样就可以继承 另一个原型对象的所有属性和方法,可以继续往上,最终形成原型链。
    2.借用构造函数继承
    function SuperType() { this.colors = [“red”, “blue”, “green”]; }
    function SubType() { //继承SuperType SuperType.call(this); }
    将SuperType函数在SubType构造函数中调用,在每个实例中执行,这样每个实例中都 会有一份SuperType中的属性方法的副本,也就实现了继承SuperType。
    3.组合继承
    也叫伪经典继承,将原型链和借用构造函数的技术组合到一块。使用原 型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性 的继承
    4.事件流 事件捕获 目标阶段 事件冒泡
    事件流包括三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。
    阻止事件默认行为(preventDefault)
    阻止事件冒泡(stopPropagation)
    原生 js 中, return false 只阻止事件默认行为,不阻止事件冒泡; jquery 中, return false 都阻止.

1.什么是跨域 怎么解决
【ajax跨域问题:】
原因:
浏览器有一个同源策略即 协议、域名、端口号一直,一个不同就是跨域。
问题:
浏览器拒绝处理ajax请求响应回来的数据。
【方案一:jsonp】----绕过了跨域。
核心:把请求地址放在script标签的src属性上。
客户端:
1)定义一个全局函数
2)把请求地址放在script标签的src属性上,并携带一个参数(函数的名字)。
服务端:
返回一个字符串(一段调用函数的js代码字符串)
缺点:
只能发送get请求
【方案二:CORS跨域资源共享】
核心:2号服务器设置一个响应报文。
// 1.允许哪些客户端访问我
res.header(‘Access-Control-Allow-Origin’, ‘*’)
// 2.允许客户端使用哪些请求方法访问我
res.header(‘Access-Control-Allow-Methods’, ‘get,post’)
缺点:
如果服务器不是自己的。
【方案三:代理】----绕过了跨域。
代理:代为处理(找个代表,发送跨域请求)。
1)1号客户端向1号服务器发送请求
2)1号服务器接收到请求,向2号服务器发送请求。
将2号服务器返回的数据,响应给客户端。
7.get 和 post 请求的区别
get用于获取数据,post用于提交数据。
1.GET是通过URL方式请求,可以直接看到,明文传输。
2.POST是通过请求header请求,可以开发者工具或者抓包可以看到,同样也是明文的。
3.GET请求会保存在浏览器历史纪录中,还可能会保存在Web的日志中。
GET用于从服务器端获取数据
POST用于向服务器提交数据
2.ajax原理
Ajax通过XmlHttpRequest对象来向服务器发送异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。
第一步:创建XMLHttpRuquest对象; 
第二步:注册回调方法 
第三步:设置和服务器交互的相应参数 
第四步:设置向服务器端发送的数据,启动和服务器端的交互 
第五步:判断和服务器端的交互是否完成,还要判断服务器端是否返回正确的数据
3.Promise async 和 await
Promise对象用于异步操作,可以多重链式调用,可以避免层层嵌套回调。
如果我们在第一次ajax请求后,还要用它返回的结果再次请求,层层嵌套结果是这样:
使用Promise,利用then进行链式回调,将异步操作以同步操作的流程表示出来
async 用于申明一个异步的 function ,而 await 用于等待一个异步方法执行完成。
10.面向对象三角形 构造函数 protype proto

① 当访问个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
③ 如果还没有就查找原型对象的原型(Object的原型对象)。
④ 依此类推直找到 Object 为止(null)。
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供个方向,或者说一条路线。
11.Vue生命周期
beforeCreate() {
// 在 beforeCreate 阶段,这时候是 Vue 进行初始化的过程,
// 这时候, data 数据访问不到, 同时,methods 方法也不能不能调用的,
// 这时候,只能访问一些生命周期钩子函数,也可以说就是只能访问 Vue 给提供的一些方法
},
created() {
// 在 created 阶段,这时候 Vue 中的 data 和 methods 已经初始化完成
// 这时候,就能够访问 data 中的数据 以及 methods 里面的方法
// 如果以后想最早发送 ajax 请求,获取数据,最早就应该在 created 里面
},
beforeMount() {
// 这个阶段,是 Vue 对代码进行编译的阶段,如果网速超级慢,那么这时候,能够在页面上看到 插值表达式
// 在这个阶段,Vue 开始从 data 中取数据,取出来数据和 插值表达式以及指令等在进行结合渲染,
// 这个阶段是在内存中进行的,也就是说,这时候在页面上还看不到页面的具体数据
},
mounted() {
// 在这个阶段,模板字符串已经在内存中编译完成,已经插入到真实的 DOM 结构中
// 也就是说这时候,就能够看到真正的数据和模板结合字符串
// ☆☆☆☆☆
// 如果想最早的操作 DOM 元素,获取里面的值,那么最早就应该在 mounted 中进行获取
},
beforeUpdate() {
// 在这个阶段,说明页面中的数据有更新,但是还没有和页面进行同步
// 也就是说此时:数据是最新的,但是页面是旧的
},
updated() {
// 在这个阶段,数据和页面都是最新的,
// 为什么是最新的,
// 因为在调用这个生命钩子函数之前,Vue 又把最新的数据放到 内存中和页面再次进行拼接处理
// 生成模板字符串,并且插入到了 DOM 结构中,所以,这时候数据和页面都是最新的

12.v-if v-show 区别
v-if判断是否加载,减轻服务器的压力,在需要时加载,切换开销较大;
v-show改变元素dispaly属性,使客户端操作更加流畅,初始渲染开销较大。频繁地切换,用 v-show ;运行时条件很少改变,用 v-if。
13. 什么是渐进式框架
Vue是渐进的 没有强主张 你可以只用一部分当做库去使用 也可以用vue全家桶来实现整个的项目
13.嵌套路由获取参数
this. r o u t e . p a r a m s . i d 15. v u e 组 件 之 间 传 值 父 组 件 往 子 组 件 传 值 : 子 组 件 需 要 用 p r o p 来 接 收 组 件 传 递 的 值 , 是 一 个 数 组 子 组 件 往 父 组 件 传 值 : 第 一 步 : 子 组 件 使 用 route.params.id 15.vue组件之间传值 父组件往子组件传值:子组件需要用prop来接收组件传递的值,是一个数组 子组件往父组件传值: 第一步:子组件使用 route.params.id15.vueprop使emit向父组件发送一个自定义事件
第二步: 父组件通过v-on接收自定义事件,属性值对应父组件中的方法
兄弟组件之间传值:
第一步: 创建一个事件中心 也就是创建一个新的vue实例bus,将事件绑定到这个实例上
第二步: 在兄弟1的点击事件上使用bus. e m i t 自 定 义 一 个 事 件 , 携 带 值 发 送 第 三 步 : 在 兄 弟 2 的 m o u n t e d 函 数 中 使 用 b u s . emit自定义一个事件,携带值发送 第三步: 在兄弟2的mounted函数中使用bus. emit2mounted使bus.on接收传递的自定义事件,在回调函数中获取传递的值
16.Vue响应式原理
Vue响应式底层是 Object.defineProperty() 存在getter和setter两个方法
getter是数据变化后渲染页面
setter是改变值,对数据监听
17.Vue组件为什么必须是函数
data值为对象,组件共享一个对象,其中一个组件改变data属性值,其它组件也会受到影响。
data为函数,通过return 返回对象的拷贝,致使每个组件都有自己独立的对象,实例之间可以互不影响的改变data属性值。
18.移动端如何适配页面
视口:布局视口 视觉视口 理想视口
19.你遇到过哪些兼容性问题 怎么解决
1.png24位的图片在ie6浏览器上出现背景
解决方案: 做成png8
2.浏览器默认的margin和padding不同
解决方案:添加一个全局的{margin:0;padding: 0;}
1.ie6双边距bug
解决方案:float的标签样式控制中加入display: inline;将其转化为行内属性
4.图片默认有间距
解决方案:使用float为img布局
5.cursor:hand显示手型在safari上不支持
解决方案:使用cursor:pointer
20.模块化、组件化
为什么需要模块化
因为 js 没有命名空间的概念,
所以在项目、代码越来越复杂的情况下,js 代码和 js 文件越来越多,并且每个脚本之间有复杂的依赖关系的时候,
就容易产生命名冲突、方法覆盖、文件依赖等等问题

为了解决这个问题了,开始提倡模块化开发,并且出现了很多的模块化规范,
比较出名的有 AMD、CMD、CommonJS 这三大模块化规范
而 Nodejs 就遵循了 CommonJS 规范。
在 Node 中,不存在全局作用域的概念,只有模块作用域的概念,
Node 中每个文件就是一个模块,即一个文件就是一个模块,
在这个模块内部定义的对象、属性以及方法,都属于当前的文件模块,外部无法访问
组件化
1、什么是组件化
 组件化并不是前端特有的思想,像后台语言 PHP、Java,都有自己的组件思想
 组件化是一种开发思想,是将整个应用网站,看成是一个个的模块组件
 组件就是将 UI 和 逻辑结构看成是一个整体,也可以理解为就是将 UI 和 逻辑代码封装 成一个单独的文件,
 那么在任何地方使用这个组件,那么 Ui 和 结构看上去都是一样的,从而实现【复用】
 2、组件化开发的优势
 ① 复用,方便后期的重复使用
 ② 易于维护
 3、 web Components 开发规范
 因为每个人开发组件思想、实现功能的方法、逻辑以及 UI 写法是不一样的,
 就会造成,封装的组件比较混乱,
 那么,就出现了一系列的开发规范,比较流行的就是 web Components
 核心思想:就是通过自定义元素进行包装 UI 和 逻辑
 Vue 基本实现了 web Components 的规范
21.js异步原理 单线程+事件队列
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件(回调函数callback)。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
22.spa(单页面应用)

单页面应用:一个项目看上去就只有一个页面
        内部页面的跳转,基本都是通过 ajax 结合 哈希(锚点) 实现
        页面不会重新刷新,都是异步更新

24.清除表单缓存问题
form中加入autocomplete='off’属性,或者在input中加入autocomplete='off’属性
25.flex与float的区别以及作用和属性
flex适用于小的UI元素,单独搭建页面,创建复杂的布局
float刚开始是用来解决图文信息中图片与文本冲突的问题的。布局出现“浮动高度塌陷”的问题,即浮动元素的父元素没有设定高度,当其子元素浮动后,父元素就因为内部没有子元素撑起从而高度变为0
26.路由实现的方式
hash模式和history模式。
hash —— 即地址栏 URL 中的 # 符号 特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。哈希(锚点) 
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由.
27.VUE.js
Vue是渐进式框架。自底向上逐层应用。只关注视图层。
28.Axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特性
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
VUE-CLI 脚手架 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,将 Vue 生态中的工具基础标准化,vue -ui 图形化界面 还有 命令行输入 vue create
Key的作用:列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态,需要使用key 来指定列表中项目的唯一的标识符。
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
提高浏览器运行速度
1减少DOM操作
2 使用外部的JavaScript和CSS
3 将JS脚本放在底部
4 压缩组件
5 减少HTTP请求
6 CSS放在头部
内存泄漏
定义:一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。
1.元素被移除或替换,元素绑定的事件没被移除------使用事件委托
2.闭包可以维持函数内局部变量,使其得不到释放-----将事件处理函数定义在外部,解除闭包
3.未声明的变量;
4.误用this-------使用严格模式 use strict

VUE局部刷新
provide+inject组合 先修改App.vue 到需要刷新的页面引用,使用inject导入然后直接调用即可

MVVM开发思想
响应式,双向数据绑定,即MVVM。是指数据层(Model)-视图层(View)-数据视图(ViewModel)的响应式框架。它包括:
1.修改视图层View层,数据层Model对应数据发生变化。
2.数据层Model变化,不需要查找DOM,直接更新视图层View。
闭包
数组去重
1、Array.filter() + indexOf
方法思路:将两个数组拼接为一个数组,然后使用 ES6 中的 Array.filter() 遍历数组,并结合 indexOf 来排除重复项
2、双重 for 循环
方法思路:外层循环遍历元素,内层循环检查是否重复,当有重复值的时候,可以使用 push(),也可以使用 splice()
3、for…of + includes()
方法思路:双重for循环的升级版,外层用 for…of 语句替换 for 循环,把内层循环改为 includes()。先创建一个空数组,当 includes() 返回 false 的时候,就将该元素 push 到空数组中 。类似的,还可以用 indexOf() 来替代 includes()
4、Array.sort()
方法思路:首先使用 sort() 将数组进行排序,然后比较相邻元素是否相等,从而排除重复项
5、for…of + Object
方法思路:首先创建一个空对象,然后用 for 循环遍历,利用对象的属性不会重复这一特性,校验数组元素是否重复
6、new Set()
ES6 新增了 Set 这一数据结构,类似于数组,但Set 的成员具有唯一性
7、ES6 Filter
给定的条件(一个函数)来返回一个新的数组
7 ES6使用 reduce()
提供的reducer 函数来reduce数组中的元素并且将他们合并为一个新的数组。
数组求和的方法
For for in for of forEach map
var arr = [7, 2, 29, 4];
// for方法
var sum = 0;
for (var i = 0, len = arr.length; i < len; i++) {
sum += arr[i]
}
console.log(‘for’, sum)

var arr = [7, 2, 29, 4];
// for in
var sum = 0;
for (var i in arr) {
    sum += arr[i]
}
console.log('for in', sum)

var arr = [7, 2, 29, 4];
// for of
var sum = 0;
for (var i of arr) {
    sum += i
}
console.log('for of', sum)

var arr = [7, 2, 29, 4];

// forEach
var sum = 0;
arr.forEach((val, index, arr) => {
    sum += val
})
console.log('forEach', sum)

var arr = [7, 2, 29, 4];

// map
var sum = 0;
arr.map((val, index, arr) => {
    sum += val
})
console.log('map', sum)

流浏览器的兼容:主要指css样式兼容
1.浏览器私有前缀
​ 为了兼容老版本的写法
-webkit- 谷歌(blink),苹果(webkit)
-moz- 火狐(gecko)
-ms- IE(trident)
-o- 欧鹏(presto,现在blink)
2.浏览器CSS样式初始化 github中 找Normalize.css,

伪数组转真
1、 声明一个空数组,通过遍历伪数组把它们重新添加到新的数组中 **

var aLi = document.querySelectorAll(‘li’);
var arr = [];
for (var i = 0; i < aLi.length; i++) {
arr[arr.length] = aLi[i]
}
2、使用数组的slice()方法 它返回的是数组,使用call或者apply指向伪数组

var arr = Array.prototype.slice.call(aLi);
3、使用原型继承

aLi.proto = Array.prototype;
var aLi = document.querySelectorAll(‘li’);

console.log(aLi.constructor === Array) //false

aLi.proto = Array.prototype;

console.log(aLi.constructor === Array) //true
4、 ES6中数组的新方法 from()

function test(){
var arg = Array.from(arguments);
arg.push(5);
console.log(arg);//1,2,3,4,5
}
test(1,2,3,4);
路由懒加载
当打包构建应用时,JS包会变得很大,影响页面加载,把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应组件
具体实现 安装包@babel/plugin-syntax-dynamic-import
在babel.config.js声明插件
更改路由组件 const Foo = () => import(/*webpackchunkName
图片懒加载
1.懒加载原理
一张图片就是一个标签,浏览器是否发起请求图片是根据的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。

2.懒加载思路及实现
实现懒加载有四个步骤,如下:
1.加载loading图片,(假图片)
2.判断哪些图片要加载【重点】根据可是窗口区域判断
3.隐形加载图片
4.替换真图片

typeof和instanceof的作用和区别?
typeof :返回值为字符串,该字符串用来说明运算数的数据类型
instanceof用于判断某个变量是否是某个对象的实例,返回值为true或false

go(-1)后退之后触发了哪些钩子函数
Beforecreate()/created()/beforemounted()/mounted

盒子水平居中
1.大盒子内一个小盒子 都设定宽高 然后给大盒子设置display:flex布局 使用justify-content: center;//实现水平居中 align-items: center;//实现垂直居中
2.给父盒子相对定位
给子盒子绝对定位
top、right、bottom、left全为0
margin: auto;
3.给父元素相对定位
给子元素绝对定位
left: 50%;top: 50%;
margin-left: 负的宽度一半。
margin-top: 负的高度一半;
1、为什么需要计算属性,什么是计算属性

  在模板中使用表达式非常的便捷,但是如果在其中写很多的逻辑代码,
  那么程序就会非常难以维护,
  插值表达式中诞生的目的是做一些简单的运算,
  如果在里面写很多太复杂的逻辑,代码看起来非常冗余,缺少可读性

  所以:就提供了计算属性,
  目的:将表达式的代码进行提取,提取到计算属性中

2、计算属性和方法的区别

  ① 计算属性存在缓存,methods 里面的方法不存在缓存

  ② 计算属性因为依赖于 data 中的数据,主要 data 中的数据没有发生变化
    那么在使用计算属性的时候,结果始终从缓存中进行取值

    methods 里面的方法每次都是重新运算或者执行相应的逻辑

1、 侦听器是什么东西

    侦听器就是用来对 data 中的数据进行监听,
    当数据发生改变之后,就会触发 watch 中绑定的方法
    
    在侦听器方法中就可以获取到更新之后的最新值以及老的值
    
    用来用一些异步操作和复杂的运算
  
  
  2、侦听器注意事项
  
    ① 侦听器 也是和 data 同级进行声明 一个 watch

    ② 侦听器的属性不能随便写,需要是 data 中的数据,
      也就是对谁进行监听,就写谁
  
    ③ 在回调函数中,有两个参数
      第一个参数是更新之后的值,也就是最新的值
      第二个参数是更新之前的值,也就是老的值
  1. 什么是过滤器
    就是对文本值、时间等进行格式化的方法

    1. 两个定义方法
      全局定义 – Vue.xxx
      局部定义 – filters

    2. 全局定义

    ① 需要挂载 Vue 上面,Vue.filter ,不带 s

    ② 有两个参数 ,第一个参数是 过滤器的名称, 第二个参数是 一个方法
    方法中有个参数,这个参数就是指所需要处理的数据

    ③ 函数内部需要 有 return,需要有返回值

    ④ 如果需要使用多个过滤器,直接使用竖线分隔 | ,后面跟上另一个过滤器名称就可以

    1. 局部定义

    filters: {}
    2.拦截器
    请求拦截器–后台要求发送请求时添加请求头,否则不返回数据,要求加再加 需要return出来修改后的配置,后台不要求不加
    响应拦截器–如果后台返回的数据不是我们想要的格式,则需要添加响应拦截器,先对先通过拦截器拦截处理,return出来处理后的数据

什么是 Promise
Promise 是 ES6 新增的一个特性,其实是一个构造函数,为了解决回调地狱问题
async 和 await – 回调地狱终极解决方案

  ① es7 新语法

  ② async 和 await -- 底层是对 Promise 再次进行了封装

  ③ async 一般用来修饰函数,一般放在函数名前面

  ④ async 和 await 必须结合使用

导航守卫
也是路由守卫,路由拦截,通过路由拦截,判断用户是否登录,用户是否有权限浏览

登录 login 页面

首先创建项目( vue ui ) 然后下载 配置 element - ui 下载配置依赖 less / less-loader

梳理项目文件夹 准备工作完毕以后 正式进行开发

login 页面 先进行样式搭建 然后在通过 element - ui 中的 form 表单这个组件 把组件中的

input框导入项目中 给 input 添加 icon 图标 然后把 button 按钮组件进行导入 搭建完整体

结构后 对数据进行双向绑定 在 el-form 上绑定一个属性 model ,对应data中的一个数据对象

同时在 data 中,声明一个数据对象 在 input 框中, 使用 v-model 绑定数据对象中的值, 当数据

都绑定好以后 进行表单的验证, form组件已经提供 直接使用就OK 给 el-form 属性添加:rules

属性, 对应一个规则验证对象 给el-form-item 添加 prop 属性, 对应规则中的某一个规则属性

对表单验证结束以后 当用户输入错误信息时 可以重置 所以需要做一个重置的功能 首先el-form

绑定一个 ref 属性 它指向当前对象的实例对象, 给重置按钮绑定点击事件 对应一个事件处理程序,

在事件处理程序中 使用 this.$refs.ref属性的值.resetFields() 进行重置 重置结束以后 在登录前要

对表单的值再次进行校验 给登录按钮绑定事件 使用 this.$refs.XX.调用文档提供的 validate 方法

对表单所有的值进行校验 在 validate 方法回调函数中 接收一个参数 返回对表单的验证结果, 验证

通过 , 结果为 true 验证失败 结果为 false 此时发送 axios 请求 在入口文件中导入 axios 然后使用

axios.defaults.baseURL 绑定根域名地址 在使用 Vue.prototype.$http 将 axios 挂载到Vue的原型

上. 这样以后每一个组件都可以使用 this.$htt.XX 来请求接口 , 在点击登录以后,会对输入的值进行判

断,如果输入符合规则 返回的是true 否则为 false 是false 阻止程序运行 若是true 发送axios请求 使

用异步的 async 和 await 修饰方法, 使用解构获取 data 对获取到的值进行判断 在element.js中,导入

message 将message挂载到Vue的原型上 this.prototype.$message 那么在组件中 就可以使用 this.

m e s s a g e . s u c c e s s ( ) 或 t h i s . message.success()或 this. message.success()this.message.error()来进行登陆成功和登录失败的弹框提示 当登陆成功后

将登录成功后的 token 保存到 sessionStorage 中 然后通过编程式导航 跳转到后台主页 然后设置一

个路由导航守卫来控制访问权限 进入后台页面后 如果想要退出 就清空token 用window.sessionSt

orage.clear() 就可以清空token 此时 重新进行路由跳转 重定向到登录页面

页面主体区域的绘制

第一步 设置整体结构 从 element 的组件中, 复制 container 布局区域的代码 进行整体骨架的搭建 给

父盒子设置高度 100% 然后给每个区域设置背景色

第二步 对头部进行基础的布局和美化 从 element 的 navigator组件区域复制 NavMenu 导航菜单区域

的代码 在element.js文件中进行导入和绑定 然后对复制的代码 进行删除和改造

第三步 设置拦截器 从axios 文档中 查找拦截器 将相关的代码黏贴到代码结构中 根据文档要求,给请求头

添加一个字段 然后 return 配置

第四步 在生命周期中获取最新的分类数据 最早获取的数据只能在 created 生命周期中 使用 axios 获取请

求的数据, 用解构赋值的方式获取真正的数据 然后判断状态值 ,看状态值是否为200 是的话 就将值赋给 menulist

分类数据对象 否则则提示失败

第五步 使用双层for循环遍历左侧导结构 一级分类 使用v-for 对导航数据 menulist 进行遍历, 同时添加:key属性 为了保证

展开的唯一性 需要给index绑定对应的值 值为字符型 二级分类 使用v-for渲染一级分类数据中的 children属性 同时绑定key

值 同时 将index 动态绑定

第六步 给一级二级分类添加icon图标 一级分类这边使用了一个技巧 将图标全部定义为一个对象 iocnObj 实行是分类的id值

属性值为分类的图标 在页面中使用对象绑定的方法 绑定iconObj类名

第七步 折叠导航栏 创建结构并布局 官方查找相关属性 是否折叠左侧导航 是否开启折叠动画 点击折叠 改变 collapse的值就

可以实现折叠效果 根据 collapse 的值 给 el-aside 动态绑定宽度 用三元表达式

第八步 将左侧导航设置成路由模式 根据文档,给menu标签添加router属性 将结果赋值为 true ,可以将左侧导航栏设置为 router

模式 然后就可以实现跳转

第九步 点击导航栏高亮 根据手册给 menu 添加 default-active 属性 在data 中声明变量 activePath, 同时绑定 给二级导航添加

点击事件,同时传入路由 声明事件处理程序 将接受的路由保存到本地 将值给 activePath 赋值 在created 生命周期中 取值给

activePath 赋值

用户列表功能

第一步 创建组件 在router.js 文件夹中 引入组件 创建路由

第二步 用 element 组件实现相关的布局 头部区域 用面包屑导航 然后下面是一个 card 卡片组件 在卡片组件中 放一个 input组件

来做搜索框 在搜索框后面 放置一个 button 按钮 来用做添加按钮

第三步 根绝接口文档 定义请求参数 queryInfo 在 created 中调用获取列表的方法 getUserList()

第四步 在 methods 中声明方法 getUserList() 使用this.$http.get() 发送请求 返回 Promise 异步数据, 并对其进行解构赋值 对返回

的结果进行判断 给出提示 将成功的结果在进行赋值

第五步 使用 el-table 渲染表格

H5新增
语义化标签:header footer section nav aside article
localStorage / sessionStorage代替cookie本地存储
geolocation 定位/ canvas 绘画 video/audio视频/音频
CSS3新增
flex布局 边框 @media媒体查询 过渡transition
代码规范
标签名小写html body div 标签闭合 加/ 空行和缩进 文件后缀如.css .js 等

什么是 AJAX ?
后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。实现不重新加载整个网页的情况下,对网页的局部进行更新。创建XMLHttpRequest 对象 (异步的与服务器交换数据),发送httprequest请求,服务器处理返回数据,使用JS处理数据并更新内容
xmlhttp.open(“GET”,“ajax_info.txt”,true);
xmlhttp.send();
破坏浏览器前进、后退按钮的正常功能
开发和调试工具的缺乏
jQuery
jquery发送ajax请求 $.ajax() $.get()请求数据 $.post()提交数据

  1. Vue 有哪些指令?
    v-html、v-show、v-if、v-for等等
  2. v-if 和 v-show 有什么区别?
    v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会控制这个 DOM 节点的存在与否。当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。
    v-if 与 v-for 
    一起使用时,v-for比v-if更高的优先级,这意味着v-if将重复运行于每个v-for循环中
    所以,不推荐同时使用
    8.vue中Computed 和 Watch的使用和区别
    1、计算属性computed适用的情形
    一个数据属性所依赖的属性发生变化时,也要发生变化,这种情况下使用计算属性。
    如果我们使用监听函数,代码就会变得有点冗余。
    2、监听器watch适当的情形
    watch函数适用于,当数据发生变化时,执行异步操作或较大开销操作的情况。
    9.知道什么是vuex吗?
    简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一个组件里进行获取、进行修改,并且你的修改可以得到全局的响应变更。
    核心概念1: State
    state 用于保存所有组件的公共数据.
    核心概念2: Getters
    我将getters属性理解为所有组件的computed属性, 也就是计算属性. vuex的官方文档也是说到可以将getter理解为store的计算 属性, getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
    核心概念3: Mutations
    我将mutaions理解为store中的methods, mutations对象中保存着更改数据的回调函数,该函数名官方规定叫type, 第一个参数是state, 第二参数是payload, 也就是自定义的参数.
    核心概念4: Actions
    actions 类似于 mutations,不同在于:actions提交的是mutations而不是直接变更状态actions中可以包含异步操作, mutations中绝对不允许出现异步actions中的回调函数的第一个参数是context, 是一个与store实例具有相同属性和方法的对象

猜你喜欢

转载自blog.csdn.net/weixin_48116269/article/details/109172521