ts类型笔记

87 阅读20分钟

any和unknow区别

unkonw不能调用属性和方法,相对来说unknow比any更加安全

unknow只能赋值给any和unknow,其他会报错提示

image.png

2.Object、object、{}三者的区别

A.Object所有类型都支持

B.object只支持复杂类型

image.png

C.字面量{}相当于new Object,所有类型都支持,

image.png

但是不支持修改属性(少用)

image.png 15、箭头函数和普通函数的区别

1、call、apply、bind不会改变箭头函数this值,会改变普通函数this值

2、箭头函数没有原型属性

3、箭头函数不绑定arguments,取而代之用rest参数… 解决

4、箭头函数不能作为构造函数使用,不能使用new

5、箭头函数中的 this 和调用时的上下文无关,而是取决于定义时的上下文

16、移动端1px像素解决办法

先理解概念,物理像素、逻辑像素

物理像素:是不同手机型号出厂时携带的像素,也称为硬件像素

逻辑像素:css中记录的像素

问题描述:

在开发的时候ui设计师要求的1px是设备的物理像素,而css中的是逻辑像素,它们之间并不是直接等于的关系,存在着比列关系,通常可以用 javascript 中的 window.devicePixelRatio 来获取,也可以用媒体查询的 -webkit-min-device-pixel-ratio 来获取。当然,比例多少与设备相关。

解决办法:

1、媒体查询利用设备像素比列缩放,设置小数像素

css可以这样设置:

js可以这样写:

2、媒体查询 + transfrom 对方案1的优化

17、伪类与伪元素的区别

首先在知道这个概念之前先了解什么是伪类?伪元素?

1、伪元素

1、伪元素在DOM树中创建了一些抽象元素,这些抽象元素并不存在与文档语言中(逻辑上存在,不存在文档树中)

2、伪元素由两个::开头,接的是伪元素得名称(使用两个::是为了区分伪类和伪元素,在CSS2中依然可以用一个:的语法,但是在CSS3中必须使用两个冒号::)

3、一个选择器只能使用一个伪元素,并且伪元素必须处于选择器语句的最后

伪元素的种类:

image-20220301105558373

2、伪类

1、伪类由一个冒号开头:

2、获取不存在与DOM树中的信息。比如标签的:link、visited等,这些信息不存在与DOM树结构中,只能通过CSS选择器来获取

伪类的种类:

image-20220301110437341

18、移动端、浏览器字体小于12px的解决方案

font-size: 12px;是浏览器字体设置最小的时候,12以下的数值不生效了,要是想实现小于12px,方法如下:

这时候可能会遇到字体缩放和布局一起缩小了,只需要将字体与容器样式分开写就好了

19、js浮点数精度计算问题解决

一般运算中,我们会保留后两位小数,这里做点知识扩展

1、.toFixed()

语法:

数字.toFixed(2)

括号中的数字是保留的位数,该方法会四舍五入,返回的值类型是string型

2、Math.round()

语法:

x是数值

返回值: 给指定的数字值四舍五入到最接近的整数

解决精度运算问题有如下方式:

1、 扩大倍数法:有多少位小数就扩大10的n次方

2、四舍五入法:

20、移动端的300毫秒延迟问题

问题描述:

移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟。也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应,而是会等上一小会儿才会出现点击的效果。

方案一:禁用缩放

方案二:更改默认的视口宽度

方案三:fastclick,解决移动端300ms延迟

FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。

直接安装依赖按照官网的教程使用就好了

21、HTTP缓存

面试中我们常会被到,你知道http缓存的方式有几种吗?这样的问题,下面我简单的介绍下,为什么会有HTTP缓存、缓存的方式

1、存在的意义

我们每一次的网络请求中,在请求成功的前提下,服务器都会给我们返回对应的资源,浏览器进行下载,但是并不是所以的资源都会被下载,比如当某些资源未改变时,浏览器会在本地缓存中拿到它们,从而避免了重复下载的过程,这也算是一种性能上的优化

可以被缓存的资源:JS文件、CSS文件、图片、字体包等等

2、缓存的类型

我们可以知道,前端发起HTTP请求的时候,会在请求头上携带相关的信息,浏览器就会根据我们携带的信息去判断,本次请求的该资源是否有本地缓存

强缓存

以前的使用中,我们一直用的是expires,也就是当服务器返回响应时,在响应头中将过期的时间写入expires字段中,自己随便找个网站F12打开调试台,找一条网络请求即可

image-20220508173343035

可以看到expires中写入了过期的时间范围,那整个流程是怎么样的呢?

当首次资源发送时:

image-20220508173625548

再次发送资源时,浏览器会把expires中的时间戳和本地时间去进行对比,如果本地时间小于expires中的时间,则在缓存中拿到这个资源,这里的时间戳由于是服务器上传的,所以需要保证浏览器和服务器上的时间一致

image-20220508174130577

expires是通过拿到时间戳去进行比对的,在后面又增加了Cache-Control 中的max-age 字段也允许我们通过设定时间长度来达到同样的目的。

max-age可以看作是对expires的补充,在日常工作中,我们可能用max-age较多,但是如果要实现向下兼容,expires也是必不可少的

这里可以看到max-age的值,它并不是一个时间戳,而是一个时间长度,单位是秒,意思是在3600秒内,该资源是有效的。max-age的机制就是对资源的判定有效不再受到服务器时间的限制,客户端会记录到请求资源的时间点,以此时间点为起点,从而确保两个时间点都来自于客户端,相对来说更加的精确,这里就不给出请求图了,和上面原理一致

这里介绍下cache-control中的值

max-age:缓存保存的时间

no-cache:绕开了浏览器,每一次发起请求都不会再去询问浏览器的缓存情况,而是直接向服务端去确认该缓存是否过期

no-store:不使用任何的缓存策略,连服务器端的缓存确认都绕开了,只允许直接向服务端发起请求,并下载完整的响应

public:资源能被本地缓存、服务器代理

private:资源只能给本地缓存,其他服务器不能缓存

协商缓存

浏览器向服务器询问是否需要重新下载资源,还是从本地上获取到缓存的资源,值得一提的是,当服务器提示资源未改动,资源就会被重定向到浏览器缓存,对应的HTTP状态码是304

协商缓存的实现

Last-Modified:时间戳,当我们第一次请求资源时,会在响应头中返回

If-Modified-Since:时间戳,就是服务器返回的Last-Modified的值

过程就是,请求头会携带If-Modified-Since,服务器会进行判断,若If-Modified-Since的时间戳是和last-modified不一致,服务器就会完整的返回响应内容,并且返回新的last-modified值,如果一致,就返回304,响应头也不会添加last-modified字段

第一次请求:

image-20220508183133159

再次请求

image-20220508183445799

但是last-modified有自己的缺陷

1、last-modified的值只精确到秒级

2、如果文件每隔一段时间重复生成,但内容是一致的,last-modified会每次返回资源文件,即使内容一致

所以etag对其进行了补充

Etag是服务器对每个资源文件生成的唯一 标识字符串 ,这个字符串基于文件内容编码,只要文件内容不同,对应的Etag也会不同

请求方式和上图差不多,服务器返回Etag,下次请求请求头会带上名为if-None-Match的字符串为服务器做对比

这里其实可以看到,Etag会让服务器多做事,也就是会影响到服务器的性能,所以我们使用的时候需要进行考虑,Etag的感知文件变化上比Last-modified更为准确,所以优先级也更高,二者同时出现时,以Etag为准

上诉只是对HTTP缓存的一些简单介绍,基础面试知识点可以应付了,HTTP缓存有很多知识,感兴趣可以多百度看下

CSS篇

1、举出让元素居中的方法

个人总结出两种情况,即需要居中的元素带宽高、不带宽高,如下:

带宽高

image-20220112201105601

不带宽高

2、常见的布局方式

一、左边(右边)固定,右边(左边)自适应

float布局

绝对定位

弹性布局

弹性布局若是要实现右边固定的效果,则加上如下代码即可

二、左中右(左右不变,中间自适应)

float布局

绝对定位

弹性布局

image-20220112210301518

三、上中下(上下不变,中间自适应)

在写之前,首先说明一点,关于元素的宽度,若是没给出,在浏览器中会自动给出宽度, 但是关于高度并不会自动给出高度,所以上面的弹性布局列子中,没给出高度但是还是显示出了盒子是因为盒子的内容已经被撑开了,但是高度并不会自动分配

绝对定位

弹性布局

额外补充点:

文档流和文本流

个人对文档流的理解就是盒模型中的概念。 文档流就是在浏览器中的规则,块状元素的规则是从上到下排序的,行内元素是从左到右排序的

文本流:适用于文字之间的规则

其中我们在上面的列子中float、绝对定位、固定定位、display:flex,都会让原本的元素脱离文档流,在了解相关的规则后,我们可以按照自己的想法去布局。

vue篇

1、你怎么理解vue?它是属于什么模式?

vue.js是一款渐进式、多途径、高性能JavaScript框架,易用、灵活、高效

属于MVVM(Model-View-ViewModel)模式,也是就model(模型层)、ViewModel(视图驱动层)、view(视图层),数据在传递的时候双向传递

2、v-if和v-show的区别

相同点:v-if与v-show都可以动态控制dom元素显示隐藏

不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css–display:none,dom元素还在。

性能角度上:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。

3、vue响应式原理和双向绑定原理

在了解该知识点前,先做一个只是铺垫,详细介绍下Object.defineProperty的用法

Object.defineProperty详解

Object.defineProperty是es5的方法,作用是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象(只能用在对象上,不能用在数组上)

1、语法

Object.defineProperty(obj, prop, descriptor)

2、参数

obj:必需。目标对象 prop:必需。需定义或修改的属性的名字 descriptor:必需。目标属性所拥有的特性 3、属性用法

修改某个属性的值时,给这个属性添加一些特性。

属性详解:

writable:是否可以被重写,true可以重写,false不能重写,默认为false。 enumerable:是否可以被枚举(使用for…in或Object.keys())。设置为true可以被枚举;设置为false,不能被枚举。默认为false。 value:值可以使任意类型的值,默认为undefined configurable:是否可以删除目标属性或是否可以再次修改属性的特性(writable, configurable, enumerable)。设置为true可以被删除或可以重新设置特性;设置为false,不能被可以被删除或不可以重新设置特性。默认为false。

vue响应式原理(vue双向绑定的原理)

vue2.x中

object.defineProperty是属性级别的拦截,会在set、get的方法中进行拦截操作

当把一个普通的js对象传入vue实列作为data选项时,vue会遍历此对象的所有的property,并使用object.defineProperty,把这些property全部转换为getter/setter。然后watcher会监听setter的变化,每当setter变化后,就会进行视图层的重新渲染,达到响应式效果

在这里主要我改动了data中的某一个值,那么整个响应式的状态又会重新开始进行setter、监听,相对来说浪费资源

若是data中有多个值,则会进行循环输出,来监听每一个值的变化

vue3.x中

Proxy(代理)

对象级别的拦截

改变语法原有的规则,可以自定义其规则(元编程)

target:代理处理的目标对象

handler: 代理处理的方法

自定义对象属性的获取、赋值、枚举、函数调用等功能

这里去监听每一个属性的时候不需要用到循环的方法,简单的说就是谁改变就去监听谁,在原用的基础上提升了性能

4、虚拟DOM和diff算法

参考b站 www.bilibili.com/video/BV1dV…

1、认识虚拟DOM

没有虚拟DOM之前: 数据改变=>操作DOM=>视图更新

使用虚拟DOM后:数据改变=>虚拟DOM(计算出变更)=>操作DOM=>视图更新

虚拟DOM:用js模拟DOM结构

如下图,左边是实际DOM元素,而右边是js模拟的DOM结构

image-20220215160130741

2、虚拟DOM的好处

每当dom改变的时候,不会全部都进行DOM改变,而是被改动的地方进行改变

image-20220215161655267

这里就是用js代码去模拟DOM结构

用虚拟DOM计算出最小的变化,然后再去更新变化的实际DOM

3、认识diff算法基本概念

是两个虚拟DOM之间的一种比较

1、虚拟DOM之间会平级别对比 ,深度遍历进行对比

2、对比的同时会通过key值进行判断,判断元素是仅仅位置发生改变还是需要整个替换或删除

3、如果不是元素发生改变的话,再对内容进行对比,如果是内容发生改变的话,就直接修改内容

详细的算法介绍就需要另外研究了

5、vue的生命周期与不同阶段的作用

vue的生命周期有:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed

作用:

beforeCreate:可以加载loading事件,在加载实列的时候被触发

created:初始化完成时的事件在这里,这里也结束loading事件,异步请求也适合在这里被调用

mounted:可以挂载元素,过去DOM节点

updated:对数据统一处理,这里写上对应的函数即可

beforeDestroy:可以确定一个停止事件的确认框

nextTick:更新数据后,立即操作dom

6、vue组件之间的传值方式

1、父子组件传值方式

父组件向子组件传值

1、传值前现在父组件中导入需要的子组件,然后在父组件中传入值、

2、子组件需要在props:{}中定义传过来的值,以及类型,然后就可以在其他地方使用

父组件:

image-20220215203707391

子组件: image-20220215203805971

子组件向父组件传值

就是在子组件中通过$emit(传向父组件事件,传向父组件值)向父组件传入值,父组件接受改变即可

子组件:

父组件:

2、兄弟组件传值方式

1、bus总线方法

1、定义一个bus.js ,内容如下

2、然后在main.js中添加如下代码

3、在需要传值的兄弟组件中,通过 b u s . bus. bus.emit(传入方法,传入值),方式传入

4、在接收的组件中在mouted生命周期中,用 b u s . bus. bus.on(传过来的方法名,回调函数),来进行接收

2、 可以子组件先传入父组件,然后再由父组件再传给另一个子组件

7、methods、computed 和 watch 的区别和运用的场景?

1、methods、computed的区别

在页面进行渲染的时候,methos中所有的方法都会被重新调用,而computed,只会在其被依赖项改变的时候才会重新计算

2、computed和watch的区别

computed是计算属性,有如下特点:

1、计算属性定义的属性可以不用在data中定义,在DOM中直接使用。

2、支持缓存,只有在数据依赖项发生改变的时候,才会重新计算。

3、不支持异步操作,在computed中异步操作无效,无法监听数据的变化

使用方法如下:

image-20220216110741938

watch是监听属性,特点如下:

1、不支持缓存,只要数据变化,就会直接触发响应的操作

2、在watch内支持异步操作

3、监听的函数接受两个参数,第一个是参数最新的值,第二个是参数输入之前的值

使用方法如下:

image-20220216111608863

image-20220216111619725

总结:

如果一个数据需要经过复杂计算就用 computed 如果一个数据需要被监听并且对数据做一些操作就用 watch 8、在哪个生命周期内调用异步请求?

在created、beforeMount、mounted都可以发送异步请求,因为可以将服务端端返回的数据进行赋值。但是最常用的是在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求

有两个优点: 第一点:能更快获取到服务端数据,减少页面 loading 时间; 第二点:放在 created 中有助于一致性,因为ssr 不支持 beforeMount 、mounted 钩子函数。

9、对 keep-alive 的了解?

img

10、组件中 data 为什么是一个函数?

因为vue的组件可能在不同的页面中会被调用,是一个函数的话每一次的调用就会执行data函数并返回新的数据,这样就可以避免多处调用之间的数据污染

11、Vue 中的 key 有什么作用?

我们可以知道,通常我们在使用v-for的时候会去标明key值,但是不建议去使用其数组的下标index作为key值。

在上面中已经简单的介绍的虚拟DOM、diff算法,key值主要是为了diff算法服务的,给每一个循环出的item绑定一个key值,做唯一标识

好处如下:

1、判断新旧VDOM节点在逻辑上是不是同一个对象

2、准确。因为key的特性是唯一性。所以如果不加key,采用index的标记法,那么vue会选择复用同类型节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug.

3、快速。在元素list一直变化的情况下,key值设置唯一时,能很精确找到/找不到变更元素,若使用index标记,要遍历vnode,时间长。

Vue的策略是不对dom直接更新,而是先比较oldDOM和VDOM 之间的区别,通过比较差别并且复用没有改变的dom,来快速的构建新的dom并渲染到页面 12、vue中如何动态的设置class、style?

13、为什么v-if和v-for不建议用在同一标签?

因为v-for的优先级高于v-if,程序会先执行v-for的操作,然后再去执行v-if,每次都会先去循环再进行条件判断,就会带来性能上的浪费

14、不需要响应式的数据应该怎么处理?

image-20220216171614716

15、watch有哪些属性,分别有什么用?

1、正常监听

2、immediate

watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。

3、deep

深度监听,当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

vue-router篇

1、this.routerthis.router和this.route的区别

this.$router:是全局路由器的router的实列,可以在任何组件内进行访问,就是跳转路由的方法,里面有很多的方法比如

his.$route:包含当前激活的路由状态信息、url解析得到的信息

2、active-class 是哪个组件的属性?

active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换;

用法: 1、直接在路由js文件中配置linkActiveClass

2、在router-link中写入active-class

这里这个路由的样式可以直接在style中去写对应的类名就好了

如果两个路由都是用一样的样式,比如如下情况:

这样跳转后两个router-link都会有显示的样式,可能是因为 to=“/” 引起的,active-class选择样式时根据路由中的路径去匹配,然后显示,例如在my页面中,路由为localhost:8080/#/my,那么to=“/”和to=”/my"都可以匹配到,所有都会激活选中样式

解决办法

a.直接在路由js文件中配置linkActiveClass

b.在router-link中写入exact

3、路由传参的方式与动态路由匹配

介绍前我们先了路由的两中形式

编程式的导航 router.push

声明式的导航

对于参数的传递主要是用对象的方式去写的,可分为命名路由、查询参数

命名路由

使用前提:在注册路由的地方需要给路由命名

命名路由搭配着params来进行传递,如下

在目标页面接收

查询参数

查询参数其实就是在路由地址后面带上参数和传统的url参数一致的,也就是传递的参数会出现在url地址栏上

注意:name、path可以和query搭配,params只能和name搭配

用法:

接收:

动态路由匹配

常见场景:当我们有一个通用组件,对应不同ID共和不相同的客户,都要使用这个组件来渲染,我们就可以使用路由中的 动态路参数来达到这个效果,一个路径参数使用:进行标记,每当匹配到一个路由,参数值就会被设置

可以用this.$route.params去接收参数的值

注意:当使用该方法时,原组件的实列会被复用,但是组件的生命周期钩子不会被调用,简单列子如下

写跳转的组件:

路由写法:

在目标组件用 {{ this.$route.params.id }}进行参数接收即可

关于在watch中$route(to, from)不生效

这里我想监听组件的路由变化,使用watch去监听$route(to, from)发现不生效,解决办法参考这篇文章

blog.csdn.net/u010227042/…

路由组件传参

当组件中使用 $route 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props 配置来解除这种行为:

1、如果 props 被设置为 true,route.params 将会被设置为组件属性

这里用动态路由匹配做列子,同样传入的是id

在目标跳转的路由中:

目标路由中props接收然后直接用:

2、对象模式

获取:

3、函数模式

函数模式的路由配置中,props属性是函数,这个函数返回一个对象。 在函数模式中,可以有一个参数,这个参数就是route对象,里面存储的是路由的相关携带信息。

js代码:

获取:

4、vue-router 有哪几种导航钩子(导航守卫)?

1、全局守卫: router.beforeEach

2、全局解析守卫: router.beforeResolve

3、全局后置钩子: router.afterEach

4、路由独享的守卫: beforeEnter

5、组件内的守卫: beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

详细介绍:

zhuanlan.zhihu.com/p/54112006

5、vue-router历史模式和hash模式的区别?

hash模式:

url里面带有#号,开发中默认的就是hash模式,hash虽然出现在URL中,但是不会被包括在HTTP请求中,所以改变hash不会重新刷新页面

路由的哈希模式就是利用了window.onhashchange事件,也就是url中的hash值(#号后面的值)如果有变化,就会自动调用hashchange的监听事件,在hashchange的监听事件内可以得到改变后的url,这样就能找到对应页面进行加载

历史模式:

利用了H5新增的pushState()、replaceState()方法。当这两个方法执行时,只能改变当前地址栏的URL,但是浏览器不会像后端发起请求,也不会触发popstate事件的执行。

也就是说,完成URL跳转而无需重新加载页面,由于vue是单页面的形式,当后台没有正确配置的时候,需要我们自己去配置404页面

image-20220218151924017

6、动态路由添加

最好和vuex做一个案列理解

7、vue-router怎么重定向的?

用redirect即可定位到相对位置

8、vue-router实现路由懒加载

路由懒加载也就是延迟加载没在需要的时候记加载,随用随载,也是前端优化的一种手段

懒加载的实现方法:

1、ES6标准语法import()

就是定义一个变量,变量就是路由文件,然后在路由中随用随导入

2、Vue异步加载技术

9、Vue-router跳转和location.href有什么区别?

10、怎么配置404页面?

在router.js中 路由是从上到下执行的 只需要在最后一行把path写成 * 并且指定一个404.vue页面即可

如何触发404页面,比如你的域名是http://localhost:8080/,当你进入一个没有声明/匹配的路由页面时就会跳到404页面, 比如访问了http://localhost:8080/无此页面,就会跳到404页面,如果没有声明一个404页面,那就会跳到一个空白页面

11、切换路由时需要保存草稿的功能,怎么实现?

1、用组件内的守卫中的:beforeRouteLeave去实现

2、使用keep-alive去缓存组件

12、切换到新路由时,页面要滚动到顶部或保持原先的滚动位置怎么做呢?

1、使用afterEach

2、该功能只能在H5 history下去使用

13、说说vue-router完整的导航解析流程是什么?(选)

1.导航被触发 2.在即将离开的组件里调用beforeRouteLeave守卫 3.调用全局前置守卫beforeEach守卫 4.在重用的组件里调用beforeRouteUpdate守卫 / 调用路由配置的beforeEnter守卫 5.解析异步路由组件 6.在被激活的组件里调用beforeRouteEnter 7.调用全局的beforeResolve守卫 8.导航被确认 9.调用全局的 afterEach 钩子 10.触发DOM更新 11.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

VUEX

要是看不懂官网的列子就看这篇博客入门就好了

www.jianshu.com/p/a804606ad…

关于mapState、mapAction等的了解可以看看这篇博客

www.cnblogs.com/m2maomao/p/…