数组方法
array.push >>> 末尾添加元素,返回新长度,返回修改后的参数
array.pop >>> 删除最后一个,返回被删除的数据
array.unshift >>> 最前面添加一个数据,返回数组新长度
array.shift >>> 删除最前面数据,并返回被删除的数据
array.reverse >>> 反转数据,返回反转后的数据
定位:
通过 position 属性进行定位的设置
static 默认值,可以不设置
relative 相对定位在确定元素默认位置后通过设置left,top,right,bottom,进行定位到,
但元素的空间还保留在原位
absolute 绝对顶定位,会把元素移出正常的文档流,后面的元素会挤占他的空间,
他会相对于他的包含元素进行定位,如果其包含元素都没有定位属性那么就是相对于其
fixed 固定定位,包含元素是浏览器窗口,无论页面怎么滚动他都会在同一个位置
sticky 相当于relative 和 fixed 的结合体,他可以让元素在距离头部一定位置把他变成固定位置,
· 其他情况下还在固定的文档流之中
注意:通过z-index 可以设置z轴偏移
将元素居中有几种方式
这里提供10种方式
方式一
.father {
display: flex;
/* 主轴方向样式:居中 */
justify-content: center;
/* 侧轴方向样式:居中 */
align-items: center;
}
方式二:
.father {
display: flex;
}
.son {
margin: auto;
}
方式三
.father {
display: flex;
}
.son {
/* align-self 脱离之前的父级的控制 */
align-self: center;
margin: auto;
}
方式四 css3 最新布局方式是一种二维布局,不同于flex一维布局,其更加强大 grid 布局
.father {
display: grid;
}
.son {
/* align-self 脱离之前的父级的控制 */
align-self: center;
justify-self: auto;
}
方式五
.father {
display: flex;
}
.son {
margin: calc(50% - 75px) auto 0 auto;
}
方式六
.father {
position: relative;
}
.son {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
方式七
.father {
position: relative;
}
.son {
position: absolute;
left: 50%;
top: 50%;
/* 以其原点移动其自身大小的50% translate >>> 平移 */
transform: translate(-50%, -50%)
}
响应式布局
前端媒体查询是响应式网站开发的基础
防抖 >>>
用户触发事件过于频发,只需要最后一次事件的触发
利用计时器实现防抖
节流 >>> 控制执行次数
事件出发后让函数执行一次,在设置的时间段函数禁用,过了这个时间段才可以使用
作用:控制高频事件执行次数
一、css
1、介绍一下css的盒子模型
Css的盒子模型有哪些??? 标准盒子模型、IE 盒子模型
两者的区别:
标准盒子模型
margin、border、padding、content
IE盒子模型:margin、content(border + padding + content)
如何通过CSS转换盒子模型
box-sizing: content-box; 标准版盒子模型
box-sizing: border-box; IE 盒子模型
2、在css中哪些属性可以继承哪些属性不可继承
可继承 >>> 文字系列 >>> font-size、color、line-height、text-align …
不可继承 >>> border/ padding / margin 。。。
3、display 有哪些值?说明他们的作用
none >>> 隐藏元素
block >>> 把某元素转换为块元素
inline >>> 转化为内联元素
inline-block >>>转换为行内块元素
4、对 BFC 规范的理解
BFC 就是页面上一个隔离的独立容器,容器里面的子元素不会影响到外面的元素
了解bfc >>> 块级格式化作用域
bfc原则 >>> 如果一个元素具有bfc ,那么内部元素怎么呢欧诺个,都不会影响到外面的元素
如何触发
float 的值非 none
overflow 的值为 visible
display 的值为 inline-block、table-cell。。。
position 的值为 absoute、fixed
5、清除浮动的方式
1、触发BFC
2、多创建一个盒子,添加样式:clear:both
3、通过伪类after方式
选择器:after {
content: '';
display: block;
clear: both;
}
6、定位position 有哪些值?分别是根据什么定位
static 【默认】没有定位
fixed 固定定位,相对于浏览器窗口定位
relative 相对于自身定位,不脱离文档流
absolute 相对于第一个有relative 的父元素定位,脱离文档
7、弹性盒子
**注意:**弹性容器外及弹性子元素内是正常渲染的,弹性盒子只定义了弹性子元素如何在弹性容器内布局。弹性子元素通常在弹性盒子内一行显示。默认情况每个容器只有一行。
下表列出了在弹性盒子中常用到的属性:
属性 | 描述 |
---|---|
display | 指定 HTML 元素盒子类型。 |
flex-direction | 指定了弹性容器中子元素的排列方式。 |
justify-content | 设置弹性盒子元素在主轴(横轴)方向上的对齐方式。 |
align-items | 设置弹性盒子元素在侧轴(纵轴)方向上的对齐方式。 |
flex-wrap | 设置弹性盒子的子元素超出父容器时是否换行。 |
align-content | 修改 flex-wrap 属性的行为,类似 align-items, 但不是设置子元素对齐,而是设置行对齐。 |
flex-flow | flex-direction 和 flex-wrap 的简写。 |
order | 设置弹性盒子的子元素排列顺序。 |
align-self | 在弹性子元素上使用。覆盖容器的 align-items 属性。 |
flex | 设置弹性盒子的子元素如何分配空间。 |
8、如何布置响应式布局
二、JavaScript
1、es6的新特性
ES6新增特性常用的主要是:let、const、箭头函数、模板字符串,解构赋值、模块的导入(import)、导出(export、 expropt default),promise、还有一些数组字符串的新方法。
作用域
作用域 >>> 变量的作用域是程序代码中的一个区域,在这个区域内变量有意义的,作用域最大的用处是隔离变量,是的作用域之间的变量是相互独立的,互不影响的,即使是同名变量,只要在不同的作用域内就不会冲突。
在 JS 中,有三种作用域:全局作用域,函数作用域,块级作用域
2、var、let、const 声明变量
var / let / const 共同点都是可以声明变量
区别一:
var 具有变量提升的机制
let 和 const 没有变量提升的机制
区别二:
var 可以多次声明同一个变量
let 和 const 不可以多次声明同一个变量
区别三:
var、let 用于声明变量
const 用于声明常量
重点:var 和 let 声明的变量可以再次赋值,但是const 不可以再次赋值。
区别四:
var 声明的变量没有自身的作用域
let 和 const 声明的变量有自身的作用域
3、合并对象的方式
方式一:assign 方法
Object.assign(a,b)
方式二:通过扩展运算符
let 变量名 = {...a, ...b}
方式三:自己封装
function extend (targe, source) {
for(var key in source) {
target[key] = source[key];
}
return target;
}
console.log(extend(a,b));
this
1、默认绑定规则 console.log( this === window); // 返回值 >>> true 独立调用也指向window
2、隐式绑定规则 谁调用就指向谁(方法调用指向方法,window调用指向window)
当出现隐式丢失,和参数赋值会导致绑定失败
3、显示绑定:call,apply,bind
4、new 绑定(new的优先大于显示绑定)
5、箭头函数
4、箭头函数和普通函数的区别
1、this 指向的问题
箭头函数中的 this 只在箭头函数定义时就决定的,而且是不可修改的(call、apply、bind)
箭头函数的this 指向的是外层第一个普通函数的指向
2、 箭头函数不能new (不能当做一个构造函数
3、 箭头函数没有 prototype
5、 箭头函数内部没有 arguments 对象
arguments是一个对应传递给函数参数的类数组对象;
使用场景:针对同一个方法被多处调用,但是参数数量不确定的情况下,可以更具arguments索引进行判断
arguments对象是所有非箭头函数都有的一个局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处
arguments对象并不是一个数组,他除了length和索引元素之外,任何数组的属性都没有
4、promise 的几种状态
有三种状态:
pending (进行中)
resolved(已成功)
rejected (已失效)
promise 是一种异步编程解决方案,比传统的解决方案--回调函数和事件更加合理更加强大
Js中进行异步编程的新的解决方案(传统的解决方案——回调函数和事件),用于表示一个异步操作的最终完成 (或失败), 及其结果值.。
语法上:promise是一个构造函数
简单来说,promise对象用来封装一个异步操作并可以获取其结果
executor:executor是带有 resolve 和 reject 两个参数的函数 。
Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor
(executor 函数在Promise构造函数返回所建promise实例对象前被调用)。resolve 和 reject 函数被调用时,
分别将promise的状态改为fulfilled(完成)或rejected(失败)。
executor 内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功/失败),
要么调用resolve函数来将promise状态改成fulfilled,要么调用reject 函数将promise的状态改为rejected。
如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。
promise 有三种状态
Pending(进行中,初始状态,既不是成功,也不是失败状态。)、Resolved(已完成,又称 Fulfilled)、Rejected(已失败)
这三种状态的变化途径只有2种:
异步操作从 未完成 pending => 已完成 resolved
异步操作从 未完成 pending => 失败 rejected
状态一旦改变,就无法再次改变状态,这也是它名字 promise-承诺 的由来,一个promise对象只能改变一次
5、数组方法中 find 和 filter 的区别
用于查找条件相符的元素
区别一:返回的内容不同
filter 返回的是新数组,原来的数组不会改变
find 返回具体的某一个内容
区别二:
find 匹配到第一个即返回
filter 返回所有匹配元素的整体(没有一个匹配到的都返回)
arr.filter(val=>{return 条件})
1、创建新数组
2、不改变原数组
3、输出的是判断为true的数组元素形成的新数组
4、回调函数参数,item(数组元素)、index(序列)、arr(数组本身)
5、使用return操作输出,会循环数组每一项,并在回调函数中操作
6、数组方法中 some 和 every 的区别
some >>> 如果有一项匹配就返回 true
every >>> 全部匹配才会返回 true
7、JS 判断变量是不是数组,你能写出哪些方法
方法一 :isArray
Array.isArray(变量名)
方法二:instanceof[可写可不写]
变量名 instanceof Array
方法三: Object.prototype.toString.call(变量名).indexOf('Array') >>> 大于-1就是数组
方式四:.isPrototypeOf
Array.prototype.isPrototypeOf(变量名)
方式五: constructor
变量名.constructor.toString().indexOf('Array') > -1
8、slice 是干什么的、splice 是否会改变原数组
1、slice 是来截取的
参数可以写 slice(3)/slice(1,3)/slice(-3)
返回一个新的数组,并不改变原来的数组
2、splice 功能有:插入、删除、替换
返回:删除元素构建的数组
该方法改变原来的数组
9、延时加载 JS
延时加载的方法有两种 >>> async、defer
例如: <script defer type="text/javascript" src="路径"></script>
<script async type="text/javascript" src="路径"></script>
defer: 等html全部解析完成,才会执行js代码,水刺执行js脚本。
async: async 是和html 解析同步的(一起的),不是顺次执行js 脚本(谁先加载完谁先执行)
10、null 和 undefined 的区别
作者在设计 js 时是先设计的null
null会被隐式转换为0,很容易发现错误
先有null 后有 undefined >>> 是为了填补之前的坑
js的最初版是这样区分的:null 是一个表示无的对象,转为数值是0
undefined 是一个表示无的原始值,转换为数值是为 NaN
11、== 和 === 的区别
== 只比较值,
string == number || boolean || number ... 都会因式转换
通过 valueOf 转换 (valueOf() 方法通常由JavaScript 在后台自动调用,并不显示在代码中)
=== 既比较值还比较类型
12、Js微任务 和 宏任务
1、js 是单线程语言。
2、js 代码执行流程:同步执行完 ===> 事件循环
同步的任务都执行完了,才会执行事件循环的内容
进入事件循环:请求、定时器、事件。。。
3、事件循环中包含【微任务、宏任务】
微任务:promise.then
宏任务:setTimeout.、回到函数
要执行宏任务的前提是清空了所有的微任务
流程:同步 >>> 事件循环【微任务和宏任务】 >>> 微任务 >>> 宏任务 >>> w >>> h ...
13、js 作用域考题
1、除了函数外,js 是没有块级作用域的
2、作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量
注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。
3、注意声名变量是 var还是没写 window.,都是全局作用域
4、var 的声明变量具有变量提升的机制 【变量悬挂声明】
14、Js 对象
JS对象注意点
1、对象是通过 new 操作符构建出来的,所以对象之间不相等(除了引用外)
2、对象注意:引用类型(共同一个地址)、
3、对象的key 都是字符串类型
4、对象如何查找 属性/方法
查找规则:现在对象本身找 >>> 构造函数中照 >>> 对象原型中找 >>> 构造函数原型中找 >>> 对象上一层原型中找
15、什么是闭包
1、闭包是什么
闭包是打通了一条在函数外部访问函数内部的通道
2、闭包可以解决什么问题【闭包的优点】
2.1 内部函数可以访问到外部函数的局部变量
2.2 闭包可以解决如下问题
var lis = document.getElementsByTagName('li');
for(var i = 0; i < lis.length; i++) {
(function(i) {
lis[i].onclick = function() {
alert(i)
}
})(i)
}
3、缺点
变量会驻留在内存中,造成内存损耗问题
解决:把闭包的函数设置为null
内存的泄露【ie版本】 >>> 可说可不说,如果一定要说要提ie浏览器
16、原型
1、原型可以解决什么问题
对象共享属性和共享方法
JS 中每个对象都有一个与之相关联的对象叫原型对象
每次获取对象属性都是一次查询的过程,在对象的自有属性中找不到就会去查找其原型对象
2、谁有原型
函数拥有:prototype
对象拥有:__proto__
3、对象查找属性或者方法的顺序
现在是对象本身查找 >> 构造函数中查找 >> 对象的原型 >> 构造函数的原型中 >>> 当前原型的原型中查找
4、原型链
是什么?就是把原型串联起来
原型链的最顶端是null
17、继承
方法一 >>> ES6 的方法 父 extends 子 {继承的方法(){super(); this.新增属性}}
class Parent {
constructor() {
this.age = 15
}
}
class Child extends Parent {
constructor() {
super();
this.name = '张三';
}
}
let o1 = new Child();
console.log(o1, 01.name, o1.age)
方法二:原型链继承 >>> ,prototype = new 构造函数 >>> 见复习中的 继承文件
方法三:借用构造函数继承 >>> 父.call(this, name)
方法四:组合继承
18、说一下 call、apply、bind 区别
共同点:功能一致
可以改变 this 指向
语法:函数.call(this, 参数2 ...)、.apply(数组形式参数)、函数.bind(this, 参数1, 参数2 ... )
区别:
1、call、apply 可以立即执行、bind不会立即执行,因为bind返回的是一个函数需要加入()执行
2、参数不同、apply 第二个参数是数组。call和bind 有多个参数需要挨个写
19、深拷贝和浅拷贝
共同点:复制
1、浅拷贝,只复制引用,并没有创建新的内存地址来存储数据
方式一:
var arr1 = ['a', 'b', 'c'];
var arr2 = arr1
方式二:
var obj1 = {a:1, b:2}
var obj2 = Object.assign(obj1) >>> 通过Object.assign(浅拷贝对象) 方法进行浅拷贝
2、深拷贝:是复制真正的值(不同于引用)
方式一:
var obj3 = {a: 1, b: 2}
var obj4 = JSON.parse(JSON.stringify(obj3));
方式二:自己写一套递归的操作
function copyObj (obj) {
var newObj = {};
for(var key in obj) {
if( typeof obj[key] == 'object' ) {
newObj[key] = copyObj(obj[key]);
}
else {
newObj[key] obj[key]
}
}
return newObj
}
console.log( copyObi(obj1) )
20、面向对象
面向对象是一种编程思想,将所需要做的功能抽象为一个对象,然后反复调用这个对象来完成所需的功能
ES5
创建对象
function 类对象 () {} >>> new 类名称 >>> 对象 【类的实例】
{}
Object
面向对象的三大特征:
封装:方法 属性风转到类内部
继承:子类可以继承父类的属性和方法
多态:同一个方法,子类和父类中内容不同
面向对象的优势:易于维护、提高代码质量
遍历对象:
for..in
对象转换为字符串:
{} >>> string 方法: JSON.stringify()
string >>> {} 方法: JSON.parse()
this 四种绑定方式
默认绑定 function 方法() {this}
隐式绑定 function a () {this} ==> obj = {obj:a} this ---> obj
显示绑定 fun.call(obj) ===> fun 中的this ---》 obj
new绑定 p = new xxxx this--》p
继承:原型链继承、构造函数继承、组合继承
设计模式;单例模式,工厂模式,观察者模式,订阅模式
ES6
class 类名称 js向后台语言靠近
static 静态属性属性
constructor 构造函数
super 父类构造函数
extends 继承关键字
21、如何去除字符串中的空格
function mrl (str) {
let reg = /\s+/g
if(typeof str === "string") {
var trim = str.replace(reg, '')
}
}
22、跨域的解决方案
跨域产生的原因
一个域名的地址的组成包含:协议、子域名、主域名、端口号、请求资源地址
js 出于安全考虑,几只调用不同源的端口
同源是指:协议、域名、端口相同
1、通过 jsonp 跨域
jsonp 是应用JSON 的一种新方法,只不过是被包含在函数调用中的JSON
他的基本思想是:网页通过添加一个
2、前端代理
前端代理是我在vue 中主要通过vue脚手架的config中的index文件来配置,其中有个proxyTable来配置跨域
3、websocket
websocket 是html5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案
三、 Vue
1、模块之间的传值方式有哪些
父传子 >>> 子组件通过props 属性进行调用父组件的值
第一步:
通过引入在 father 组件中引入 son
import son from './son'
第二步:
在计算属性中引入
components: {
son
}
第三步:
在 template 中引用 son 标签
并将数据传递到 son 组件中
<son :自定义名='父组件的值名'></son>
第四步:
在子组件中通过 props 属性进行调用 父组件的值
props: ['自定义名']
或
props: {
'自定义名': 数据类型
}
子传父 >>> 子组件通过this.$emit 方法传递,父组件通过在子组件的标签 绑定方法 获取子组件值
子组件
this.$emit(‘方法名’, 要传的数据);
父组件:
<son @方法名=‘getVal’>
` methods: {
getVal(msg) {
msg 是子组件传递的数据
}
}
兄弟传值 >>> 通过创建一个bus中间件,传值组件通过 bus. e m i t 进行传递,接收组件通过 b u s . emit进行传递,接收组件通过bus. emit进行传递,接收组件通过bus.on进行接收
A兄弟传值:import bus from ‘@/common/bus’
bus.$emit(“toFooter”, this.msg);
B兄弟接收:import bus from ‘@/common/bus’
bus.$on(‘toFooter’, (data) => {
this.str = data;
})
vueX 传值 >>>
2、Vue 生命周期有哪些
四个阶段:创建,挂载,更新,销毁
创建前:beforeCreate 创建后:created
挂载前:beforeMount 挂载后:mounted
更新前:beforeUpdate 更新后:updated
销毁前:beforeDestroy 销毁后:destroyed
一旦进入到页面或者组件,会执行哪些生命周期,顺序是什么
创建前:beforeCreate 创建后:created
挂载前:beforeMount 挂载后:mounted
在哪个阶段有 $el ,在哪个阶段有 $data
创建前:beforeCreate >>> 啥都没有
创建后:created >>> 有data没有el
挂载前:beforeMount >>> 有data没有el
挂载后:mounted >>> 都有
3、ref、 r e f s 、 refs、 refs、el 有什么区别,分别是什么意思
ref (给元素或者子组件注册引用信息) 就像你要给元素设置样式,就需要先给元素设定一个 class 一样,同理,你想获取哪个元素的 DOM,就给这个元素先设定一个 ref,其实这里和 JS 中的 document.各种方法获取 DOM 差不多,不过 ref 是访问 VUE 虚拟出来的DOM,这样可以有效的减少性能消耗
简述三者区别:
ref :是 元素的属性,用于设置在元素上
$refs :是 ref 的集合,集合里面包含了当前.vue中的所有 ref
用于获取普通元素中的 DOM 以及 子组件中方法/参数的
$el :是 用于获取组件内 DOM(包括子组件,当前.vue组件,以及父组件)
DOM >>> 文本对象模型
4、谈谈你对 keep-alive 标签的理解
1、是什么
vue 系统自带的一个组件,功能:是用来缓存组件的 >>> 可以提高性能
2、使用的场景:
就是缓存组件,提升项目性能。
具体事例比如:首页进入到详情页,如果用户在首页每次点击都是相同的,那么详情页就没必要请求N次了,直接缓存起来就可以了,当然如果垫底的不是同一个,那么就直接请求
3、加入 keep-alive 时,第二次或者第N次进入组件会执行的生命周期
activated 钩子被调用,服务器渲染期间不会调用
deactivated 钩子函数,keep-alive 组件停用时被调用 ,服务器渲染期间不会调用
5、v-if 和 v-show 的区别
v-if 和 v-show 都是像是和隐藏一个元素,但是有本质的区别。
v-if 是创建一个 dom 节点,是惰性的,只是值为false 就不回加载对应的html代码,为 true 才会动态加载对应元素
v-show 是无论是true 或 false 都会加载对应的html 代码,但是为false时用 display:none 隐藏不再页面显示,但是为true 用 display: block 显示其效果
使用场景:
初次加载 v-if 比 v-show 好,页面不会多加载这个盒子
频繁切换 v-show 比 v-if 好,创建和删除的开销太大了,显示和隐藏开销较小
6、v-if 和 v-for 优先级
v-for 的优先级要比 v-if 的优先级高
7、ref 是什么
ref 是用来获取 dom 元素的各种属性方法
第一步;
给标签加 ref 属性
<标签名 ref="自定义名字">
第二步:
通过 this.$refs.自定义名字 调用
7、nextTick 是什么
vue 中的nextTick 主要用于处理数据动态变化后,Dom 还未及时更新的问题,用 nexTick 就可以获取数据更新后的DOM的变化
8、scoped 原理
scoped 是用来进行 >>> 样式私有化
作用:让样式只在本组件中生效
原理:给元素的节点新增加一个自定义属性,然后css根据属性选择器添加样式
9、如果使用scss
需要下载 cnpm install sass-loader node-sass -save
在style 中添加 lang=“sass”
10、computed/methods/watch 有什么区别
1、computed VS methods 的区别
methods 中都是封装好的函数,只要触发就会执行
computed 是 vue 独有的特性计算属性,可以对 data 中的依赖项再重新计算,得到一个新值,应用到视图中,和methods 本质区别就是 computed 是可以缓存的,也就是说,computed 中的依赖项没有发生变化,则computed就不会重新计算,而 methods 中的函数是没有缓存的。
2、computed VS watch 的区别
watch 是监听 data 和计算属性中的新旧变化
watch 是监听,数据或路由发生了改变才能响应
computed 计算某一个属性的改变,如果某一个值改变了,计算属性会监听到进行返回
watch 是当前监听到数据改变了,才会执行内部代码
11、vue 用什么绑定事件、用什么绑定属性
用 v-on 绑定事件 ,简称@事件名
用v-bind 绑定属性:简称 :属性名
12、props 和 data 优先级谁高
props ==> methods ==> data ==> computed ==> watch
data 为什么必须是函数 >>>
vue 中组件是用来复用的,为了防止 data 的复用,将其定义成函数
vue 的常用指令有哪些
v-on / v-if / v-show / v-for / v-bind / v-model / v=pre / v-once
13、Vuex 有哪些属性?
什么场景用Vuex ?
共享、方便管理、方便维护、组件传值……
项目:购物车数据、订单数据、用户登录信息……
state、getters、mutations、actions、modules
state >>> 类似于组件中 data,存放数据
getters >>> 类似于组件中的 computed
mutations >>> 类似于组件中 methods
actions >>> 提交mutations 的
modules >>> 把以上4个属性在细分,让仓库更好的管理
mutations 和 actions 的区别
本质区别:mutations 必须是同步函数
actions 可以包含任意异步操作
使用区别:mutations 中可以放入函数,actions 也可以放入函数,但是一般我们在mutations中放入函数而actions时提交mutations
14、Vuex 中 mutations 和 actions 的区别
mutaitons >>> 主要用来更新state中的数据,都是同步事物
actions >>> 主要用来做一些扩展操作,和一些异步操作
15、Vuex 是单向数据路还是双向数据流
vuex 是单向数据流
16、Vuex 如何做到持久化存储
由于vuex中的数据是储存到内存中的,一刷新就没了
第一种:利用H5的本地储存 localStorage,sessionStorage
第二种:利用第三方封装好的插件,例如vuex-persistedstate
第三种:使用vue-cookie 插件来做储存
17、说说你对单向数据流的理解
单向数据流 >>>
单向数据流主要是vue 组件间传递数据是单向的,即数据总是由父组件传递给子组件,子组件在其内部维护自己的数据,但它无权修改父子间传递给他的数据,当开发者尝试这样做时,vue将报错。这样做是为了组件间更好的维护。
在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件可以修改父组件数据的话,一个子组件变化会引发所有依赖这个数据的子组件发生变化,所以vue不推荐子组件修改父组件的数据
18、vue 路由模式
路由模式有两种:history、hash
history >>> 历史模式,会产生历史记录,可在浏览器中前进后退,但是点击刷新会向服务器发送网络请求,导致页面白屏或404,解决方式 >>> 在脚手架配置文件中,配置一条 historyApiFallback 相应代码
hash >>> 在地址栏中有一个#,不美观,但是,点击刷新不会向服务器发起请求
区别:
1、表现形态不同
history:http://localhost:8080/about
history:http://localhost:8080/#/about
2、跳转请求
history:http://localhost:8080/id >>> 发送请求
hash 不会发送请求
3、打包后前段自测要用hash,如果使用history 会出现空白页
19、介绍一下 SPA 以及 SPA 有什么缺点
SPA 是单页面应用
缺点:seo 优化不好,性能不是特别好
20、路由传值
1、显示 >>> 通过调用 thi.$router.push 中的query方法
http://localhost:8080/about?a=1
传值
this.$router.push({
path: '/about',
query: {
a:1
}
})
接收
this.$route.query
2、隐式 >>> 通过调用 thi.$router.push 中的 params 方法
http://localhost:8080/about
传值
this.$router.push({
name: 'About',
params: {
a:1
}
})
接收:this.$route.params.a
21、路由导航守卫
路由导航守卫主要分为三大类:全局、路由独享、组件内
1、全局
beforeEach、beforeResolve、afterEach
2、路由独享
beforeEnter
3、组件内
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
使用场景:判断是否登录,如果登录就next否则就跳转到登录页面
22、vue 动态路由
场景:详情页(文章、商品)
router.js 中配置
23、v-model 双向绑定的原理
通过 Object.defineProperty 劫持数据发生的变化,如果数据发生变化会触发set并在其中进行赋值,触发updata方法更新进行更新节点内容({{str}}),从而实现数据的双向绑定的原理
24、虚拟DOM、diff 算法
虚拟DOM >>>
数据改变 >>> 虚拟dom >>> 操作真实的dom >>> 试图更新
什么是虚拟 DOM ??? >>> 用js 模拟DOM 解构,因为不是真实的DOM 所以称为虚拟DOM
虚拟DOM 的作用 >>>
可以维护视图和状态之间的关系
负责视图可以提高渲染的性能
diff 算法
25、vue 优化性能的方法
懒加载模块
路由懒加载
prefetch
优化第三方依赖
善用浏览器缓存
优化压缩图片
静态文件上CDN