一、scss和less的区别
区别之处:
- 编译环境不一样 Less是基于JavaScript,是在客户端处理的。Sass是基于Ruby的,是在服务器端处理的。
- 变量符不一样,Less是@,而Scss是$。
- 输出设置,Less没有输出设置,Sass提供4种输出选项:nested, compact, compressed 和 expanded。
- Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持。
- 引用外部CSS文件 css@import引用的外部文件如果不想编译时多生成同名的.css文件,命名必须以_开头, 文件名如果以下划线_开头的话,Sass会认为该文件是一个引用文件,不会将其编译为同名css文件.
- Sass和Less的工具库不同 Sass有工具库Compass, Less有UI组件库Bootstrap.
二、Vue中样式穿透
场景:如果你的引入了第三方库,例如element-ui,如果你想修改第三方库的样式,直接通过dom查找,修改样式(如颜色,边距等)是没有效果的
css可以使用>>>,/deep/,::v-deepless和node-sass可以使用/deep/,::v-deepdart-sass可以使用::v-deep
三、for in 和 for of 的区别
for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值
for in可以得到对象的key或数组、字符串的下标
for of不能直接遍历对象, 可以先通过 Object.keys 得到对象的键再获取值
四、 echarts的使用
- 第一步:下载echars包。
- 第二步:准备一个具备大小(宽高)的 DOM,也就是容器
- 第三步:然后可以通过echarts.init()方法初始化一个echarts实例,init里面放入的是一个dom对象
- 第四步:调用生成dom对象,设置配置项空的option 即可
- 第五步:调用方法,生成效果图
1:准备容器
<div id="main" style="width: 600px;height:400px;"></div>
2:初始化echart实例
var myChart = echarts.init(document.getElementById('main'));
3:指定图表的配置项和数据 (根据文档提供示例找到option)
var option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line'
}]
};
4:调用方法,生成效果图
myChart.setOption(option);
五、 防抖和节流
防抖:多次触发只执行最后一次
<script>
// timer 必须定义为全局变量,因为如果是局部变量,后一次无法访问到前一次的变量值;
let timer = null;
// 获取元素,绑定事件
document.querySelector('button').onclick = function () {
// 防抖的核心代码,后一次触发的时候,如果前一次的延时器还没有执行,那么就不要执行了;
clearTimeout(timer);
// 防抖就是多次触发某个逻辑,只执行最后一次;
timer = setTimeout(function () {
// 将来的代码,就写道这里;
console.log('ajax请求已发出...');
}, 1000);
}
</script>
节流:多次触发只执行第一次
<script>
// 开关,控制器,开闭原则;
let flag = false;
// 获取元素,绑定事件
document.querySelector('button').onclick = function () {
// 节流的核心代码是,不能频繁触发定时器;
// 在定时器里面的代码,执行完毕之前,都不能触发;
if (flag) {
return;
}
// 经过if判断,如果flag的值是false,就把他改为true
flag = true;
// 节流的逻辑是,多次触发某个事件,以第一次为主,执行完毕之后才能触发第二次;
setTimeout(function () {
console.log("模拟ajax发送...");
// 代码执行完毕之后,再把flag改为false
flag = false;
}, 2000);
}
</script>
六、 介绍下 Set、Map、WeakSet 和 WeakMap 的区别
Set他的键和值是一样的,同时他有一个特性,就是存储不重复的元素,所以可以应用他用来值类型的数组去重或者求数组的交集
let arr=[1,2,3,3,3,3]
let arr1=[2,3,4]
let arr2=[7,8,9,10]
// 求交集
let setList=new Set([...arr1,...arr2])
let setList1=new Set(arr)
Array.from(setlist)
console.log(setList,"求交集");
console.log(setList1,"去重");
七、 Async/Await 是如何通过同步的⽅式来实现异步?
AsyncAwait实质上是Generator的语法糖, 采⽤单向链表的处理⽅式, 利⽤async相当于function *,await相当 于yeild. 函数加上async后, 就会返回⼀个Promise对象, 并将return的结果执⾏Promise.resolve(). await会等待后⾯的异步Promise执⾏完成后拿到resolve结果后再向下执⾏.
八、 3个判断数组的⽅式
1:Object.prototype.toString.call()
因为⼀切皆对象, 所以理论上来说所有类型的数据都可以通过toString⽅法来得到 [object type] 的结果, 但是除了Object类型的对象外, 其他类型的数据直接调⽤toString会转化为内容的字符串, 所以 需要通过Object.prototype.toString.call的⽅式来调⽤, 缺点是toString⽅法可能会被᯿写, 影响判断结 果.
Object.prototype.toString.call('An')// "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call({name: 'An'}) // "[object Object]"
2 instanceOf
instanceof判断⼀个对象是否是数组, 是通过判断这个对象的原型链上是否能找到对应的Array的原 型, 然后返回true和false, 但是instanceof只能判断对象类型, 原始类型必须通过new来创建才可以检测, ⽐如new String, ⽽且所有的对象类型instanceof Object的时候都会返回true, ⽽更改对象原型链指向 Array的话也会影响判断.
let a = '1';
a instanceof String; // false
a = new String('1');
a instanceof String; // true
a = [];
a instanceof Array; // true
a instanceof Object; // true
a = new Number(1);
a.__proto__ = Array.prototype;
a instanceof Array; // true
3 Array.isArray()
isArray是ES5推出解决判断是否为数组的⽅法, 所以可能会有兼容问题
九、 Vue的双向数据绑定, Model如何改变View, View⼜是 如何改变Model的
1:MVVM的双向绑定, 采⽤的是数据劫持集合发布订阅模式的⽅式
2:⾸先需要⼀个解析器Compile来扫描和解析每个结点的指令, 根据指令模板替换数据,以及绑定相应的更新函数
3:通过设置⼀个Observer利⽤Object.defineProperty(Proxy)来劫持各个属性的setter和getter, 如有数据变动可通知订阅者
4: Wacther作为Observer和Compile的桥梁, 可以订阅并收到每个数据变动的通知, 执⾏指令绑定的相应动作,从⽽更新视图
十、 Vue中, ⼦组件为何不可以修改⽗组件传递的Prop, 如果修改了,Vue是如何监控到属性修改并给出警告的
因为Vue是单向数据流的, ⽗组件的数据不可以被⼦组件修改
if (process.env.NODE_ENV !== 'production') {
var hyphenatedKey = hyphenate(key);
if (isReservedAttribute(hyphenatedKey) || config.isReservedAttr(hyphenatedKey)) {
warn( ("\"" + hyphenatedKey + "\" is a reserved attribute and cannot be used as
component prop."), Vm );
}
defineReactive$$1(props, key, value, function () {
if (!isRoot && !isUpdatingChildComponent) {
warn( "Avoid mutating a prop directly since the value will be " + "overwritten
whenever the parent component re-renders. " + "Instead, use a data or computed property
based on the prop's " + "value. Prop being mutated: \"" + key + "\"", Vm );
}
});
在initProps的时候, 会去判断是否在开发环境, 如果是开发环境, 会在触发set的时候判断时候是否此key处 于updatingChildren中被修改, 如果不是, 说明此修改来⾃⼦组件, 触发warning 需要注意的是, 丛⼦组件修改的prop属于基础类型的时候才会触发提示, ⽽且这样是⽆法修改⽗组件数据 源的, 但是当修改object属性时不会触发提示, 并且会修改⽗组件数据源的数据
十一、 Vue 的响应式原理中 Object.defineProperty 有什么缺陷?
Vue在3.0中采⽤的Proxy, 抛弃了object.defineProperty
- DP⽆法监控到数组下标的变化, 导致通过数组下标添加元素, 不能实时响应
- DP只能劫持对象的属性, 从⽽需要对每个对象, 每个属性进⾏遍历, 如果属性值是对象, 还需要深度遍
- 历, Proxy能劫持整个对象, 并返回⼀个新对象
- Proxy不仅可以代理对象, 还可以代理数组, 还可以代理动态增加的属性
十二、分析⽐较opacity: 0; visibility: hidden; display: none;优劣和使⽤场景
- display-none 不占空间, 不能点击;显示出原来这⾥不存在的结构,导致⻚⾯回流
- visibility-hidden 占据空间,不能点击;显示不会导致⻚⾯回流
- opacity-0 占据空间, 可以点击; 只是颜⾊完全透明, 可以跟transition搭配实现⼀些特效
十三 介绍下webpack热更新原理, 是如何做到在不刷新浏览器的前提下更新⻚⾯的
- 当修改了⼀个或者多个⽂件
- ⽂件系统接受更改并通知webpack
- webpack᯿新编译构建⼀个或者多个模块, 并通知HMR服务器进⾏更新
- HMR Server使⽤webSocket通知HMR runtime需要更新, HMR runtime通过HTTP请求更新jsonp
- HMR runtime替换更新中的模块, 如果确定这些模块⽆法更新, 则触发整个⻚⾯的刷新
十四、 为什么普通for循环的性能要⾼于forEach的性能, 请解释原因
for循环没有任何额外的函数调⽤栈和上下⽂查找, forEach不是普通for循环的语法题, 还有诸多参数传递/函数调⽤/上下⽂查找等需要在执⾏的时候考虑进来.
十五、介绍下BFC/IFC/GFC/FFC
- BFC 是块级格式上下⽂, ⻚⾯中的⼀个隔离的渲染区域.
- IFC 是内联格式上下⽂, ⾼度由其⾏内元素最⾼的实例⾼度计算⽽来
- GFC 是⽹格格式上下⽂, display-grid, 可以定义⾏和列实现⽹格布局
- FFC 是⾃适应格式上下⽂, flex or inline-flex, 弹性布局
十六、 介绍下Promise.all的使⽤/原理实现及错误处理
Promise.all⽅法接受⼀个数组作为参数, p1,p2,p3都是Promise实例, 如果不是, 就会先调⽤Promise.resolve 将参数转为Promise实例
十七、 mutation 里面可以放异步吗?
非严格模式确实是可以放异步,代码也可以正常执行!严格模式下不能这样操作(写异步),会有警告。 不建议放异步代码,目的是为了形成数据快照(拿到当时的那个数据状态)便于溯源,同时在vuex数据更新也会出现延迟现象,为了配合 DevTools 调试。
十八、vuex中的数据在页面刷新后数据消失
用sessionstorage 或者 localstorage 存储数据
存储: sessionStorage.setItem( '名', JSON.stringify(值) )
使用: sessionStorage.getItem('名') ---得到的值为字符串类型,用JSON.parse()去引号;