面试被问到的问题
history 模式怎么配置?
在 pages 的 index.js 中配置:
const router = new VueRouter({
mode: 'history',
routes: [
{
name: 'guanyu',
path: '/about',
component: About,
meta:{ isAuth:true,title:'关于'}
}
]
})
vue-router 跳转页面并刷新为什么会闪屏?
功能:在 vue-router 中,在当前页面中点击当前页面的路由,页面是不会进行刷新的,如何做到点击当前页面并进行刷新呢?(2021年8月25日03:04:49)
解决方法:
this.$router.go(0);
location.reload()
上两种方法都会出现商品的现象,影响用户体验,如果做到页面刷新不闪屏呢?
终极解决方案:
- 在 App.vue,声明 reload 方法,控制 router-view 的显示或隐藏,从而控制页面的再次加载。(provide /inject )。祖先组件(provide )会向其所有子孙后代(inject )注入一个依赖
- 在需要的页面 调用方法。
博客地址
js 复制对象的方法有哪些?
JSON 方法:JSON对象的深度克隆。方法是先 JSON.stringify() 转为 json 字符串, 再JSON.parse() 转为 json 数组。
缺点:
- 如果你的对象里有函数, 函数无法被拷贝下来。
2. 无法拷贝 copyObj 对象原型链上的属性和方法。
- 如果你的对象里有函数, 函数无法被拷贝下来。
- jQuery extend(object) 方法:扩展 jQuery 对象本身,用来在 jQuery 命名空间上增加新函数。
- Object.create() 方法:复制对象存在于 Object 原型 prototype 中。
for 循环遍历法。
- 浅拷贝:只是拷贝了基本类型的数据;然而引用类型数据, 只是复制了指针,复制后也是会发生引用。
- 深拷贝:深拷贝, 就是遍历那个被拷贝的对象。判断对象里每一项的数据类型。如果不是对象类型, 就直接赋值, 如果是对象类型, 就再次调用递归的方法去赋值。
- 原型链继承方法:通过原型来继承父类的公共属性。
Object.assign() 方法:
const ObjA = Object.assign({ }, obj)
ObjA.data = 'a'
ObjA.info.d = 'b'
const ObjB = Object.assign({ }, obj)
ObjB.data = 'c'
ObjB.info.d = 'd'
console.log(ObjA)
console.log(ObjB)
/* ==========输出========== { data: 'a', info: { d: 'd' }, un: undefined, fn: [Function: fn] } { data: 'c', info: { d: 'd' }, un: undefined, fn: [Function: fn] } */
博客地址
js 复制数组的方法有哪些?|| 浅拷贝的方法有哪些?
- 扩展运算符(浅拷贝)。
- for 循环 (浅拷贝)。
- while 循环 (浅拷贝)。
- Array.map() (浅拷贝)。
- Array.filter() (浅拷贝)。
- Array.reduce() (浅拷贝)。
- Array.slice() (浅拷贝)。
- JSON.parse() & JSON.stringify()(浅拷贝)。
- Array.concat() (浅拷贝)。
- Array.from() (浅拷贝)。
直接赋值:
var obj = {
a: 1,
b: 2,
}
var obj1 = obj;
console.log(obj1); // {a:1, b:2}
博客地址
深拷贝的方法有哪些?
- 迭代递归法:判断类型 + for … in 遍历。
- jQuery 中 extend() 方法:
jQuery.extend([deep], target, object1, [objectN]);
lodash 工具库:
- 引入:
import _ from 'lodash'
- 使用:
const b=_.cloneDeep(a)
- 引入:
谈谈你对 iframe 的了解
<iframe>
标签规定一个内联框架。一个内联框架被用来在当前 HTML 文档中嵌入另一个文档(可以是本地 html 页面,也可以是第三方网页)。所有的主流浏览器都支持
<iframe>
标签。你可以把提示的文字放到<iframe>
和</iframe>
里面,这样不支持<iframe>
的浏览器就会出现提示的文字。使用 iframe 是不是一个好的用法(good practice),不能一概而论,但是可以肯定是,现在的大部分网站避免采用这种方式的。
比较早期的网站使用 iframe,主要是用于导航栏(navigator)。为什么?
因为一个网站很多页面的导航栏部分是相同的,在避免切换页面的时候重复下载,将导航栏和正文分开在 iframe 中,是一个方便的做法。
同时带来的不利是,默认情况下,使用了 iframe 的网站的 URL 不会随着页面的变化而变化。
这就意味着一旦刷新,网站可能又回到首页。
那么现在的网站是如何解决不同页面使用相同的 navigator 而避免重复编码呢?
不同后台技术都有自己的方法,比如 ASP 有 SSI,PHP 有 require、require_once 或 include 函数,JSP 也有 include 指令。iframe 一直是浏览器标准规范之一,只有很早期的浏览器不支持 iframe,现在几乎已绝迹。
所以从兼容性上来说,iframe 是没问题的。那么现在什么时候会用到 iframe 呢?
因为 iframe 的页面和父页面(parent)是分开的,所以它意味着,这是一个独立的区域,不受 parent 的 CSS 或者全局的 JavaScript 的影响。
典型的,比如所见即所得的网页编辑器(WYSIWYG Online HTML Editor),因为它们需要 reset 自己的 CSS 到自己的标准,而不被 parent CSS 的 override。说到上面一点了,顺便说一下,知乎的这个编辑器不是用 iframe,它使用了一种叫 contentEditable 的属性,用来启用页面元素的编辑,在早期版本 IE 下不支持的。
正是因为刚刚提到的 iframe 等于新建了一个全新的,不受 parent 影响的页面上下文,所以在一定程度上,类似于沙箱隔离(sandbox)。
除此之外,如果有可以不用 iframe 来解决的问题,还是避免使用 iframe。
替代方案一般就是动态语言的 include 机制、ajax 动态填充内容,以及以后会普及的 contentEditable。谈一谈 http 缓存:
**定义:**http 缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
常见的 http 缓存只能缓存get请求响应的资源,对于其他类型的响应则无能为力,所以后续说的请求缓存都是指 GET 请求。http 缓存都是从第二次请求开始的。
分类:
- 根据是否需要重新向服务器发起请求来分类,可分为强制缓存和协商缓存。
根据是否可以被单个或者多个用户使用来分类,可分为私有缓存和共享缓存。
**强制缓存:**强制缓存在缓存数据未失效的情况下(即 Cache-Control 的 max-age 没有过期或者 Expires 的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。
协商缓存:当第一次请求时服务器返回的响应头中没有 Cache-Control 和 Expires 或者 Cache-Control 和 Expires 过期还或者它的属性设置为 no-cache 时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。
**分类注意点:**强制缓存如果生效,不需要再和服务器发生交互,而协商缓存不管是否生效,都需要与服务端发生交互。
为什么要使用 HTTP 缓存:
- 减少了冗余的数据传输,节省了网费。
- 缓解了服务器的压力, 大大提高了网站的性能。
- 加快了客户端加载网页的速度。
总结:
1、对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行协商缓存策略。
2、对于协商缓存,将缓存信息中的 Etag 和 Last-Modified 通过请求发送给服务器,由服务器校验,返回 304 状态码时,浏览器直接使用缓存。博客地址
谈一谈 浏览器 缓存:
定义: web 缓存是指一个 web 资源(如 html 页面,图片,js,数据等)存在于 web 服务器和客户端(浏览器)之间的副本。
浏览器缓存方式:
1、http 缓存:是基于 HTTP 协议的浏览器文件级缓存机制。
2、websql:这种方式只有较新的 chrome 浏览器支持,并以一个独立规范形式出现。
3、indexDB:是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。
4、Cookie:一般网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
5、Localstorage:html 5 的一种新的本地缓存方案,目前用的比较多,一般用来存储 ajax 返回的数据,加快下次页面打开时的渲染速度。
6、Sessionstorage:和 localstorage 类似,但是浏览器关闭则会全部删除,api 和 localstorage 相同,实际项目中使用较少。
7、application cache:是将大部分图片资源、js、css 等静态资源放在 manifest 文件配置中。
8、cacheStorage:是在 ServiceWorker 的规范中定义的,可以保存每个 serverWorker 申明的 cache对象。作用:
- 减少网络宽带消耗。
- 降低服务器压力。
- 减少网络延迟,加快页面打开速度。
http 缓存和浏览器缓存的区别:
前端缓存主要是分为 HTTP 缓存和浏览器缓存。
- HTTP 缓存是在 HTTP 请求传输时用到的缓存,主要在服务器代码上设置。
- 而浏览器缓存则主要由前端开发在前端 js 上进行设置。
1. ES5 数组方法:
改变原数组:
push(), pop(), shift(), unshift(), reverse(), sort(), splice()
不改变原数组:
concat(), join(), slice(),map(), filter(), forEach(), some(), every(), reduce()
1. ES6 数组方法
- arr.find:需要传入一个回调。
- arr.findIndex:需要传入一个回调。
- arr.fill: value,start,end。
arr.includes:方法返回一个布尔值,表示某个数组是否包含给定的值。
该方法主要用来替代
indexOf()
,因为indexOf()
是全等运算
,而NaN
和NaN
也不相等。Array.flat: 拉平数组。- Array.from:将伪数组转换为真数组。
- Array.of:用于将一组值转换为数组。返回新数组。
不改变原数组:
some、every 返回 true、false。
map、filter 返回一个新数组。
forEach 无返回值。1. ES6 的静态方法:
- Array.from():把伪数组转成数组。
Array.of():将一组数字转换成数组,弥补 Array 的不足。
let arr1 = Array.of(1, 2, 3, 4);
console.log(arr1); // [1, 2, 3, 4]
let arr2 = Array.of(1);
console.log(arr2); // [1]
1. ES6 的原型方法:
- find():数组实例的
find
方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true
的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined
- findIndex()
- includes():
includes
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes
方法类似。 - flat():拉平数组。处理数组扁平化。
- entries,keys,values 配合for of解构遍历数组的
//keys 是所有数组的下标
let arr3 = [“a”, “b”, “c”, “d”, “e”];
console.log(arr3.keys());//Array Iterator
for (index of arr3.keys()) {
}console.log(index);
//values 所有数组的值
for (item of arr3.values()) {
}console.log(item);
//values
for (item of arr3.entries()) {
}console.log(item);
2. ES5 字符串方法
charAt(),根据传入的位置取得其所在的字符。
charCodeAt(),根据传入的位置取得其所在的字符编码(unicode码)。(不常用)
String.fromCharCode(),根据传入的 unicode 码,转换为相应的字符。返回转化后的字符。
- concat(),将一或多个字符串拼接起来返回拼接得到的新字符串。
- indexOf(searchValue[,offset]),从一个字符串中向后搜索给定的子字符串,然后返回子字符串的位置(如果没有找到该子字符串,则返回-1)。第二个参数可以指定从哪开始(默认从0位置开始查找)。(常用)
- replace()方法,替换子字符串。(其他功能讲正则的时候说)将某个字符串置换成某个字符串。
- slice(beginSlice[,endSlice]),提取一个字符串的一部分,返回一个新的字符串。beginSlice 从 0 开始,endSlice 可以省略,如果省略 endSlice 会一直提取到字符串末尾。(beginSlice 是开启的位置,endSlice 是结束的下标的——但结果不会包含结束的下标)—用的较多。(按下标取字符串)
valueOf(),返回对象的字符串、数值或布尔值表示。如果是包装类型返回包装类型的值,如果是对象则返回对象本身。
该方法没有参数
返回值:如果是包装对象,返回的是包装对象中的基本值;如果不是包装对象类型,返回的是对象本身。
toString(),返回对象的字符串表示。
该方法没有参数
返回值:如果是包装对象,返回的是包装对象中的基本值转换为字符串;如果不是包装对象类型,根据对象类型的不同返回值也不同。
- toLowerCase(),将字符串转换为小写。
- toUpperCase(),将字符串转换为大写。
2. ES6 字符串方法
- str.startWidth(): 判断开头有没有包含某个字符串。
- str.endsWith(): 判断结尾有没有包含某个字符串。
- str.includes(): 判断字符串是否包含某个字符串。
- str.repeat(): 重复当前的字符串,可以规定次数。
- str.trim(): 删除字符串两端的空白符。
- trimStart() 去除首部的空格。
- trimEnd() 去除尾部的空格。
3. ES6 对象方法
- Object.is():判断对象是否相等 相当于 ===,修复NaN不等自己的问题。
Object.assign():合并对象。
let obj1 = { a: 1 };
let obj2 = { b: 2 };
let obj3 = { c: 3 };
let newObj = Object.assign(obj1, obj2, obj3);
console.log(newObj)
- Object.getOwnPropertyName(obj):获取 obj 的 key 名称,并储存为一个数组,返回值为此数组。
- Object.keys(obj):获取 obj 的 key 名称并储存为一个数组,返回此数组。
- Object.values(obj):获取 obj 的 value 名称并储存为一个数组,返回此数组。
- Object.entries(obj):获取 obj 的键值储存为一个为二位数组,返回此而为数组。
- 封装过哪些插件?(非上传 npm 上的)
h5 适配怎么做?
flexible 是淘宝开源的 h5 适配方案,手机淘宝从14年开始至今一直在使用,比较稳定,并且在开发过程中不要进行复杂的折算,直接使用设计稿中的尺寸,方便好用。该方法是主流的 h5 前端开发方案之一。
使用方法:
- Flexible 的使用方法非常简单,只需要引入 flexible_css.js 和 flexible.js 下载地址
将 px 转成 rem。
如果按 750px 的设计稿进行开发,为了方便换算,flexible 将屏幕宽度为 750 的
<html>
元素设置 font-size 为 75px,我们将 75px 称之为 rem 基准值,针对这份设计稿,我们可以知道 1rem=75px。字号不要使用 rem。
在不同的屏幕下,我们是不希望看到字号也随屏幕缩放,我们希望在小屏上看清文本,在大屏上看到更多的文本,所以字号还是用 px 单位设置,以及现在绝大多数的字体是点阵字体,通常是 16px 和 24px,所以不希望出现 13px、15px 这样的奇葩尺寸。
根据 flexible 的适配方案,dpr = 2 时
<meta name="viewport">
initial-scale 属性为 0.5,dpr = 3 时<meta name="viewport">
initial-scale 属性为 0.3333333333
什么是 SaaS 平台?
- 什么是 SaaS?
SaaS 是一种软件布局模型,其应用专为网络交付而设计,便于用户通过互联网托管、部署及接入。
- 什么是 SaaS 平台?
SaaS平台是运营 saas 软件的平台。SaaS 提供商为企业搭建信息化所需要的所有网络基础设施及软件、硬件运作平台,并负责所有前期的实施、后期的维护等一系列服务,企业无需购买软硬件、建设机房、招聘IT人员,即可通过互联网使用信息系统。
**白话解释:**就像打开自来水龙头就能用水一样,企业根据实际需要,从 SaaS 提供商租赁软件服务。
Vue 里面传递给组件的 props 如何验证?
想象一下当有一个人要使用 foo-component 组件的时候,他可能对于其要接受的参数有什么要求并不是很清楚,因此传入的参数可能会在开发子组件的人的意料之外,程序就会发生错误,就像我们在函数调用之前先检查一下函数一样,props 也可以进行一个预先检查。
校验器模式就是指把在函数开头的对参数校验的部分提取出来作为一个公共的部分来管理,让一个什么东西来专门负责校验,当类型不正确的时候就抛个异常根本不去调用这个函数,很多框架设计时都是这么设计的(Spring MVC、Struts2等等),props 也提供了这个功能,想一下如果没有这个功能的话,为了保证正确性我们可能需要在每次使用 props 属性之前都写一段代码来检查。校验器最大的好处就是大多数情况下我们只需要声明我需要什么样的数据,让校验器检查好了再塞给我。
为什么要用 async 和 await?
- 可以通过同步代码实现异步效果,可读性强。
- .then 和 .catch 不是说不能用,只是说可读性要差一些,因为里面还是有异步代码(异步回调函数)。
v-html:如果插值语法中 HTML 元素会被解析成 HTML 渲染到页面。
<body>
<div id="app">
<p v-cloak>{ { msg }}</p>
<p v-text="msg"></p>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
msg : "<h1>这是一个h1元素内容</h1>"
}
});
</script>
</body>
css3 实现无缝滚动防抖:
问题:图片加文字的无缝滚动,在手机端的效果总体还行,但是图片在手机某些浏览器会抖得厉害。
解决方法:
里面的某个元素在手机端会抖动的厉害,改用二维的 translate,如:
.donghua.active{
animation: scoll ease-in-out 1s infinite alternate;
-webkit-animation: scoll ease-in-out 1s infinite alternate;
}
@keyframes scoll {
0% {
transform: translate(0px, 0px);
}
100% {
transform: translate(0px, -353px);
}
}
@-webkit-keyframes scoll {
0% {
transform: translate(0px, 0px);
}
100% {
transform: translate(0px, -353px);
}
}
animation 中的值:
- ease-in-out:慢速开始和慢速结束的过渡效果(相对于匀速,(开始和结束都慢)两头慢)。
- ease:慢速开始,然后变快,然后慢速结束(两头慢,中间块)。
- ease-in:慢速开始,之后一直快。
- ease-out:开始快,之后一直慢。
- linear:匀速开始和结束。
- Vue 递归组件实现多级列表
快速将字符串转成数值:
// 题目:快速将字符串转换为数值
var str = '99';
// 想办法转换成数值型。
// 方法一:
console.log(Number(str)); // 99
// 方法二:
console.log(parseInt(str)); // 99
// 方法三:
console.log(parseFloat(str)); // 99
// 方法四:
console.log(str - 0); // 99 // str 会调用Number()转换为99。
// 方法五:
console.log(+str); // 99
Vue 下拉框 select 的分段加载解决数据过大导致页面卡顿。
原因: 下拉框数据过多,若渲染全部数据,会导致 DOM 数量太多,操作卡顿。
**解决:**比如说这是一个关于活动的下拉框,有 活动名 和 活动列表
- 定义 filter-method=“事件名”,这是 element 提供的自定义事件方法。过滤出自己需要的数组对象数据。
- 将获取到的 活动名 和 活动列表 分离开,限制渲染数组的长度。
- 存储符合条件的下拉选项。并且限制数据的长度,比如说取前一百个:
this.activityList = result.slice(0,100)
博客地址
Vue 的 filter 过滤器(天禹):
过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1. 注册过滤器:
Vue.filter(name,callback)
或new Vue{filters:{}}
2. 使用过滤器:
{ { xxx | 过滤器名}}
或v-bind:属性 = "xxx | 过滤器名"
备注:
1. 过滤器也可以接收额外参数、多个过滤器也可以串联。
2. 并没有改变原本的数据, 是产生新的对应的数据。
localStorage 安全性问题:
现在越来越多的前端人员把性能优化的目标指向了本地存储,利用 localStorage 来进行本地资源缓存,因为其大小上限为 5MB,可以装相当多的东西,甚至在FireFox中你还可以修改这个上限。
虽然说这个 localStorage 非常好用但也存在安全隐患,如果我们将恶意代码植入里面那么这段恶意代码也会一直存在知道用户清空我们的 localStorage 为止
我们可以看一段代码:将原来 localStorage 存储的 name 数据赋值给 id 为 test 的页面元素 我们可以设想万一里面是恶意代码呢?
<body>
<div id="test"></div>
<script> localStorage.setItem('name','xiaohua'); document.getElementById('test').innerHTML = localStorage.name; </script>
</body>
博客地址
get 和 post 的区别:
- get上传的数据,会出现在浏览器的地址栏中。 post 存放在请求主体中 。
- get 不安全,post 相对安全。
- get 请求的数据量有限制(浏览器地址栏有大小),post 请求上传的数据理论上没有限制(实际上服务器会对上传的数据,进行限制)。
- get 一般用于获取数据,如果要给服务器上传数据使用 post。
- 深入剖析 JS 类的 static、public、private、protected:博客地址
- Vue 中做 权限管理 使用 router.addRoutes() 动态添加路由以及解决刷新失效,跳转后刷新失效问题:博客地址
a = [0-9]过滤数组中的奇数,留下偶数。
定义和用法:
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let newArr = arr.filter((item, i, arr) => {
//函数本身返回布尔值,只有当返回值为true时,当前项存入新数组。
return item % 2 == 0
})
console.log(newArr) // [2, 4, 6, 8, 10]
filter 更多用法
谈谈 webpack:
什么是 webpack
- Webpack 是一个模块打包器(bundler)。
- 在 Webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。
- 它将根据模块的依赖关系进行静态分析,生成对应的静态资源。
五大“护法”
- Entry:入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
- Output:output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
- Loader:loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只能解析 JavaScript)。
- Plugins:插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
- Mode:模式,有生产模式 production 和开发模式 development。
理解 Loader
- Webpack 本身只能加载 JS/JSON 模块,如果要加载其他类型的文件(模块),就需要使用对应的 loader 进行转换/加载。
- Loader 本身也是运行在 node.js 环境中的 JavaScript 模块。
- 它本身是一个函数,接受源文件作为参数,返回转换的结果。
- loader 一般以 xxx-loader 的方式命名,xxx 代表了这个 loader 要做的转换功能,比如 json-loader。
理解 Plugins
- 插件可以完成一些 loader 不能完成的功能。
- 插件的使用一般是在 webpack 的配置信息 plugins 选项中指定。
配置文件(默认)
webpack.config.js : 是一个 node 模块,内部暴露 webpack 配置对象。
常用的 loader 有:
- eslint-loader:审查代码是否存在语法错误。
- babel-loader:将 es6 以上的语法编译成 es5 及以下的语法。
- style-loader:是将 css-loader 打包好的 css 代码以
<style>
标签的形式插入到 html 文件中。 - css-loader:用于解释 @import 和 url(),并通过 import 后进行解析,通常和 style-loader 结合使用。
- less-loader:将 less 语法编译成 css 语法。
问题:
eslint-loader 配置:“0” “1” “2”代表什么?
eslint 要想工作,必须定义配置文件,配置文件有两种写法
.eslintrc.*
- package.json 文件中
eslintConfig
我们以第一种为例,项目根目录新建
.eslintrc.js
module.exports = {
// eslint配置
parserOptions: {ecmaVersion: 8, // es8
sourceType: "module", // ECMAScript 模块
},
rules: {// error 和 2 代表错误
// warn 和 1 代表警告
// off 和 0 代表关闭
semi: "error", // 分号
"no-debugger": "warn",
eqeqeq: "off", // 必须使用三个等号
},
};
- 谈一谈 js 的面向对象
项目中创建时,都是 cv 的项目配置,一个有问题就需要都改,如何解决?
- 如果 cv 了很多配置出问题了,看控制台报错,按照报错去处理。如果有问题还不报错,把其他的配置注释起来,再一段段的测试出现的位置。
- 一般在 cv 东西的时候,需要注意一下,cv 一段最好看一下控制台有没有报错,就算出错了,我也能够知道就是刚才 cv 的代码出问题了。
forEach、map、filter、reduce 的区别:
相同点:
- 都会循环遍历数组中的每一项。
- map()、forEach() 和 filter 方法里没执行匿名函数都支持 3 个参数,参数分别是:当前元素、当前元素的索引、当前元素所属的数组。
- 匿名函数中的 this 都是指向 window。
不同点:
- map() 的速度比 forEach() 快。
- map() 和 filter() 会返回一个新数组,不对原数组产生影响。forEach() 不会产生新数组,返回 undefined,reduce() 函数是把数组缩减为一个值(比如求和、求积)。
- reduce() 有 4 个参数,第一个参数为初始值。
博客地址
- 哪些会触发 Vue 的响应式?
- mixin 的了解。
项目发布后,用户访问到之前的,怎么解决?
今天遇到一个奇葩问题,web端的后台管理系统发布成功后,用户说功能没有更新,还是之前的版本,我就纳闷了,确实已经更新成功了,后来仔细检查发现竟然是缓存造成的,清除了一下浏览器缓存,再打开就是最新版本了。
清除浏览器方法
- set 和 map 数据类型,是否用过?
- e-charts 用得多吗?
- 是否用过为前端?
- TypeScript 是否了解用过?
- VueX 如何数据持久化?
用户权限如何控制?
- 控制的第一步是知道用户拥有哪些权限,所以用户登录后第一件事是获取权限数据。
- 有了权限数据下一步就是分别-实现对路由、视图、请求的控制。
- 路由控制的思路有两种,一种是初始化即挂载全部路由,每次路由跳转前做校验;另一种是只挂载用户拥有的路由,相当于从源头上做了控制。
博客地址
还没有评论,来说两句吧...