我认为有四个方面 第一个是vue3在性能方面有了优化,比如使用了proxy替代Ovject.defineProperty实现响应式数据的监听,提高了响应式数据的访问速度,第二个是在API方面进行了改进,比如通过setup函数代替vue2中的created和mounted生命周期;通过composition API提供了更加灵活的API,可以让代码更方便的复用
数据劫持方式不同:vue2使用的是Object.defineProperty方法对getter和setter进行数据劫持,在数据改变的时候通知订阅者,订阅者收到消息后进行相应的处理,通过原生JS提供的监听数据的API,当数据发生改变的时候在回调函数中改变dom,vue3使用的是proxy对象对数据进行劫持,它可以直接监听对象数组数据类型等的变化
响应式系统初始化方式不同:vue2是在组件实例化是进行初始化的,在这之后添加的属性不会被监听,vue3是在组件渲染的时候进行初始化的在这之后添加的属性也会被监听
ref和reactive实现的方式不同:vue2使用的是ref和reactive两个API实现的响应式数据,ref可以将基本类型的数据变成响应式,reactive可以将对象变成响应式数据,vue3使用的是ref,reactive和toRefs三个API实现相适应数据的toRefs可以将一个reactive对象变成有多个ref对象组成的响应式数据方便再组件中使用
他是ES6新增的一个特性,它可以在一个对象上添加一个代理层,可以拦截到对象的操作,包括读取、设置、删除等操作,他的原理就是通过拦截对象的操作,将其转发到处理器对象进行处理,并返回处理结果,这样可以实现对对象的全面控制和定制化
vue3中新增的一个组合式API,它可以帮我们更好地组织和复用逻辑代码,他更好的支持了TS,让代码的可读性、可维护性更好,使用方式有setup函数替代vue2 created和mounted等生命周期函数,使用rereactive和ref函数创建响应式数据
require是CommonJS规范中加载方法,是Node.js中的模块加载方法,vite是基于ES模块化方案,两者不能兼容,在vite中可以使用import语句来引入模块
v-model、v-if、v-for、v-show、v-bind、v-on、v-text、v-once
TS就是JS的超集,TS是强类型的语言,相对于JS,TS的优势可以在写代码的时候检查代码的类型错误,提高代码的健壮性和可靠性,TS支持类和接口的定义,可以更好的实现面向变成的思想,可以让代码更有结构性和可读性,TS还支持泛型,可以更好的处理不同类型的通用算法,还可以更好的提供代码的不全,提高开发效率
public修饰符是默认的修饰符可以不写,他的属性和方法可以被任何人访问
private修饰符是用于限制列的属性和方法只能在类的内部访问,在类的内部可以使用this访问private修饰符的属性和方法
protected修饰符用于限制类的成员只能在类的内部和子类中被访问,在子类中可以使用super访问protected修饰的属性和方法
any是一种动态类型,表示任意类型,它可以调用任何属性和方法,也可以进行任何操作,但是编译器不能对他进行类型检查和类型推断,一般在使用的时候是在类型不确定的情况下使用可以作为占位符来过渡
JS通过多种方式发送HTTP请求,最常用的就是XMLHttpRequest对象,简称XHR,他是JS中的内置对象,提供程序中发送HTTP请求和接收HTTP响应的功能,可以发送各种类型的请求,例如get、post、put、delete,还可以设置请求头、请求参数、超时时间等,除了XHR,还可以使用axios、jQuery等第三方库发送Http请求
8个阶段,beforeCreate 实例刚刚被创建,都没有初始化,created 实例创建完成,但元素没有生成不能访问dom,beforeMount 实例挂载前,DOM生成,但没有挂载到页面中,mounted 实力挂载完成,dom元素已经插入到页面 ,可以访问元素,before Update,数据更新前的钩子函数,可以对数据进行操作,updated数据更新完成后的一个钩子函数,dom元素已经被更新,beforeDestroy 实例销毁前的一个钩子函数,destroyed 实例销毁后的最后一个钩子函数
可以使用浏览器缓存或服务器缓存,浏览器缓存可以使用HTTP控制缓存头,也可以使用CDN内容分发到网络来缓存静态资源,并将其发到全球各地的服务器提高访问速度
首先需要获取一台服务器,可以选择自己租用或使用云服务器提供的虚拟主机或云主机,然后将代码上传到服务器上面,可以使用git等版本控制工具进行代码同步,根据代码的云心个环境们需要配置响应的服务器环境,将域名注册并指向服务器IP地址,可以使用dns服务商提供的控制面板进行配置,部署完成后进行测试和调试,确保网页可以正常运行,然后将网页发布,让用户使用
在模板中使用v-model指令将input元素value值与vue实例中的message属性进行绑定,双向绑定通过数据劫持和发布订阅者模式实现,当数据发生变化的时候 会触发setter getter方法通知订阅该数据的watcher对象进行更新,更新完成后通知视图进行重新渲染,实现双向绑定的效果
首先先安装node和npm,在安装vue脚手架,然后创建vue项目,使用npm run dev 运行项目,在src目录中进行编码,路由配置,状态管理等
v-if就是根据表达式的值的真假来条件性的渲染元素,值为真则渲染,值为假就不会渲染
v-show 是根据表达式的真假来切换元素的显示和隐藏
v-for 是根据指定的数组或对象来循环渲染元素
v-if和v-show的区别是 v-if是根据条件动态的添加或移除元素,v-show则是通过css来控制元素的显示和隐藏
v-for主要用来循环渲染列表的数据,生成对应的列表元素
单项数据流是指在应用程序中流动方向只有一个方向,比如父级组件到子级组件传递数据,但是子组件不能直接修改父组件的数据,只能像父组件发送事件来请求修改数据,避免了数据的混乱和数据变化冲突
如果后端人员有能力修改接口,可以让后端适配前端的需求,如果后端不方便修改接口的话,可以让前端在前端代码中适配接口,根据后端返回的数据结构进行相应的处理,也可以使用代理服务器在在前后端工作分离比较明显的情况下,使用代理服务器来处理接口不一致的问题
number string boolean null undefined symbol:ES6新增的数据类型,表示独一无二的值
复杂类型有Object ,NAN
在jQuery中,$是一个函数,可以接受一个参数,该参数可以是一个选择器 ,html代码,DOM元素,函数等。 $ 函数返回一个包含匹配元素的jQuery对象,可以更方便的操作DOM元素,执行函数
ajax是一种通过后台与服务器进行数据交互的技术,先安装axios,然后引入他,发送请求
Ajax是一种异步获取数据的技术,他的原理是通过XmlHttpRequest对象来向服务器发送异步请求,类似一个中间层,负责请求数据,而不影响浏览器其他事件执行,等到数据回来之后在通知浏览器,浏览器在进行处理
let和const 用于声明变量和常量,取代了Es5的var关键字
箭头函数,用来声明匿名函数
模板字符串,用于拼接字符串 可以使用反引号和${}表达变量和表达式
解构赋值 用于从对象或数组里面提取值赋给变量
Promise,用于处理异步操作,可以改善回调地狱的情况
模块化,用于将代码分离成独立的模块,避免全局变量污染和命名冲突
设置元素的高度和宽度,同时设置border样式为transparent,这样回显示出一个实心的矩形,然后设置border-top或者bottom、left、right样式为一个实心的边框,这样就可以在某一边生成一个三角形,最后可以使用transform:rotate属性调整三角形的方向和位置,
transition
低代码平台是无需编码或通过少量代码就可以快速生成应用程序的开发平台。也是一款图形化、拖拉拽方式快速实现企业数字化转型中的创新应用、支持用少量代码扩展实现个性化需求的数字技术
工具平台
是css3引入的一种技术,用于根据不同的媒体类型和设备特性来应用不同的样式,可以根据设备的屏幕尺寸来改变网页的布局,字体大小、颜色等样式
rem可以用根据根元素字体大小变化而变化的长度单位,可以在body里面设置
可以使用Array.isArray方法来判断一个变量是富士数组,如果是数组返回true 否则返回false
BOM是浏览器提供的一个JS对象,用于与浏览器窗口和框架进行交互
事件冒泡是指当一个元素上的事件被触发时,他会他会沿着DOM树向上冒泡知道到达根节点或者被阻止为止,事件冒泡可以通过stopPropagation方法来阻止
性能比vue2加快了很多使用了proxy来代替Object.defineProperty,提高了响应式系统的性能和稳定性vue2使用的是选项API,vue3使用的是组合式API,vue3支持tree-shaking,可以更好的优化打包体积,更好的支持TS
原生的HTML表单可以使用input标签的type属性为file的表单元素,Ajax上传可以通过FormData对象将文件数据上传到服务器,第三方组件有Plupload、fine、Uploader
可以将大文件分割成多个小文件,分别上传到服务器,最后在服务端合并成一个完成的文件这样可以减少单个文件上传失败的概率,同时也可以减轻服务器的压力。常见的分片上传组件有webUploader
XMLHttpRquest(XHR)对象:是浏览器提供的原生的Ajax实现方式,通过js向服务器发送异步请求
axios:是一个基于Promise的Http库,可以在node.js和浏览器中发送异步请求
父组件需要向子组件传递内容,但不确定传递的内容是什么,这时候可以使用默认插槽,子组件向父组件传递内容,不确定传递的内容可以使用插槽,子组件向父组件传递多个内容,且这些内容的位置不确定,可以使用具名插槽,父组件需要根据条件来动态传递内容,可以使用作用域插槽
mixin是一种代码复用的机制,可以在组件中共享相同的代码逻辑,他的原理是利用了vue中的选项合并机制。当一个组件使用了一个混入对象时,vue会将混入对象中的选项合并到组件的选项中,按照顺序依次执行
基本上就是在 Vue2 生命周期钩子函数名基础上加了 on
beforeDestory 和 destoryed 更名为 onBeforeUnmount 和 onUnmounted;
然后删了两个钩子函数 beforeCreate 和 created变成了setup函数
分页,可以使用JS等技术对数据进行操作处理,这样可以提高用户体验,可以让用户快速的看到数据,并且可以在页面上进行操作和搜索,先用Ajax向后端请求所有数据,然后计算每页显示的数量和数据总量计算总页数,还有每一页需要娴熟的数据范围,然后把显示的数量分组,让用户点击操作的时候根据用户的操作计算要展示的数据范围显示到页面上
返回值的类型不同import返回的是promise对象,普通函数返回值类型可以是任何类型,他们的作用月也不同import实在模块作用域中执行的,因此在import函数内部定义的变量,函数等都属于模块作用域,普通安徽念书实在全局作用域或者函数作用域执行的,可以访问全局变量和函数
v-for指令会生成一组节点,每个节点都需要一个唯一的key值来标识自己
可以使用定时器或者节流函数来限制用户的请求频率,在用户点击登录按钮的时候添加一个定时器,防止用户重复点击,也可以添加一个验证码,在用户输入账号 密码的时候需要输入验证码才能完成登录
把密码进行哈希处理,可以通过比对哈希值来验证密码是否正确,也可以使用https协议来保护用户的密码不被窃取
可以使用v-model将input表单和数据进行双向绑定,将下拉框的data中的v-model的属性值进行绑定
组件创建的阶段放在vue生命周的钩子函数created或mounted来进行数据的请求,也可以放在vuex状态管理阶段,把完成请求的数据保存到vuex的state里面实现共享数据
可以使用rem和viewport适配,rem是相对于html根元素字体大小的单位,移动端高清适配一般是将字体大小设置为屏幕宽度的一定比例,viewport是值浏览器可视区域的大小,可以通过设置viewport的meta标签,控制页面在不同设备上显示的效果
他主要是三个步骤按下鼠标、移动鼠标、松开鼠标,先获取道拖拽的目标元素,定义鼠标按下的事件处理函数,在计算鼠标再目标元素的坐标,然后在定义鼠标移动时的事件处理函数,最后在松开鼠标的时候,取消鼠标移动的事件处理函数
computed是计算属性,他是根据依赖的数据动态计算出一个新的值,只有在以来数据发生变化的时候才会重新计算
watch是监听指定的数据变化,在数据变化的时候执行指定的回调函数,它可以监听一个复杂的数据结构或者是需要执行异步操作的情况
Promise表示一个异步操作的最终结果,与之交互的方式主要有then方法,该方法主要注册了两个回调函数,用于接受Promise的最终结果和不能执行的原因
Promise三种状态:
结果值:
5. 如果调用的是resolve(),通过then中第一个回调函数获取
6. 如果调用的是reject(),通过then中第二个回调函数获取
他们都是Promise的静态方法,race方法接收一个数组作为参数,返回一个新的Promise对象,Promise对象的状态由第一个完成Promise对象决定,如果第一个promise对象变为fulfilled,返回的promise对象也是fulfilled,否则返回rejected;all如果所有Promise对象状态都是fulfilled,返回的Promise对象也是fulfilled,并且将Promise对象返回值组成一个数组作为返回值,否则返回rejected,并将第一个rejected状态的Promise对象的返回值作为返回值
可以使用浏览器的localStorage或者sessionStore将状态存储到本地,页面刷新或者关闭的时候再从本地读取状态恢复,但是只能存储字符串类型的,需要将状态序列化为字符串后在存储,也可以使用cookie,当页面刷新或者关系的时候从cooie读取状态恢复,这种方法可以存储非字符串类型的数据,但是需要考虑cookie的大小限制和安全问题,还可以使用第三方库比如vuex-persistedstate,将状态存储到本地并恢复
遍历数组和对象,也可以进行一些计数操作,比如统计数组中某个元素出现的次数或字符串中某个字符出现的位置
参数传递方式不同:get请求通过URL传递参数,POST请求通过请求体传递参数
数据量大小限制不同:get请求发送的数据通常不能超过1024字节,post请求没有数据量大小的限制
缓存机制不同:get请求可以被浏览器缓存,post请求不会被浏览器缓存,每次请求都是最新的数据
使用场景不同:get适用于获取数据,比如搜索、i获取文章列表,post适用于提交数据,比如登录、注册、发表评论等
SPA翻译过来就是单页面,SPA 是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验
SPA和MPA的区别
MPA就是多页面应用,每个页面都是主页面,都是独立的,每次访问都需要重新加载html,css,js等文件
优点:
具有桌面应用的即时性、网站的可移植性和可访问性
用户体验好、快,内容的改变不需要重新加载整个页面
良好的前后端分离,分工更明确
缺点:
不利于搜索引擎的抓取
首次渲染速度相对较慢
this指向不同 箭头函数指向定义函数时候的作用域,没有自己的this,普通函数的this指向调用该函数的对象
arguments对象不同:普通函数中有arguments对象,可以获取到函数的参数,箭头函数没有arguments对象,需要使用rest参数获取传入的参数
构造函数不同:普通函数可以作为构造函数使用并且能通过new创建实例对象,箭头函数不能创建实例对象
语法不同:箭头函数比普通函数更简洁,可以省略大括号、function和return
async函数返回一个Promise对象,可以使用await等待异步操作的结构,他们的使用场景是在需要等待异步操作完成后在进行的操作情况下,避免了回调嵌套和Promise链式调用的问题,await只能在async里使用否则会导致语法错误
npm是Node.js官方的包管理工具,npm有大量的开源包可以使用但是他在安装包的时候可能会出现版本冲突的问题,安装时间比较慢
yarn相对于npm,yarn的社区活跃度比较低,但是在安装包的时候速度更快,会通过锁定版本号的方式来解决版本管理的问题,避免冲突
pnpm 更新版本的速度比较慢,社区活跃度也比较低,但是pnpm的缓存机制能让安装包有很好的稳定性,他使用硬链接的方式来管理包,节省了磁盘空间
当我们需要在DOM更新之后执行一些操作的时候可以使用$nextTick方法,他的原理是利用JS的事件循环机制,在DOM更新之后执行回调函数,当vue需要更新DOM的时候,会先将DOM更新任务放入一个队列,然后通过JS事件循环机制,等待所有同步任务完成之后在执行所有异步任务,异步任务执行完成后会执行 $nextTick方法中的回调函数,避免出现DOM没有更新的情况
type只能定义基本类型,interface只能定义对象类型,type可以使用typeof、keyof和in修饰符,interface不支持,type可以使用类型别名,interface不支持,他俩都是用于定义类型,但是type更加灵活,可以定义更多类型,支持更多操作符和语法,interface更加专注于定义对象类型,让代码的可读性和维护性更高
const用于定义常量,readonly用来定义只读属性;const常量必须在定义的时候立即初始化,readonly可以在构造函数中初始化,const常量只能定义基本类型和对象字面量类型,readonly可以定义任何类型的属性,const常量可以在全局和局部作用域中使用,readonly只能在类和接口里面使用
webscoket是一种基于TCP协议的网络协议,它可以在客户端和服务器之间建立持久性的连接,实现双向通信,不需要像HTTP协议那样每次请求都要重新建立连接,它可以实时聊天、数据展示、多人协作,也可以实现实时的游戏互动的功能等
深拷贝会复制对象或数组的所有内容,包括在对象或数组内部的所有属性和子属性,深拷贝后的对象或数组不会影响原对象或数组;浅拷贝只复制对象或数组的引用,不会复制对象或数组的内容,如果修改浅拷贝后的对象或数组的时候,原对象或数组也会受到影响
利用JSON.stringify和JSON.parse方法将对象或数组转换为JSON字符串,然后再将JSON字符串转换为对象或数组,但是他不能复制特殊对象比如正则表达式、日期、map等无法复制,不能复制函数,如果对象存在循环引用可能会导致死循环
const arr=[1,2,3,1,1,2,3,4]
cosnt newArr=Array.from(new Set(arr))
console.log(newArr)
const arr=[1,2,3,1,1,2,3,4]
const newArr=[]
for(let i=0;i<arr.length;i++){
if(newArr,indexOf(arr[i])===-1){
newArr.push(arr[i])
}
}
console.log(newArr)
如果用双重for许愿实现数组去重的话,会出现事件复杂度较高的问题,在数据量较大时会导致性能下降
他们都是js的比较运算符,==比较两个值是否相等,会进行类型转换相等返回true不相等返回false;= = =比较两个值是否严格相等不会进行类型转换,相等返回true,不相等返回false
虚拟DOM,也就是我们常说的虚拟节点,用于比对虚拟DOM和真实DOM的差异,从而进行局部渲染达到优化性能的目的,起初在使用JS/jQuery的时候,我们不可避免的会大量的操作DOM元素,导致一直引发回流或者重绘,降低了渲染页面的性能,虚拟DOM就是由此而生,虚拟DOM的出现大大的降低了因为频繁操作DOM引起的性能问题 。
diff算法可以算作是一种对比手法,对比的对象是新旧虚拟DOM,diff算法可以找到新旧虚拟DOM 之间的差异,但diff算法并不只是对比虚拟DOM,还有根据对比后结果更新真实DOM,由于diff算法对比的是虚拟Dom,而虚拟Dom是呈树状的,所以我们可以发现,diff算法中充满了递归。
闭包=内层函数+引用的外层函数变量,闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。本质上,闭包是将函数内波和函数外部连接起来的桥梁。
闭包的作用:延长了变量的生命周期
闭包的特点:
当一个函数返回另一个引用数据类型的时候被外界所接收了,就会形成一个不会被销毁的作用域局部变量会常驻在内存中
函数之间会生成一个私有作用域,防止全局变量污染
闭包的缺点:
可能会造成内存泄漏或溢出
内存泄漏:浏览器无法回收代码的内存,比如说一个对象或者数组
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
共同点:都是用来存储数据的
不同点:
一、储存的时间有效期不同
1、cookie的有效期是可以设置的,默认是关闭浏览器后失效
2、sessionStorage的有效期仅在当前页面显示,关闭浏览器后就会失效
3、localStorage是永久有效期,在不手动删除的情况会一直存在
二、存储的大小不同
1、cookie的存储在4kb左右,但是可以存20个cookie左右
2、localStorage和sessionStorage的存储容量是5Mb
三、存储的位置不同
1、cookie是存储在服务器和浏览器中的
2、localStorage和sessionStorage只在浏览器中存储
共同点:都是用来控制页面元素的显示和隐藏
不同点:v-if显示隐藏是将DOM元素添加和删除,v-show显示隐藏是为该元素的css设置display:none,DOM元素依旧存在
MVC:,M(Model):模型层。是应用程序中用于处理应用程序数据逻辑的部分,模型对象负责在数据库中存取数据;
V(View):视图层。是应用程序中处理数据显示的部分,视图依旧是模型数据创建的;
C(Controller):控制层。是应用程序中处理用户交互的部分
MVVM:M(Model):模型层,就是业务逻辑相关的数据对象;
V(View):视图层。展现出离开的用户界面
**VM(ViewModel)**视图模型层。连接view和model的桥梁。
MVVM和MVC都是一种设计思想,主要就是MVC中Controller演变成MVVM中的viweModel。MVVM主要解决了MVC中大量DOM操作使页面渲染性能降低,加载速度变慢的问题。
MVVM和MVC最大的区别就是:它实现了View和Model的自动同步;当Model的属性改变时,我们不用在自己手动操作DOM元素来改变View的显示,他会自动变化,整体看来,MVVM比MVC精简很多,我们不用频繁的操作DOM;MVVM并不是用VM完全取代了MVC,ViweModel存在的目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其他视图操作业务等还是应该放在Controller实现。
1、隐式的创建了一个空对象 new Object()
2、让this指向这个空对象 this=new Object()
3、让proto指向原型对象
4、在this上添加属性和方法
5、隐式的返回创建好的对象return
函数是什么? 函数就是由事件驱动的或者当他被他调用时执行的可重复使用的代码块
如果data是一个对象的话,对象是一个引用类型,他会在堆空间中开辟一片区域,将内存地址存入,这就使得所有的组件公用一个data,当一个组件修改了data的数据就会出现一变全变的现象
如果data是一个函数的话,使用一个return返回一个对象;这就使得每服用一次组件就会返回一个全新的data,就相当于scoped,每一个组件都是私有的,互不干扰。
总结来说
1、是为了在重复创建实例的时候避免共享统一数据造成的数据污染
2、写函数的原因是为了保证这个对象是独立的,如果可以保证对象是唯一的,也可以不写函数直接写对象
js规定每一个构造函数都有一个prototype属性,每个对象都有__proto__属性,原型对象是个对象也拥有__proto__属性,指向上一级的原型对象,一层一层向上指,那么这种关系像链条一样就是原型链
作用 :原型链是为对象查找属性和方法指明一个方向
查找规则 :实力对象先在自身上面查找属性,如果自身没有,会顺着原型链下个上查找,知道找到原型链的终点为止,如果整个原型链上没有这个属性,那么结果是undefined,如果整个原型链没有这个方法,那么结果是报错
改变this指向的方式一共有三种:call、apply、bing
共同点:
1、都能改变this指向,第一个传递的参数就都是this指向的对象
2、三者都能采用后续传参的形式
不同点
1、call的传参是单个传递的,而apply后续传递的参数是数组形式,而bind没有规定,传递值和数组都可以
2、call和apply函数的执行是直接执行的,而bind函数会返回一个函数,然后我们想要调用的时候才会执行
由于箭头函数没有自己的this指针,通过call()或apply()方法调用一个函数时,只能传递参数,他们的第一个参数会被忽略
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
vue的数据双向绑定将MVVM作为数据绑定的入口,整合observer,Compile和Watcher,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令。最终利用Watcher搭起observer和Compile之间的通信桥梁,达到数据变化----->视图更新;视图交互变化(input)------>数据model更新双向绑定效果
SPA翻译过来就是单页面,SPA 是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验
SPA和MPA的区别
MPA就是多页面应用,每个页面都是主页面,都是独立的,每次访问都需要重新加载html,css,js等文件
优点:
具有桌面应用的即时性、网站的可移植性和可访问性
用户体验好、快,内容的改变不需要重新加载整个页面
良好的前后端分离,分工更明确
缺点:
不利于搜索引擎的抓取
首次渲染速度相对较慢
首屏时间,指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗的内容,在页面渲染工程中导致加载速度变慢的原因可能是:1、网络延时问题
2、资源文件体积是否过大
3、资源是否重复发送请求去加载了
解决方式:
1、减小入口文件体积
使用路由懒加载,把不同路由对应的组件分隔成不同的代码块,待路由被请求的时候会单独打包路由,让入口文件变小,提高加载速度
2、静态资源本地缓存
采用http缓存,设置cache-Control,Last-Modifed,etag等响应头
采用 Servirce Worker 离线缓存
3、UI框架按需加载
4、图片资源压缩
对页面上使用到的icon,可以使用在线字体图标,或者雪碧图,将众多小图标合并到同一张图上,减轻http请求压力
5、组件重复打包
假设A.js文件是一个常用的库,现在有多少个路由使用了A.js文件,这就造成了重复下载,在webpack的config文件中,修改CommonsChunkPlugin的配置
本质上他两都是优化高频率执行代码的一种手段,
如浏览器的resize 、scroll、keypress、mousemove等事件触发时,会不断的调用绑定在事件上的回调函数,极大的浪费资源,降低前端性能,为了优化体验,需要对此类事件进行调用次数的限制,对此我们可以采用节流和防抖的方式来减少频率。
节流:n秒能只运行一次,若在n秒内重复触发,只有一次生效
防抖:n秒后在执行该事件,若在n秒内被重复触发,则重新计时
比喻:假如电梯有两种运行模式,节流和防抖,超市设置为15秒。电梯等第一个人进来后,15秒后开始运送,这是节流,电梯等待过程中又有人进来那么会重新从15秒计时,这是防抖
共同点:都可以使用setTimeout实现
目的都是降低回调执行频率,节省计算资源
应用场景
节流:滚动加载,加载更多或滚到底部监听
搜索框,搜索联想功能
防抖:搜索框搜索输入。只需用户一次输入完,再发送请求
手机号、邮箱验证输入检测
窗口大小调整
首先先明确两点:
1、JS执行机制是单线程
2、JS的Event loop是JS的机制,深入了解Event loop,就等于深入了解JS引擎的执行
单线程带来了什么问题?
在JS执行中都是单线程执行,所以代码的执行都是自上而下,如果前一段代码出现问题,就会导致下一段代码无法执行,对用户来说就是卡死现象,所以在JS机制引出了异步操作。
异步解决了什么问题?
异步操作很好的解决上面单线程执行出现的卡死现象,但也会产生问题,比如对同一件事,不知道应该执行哪一个
同步和异步到底是什么呢
同步任务是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务,异步任务指的是,不进入主线程,而是进入任务队列的任务,只有等主线程任务执行完毕,任务队列开始通知主线程,请求执行任务,该任务才会进入主线程执行。
1、所有同步任务都在主线程上面执行,形成一个执行栈
2、主线程之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列之中放置一个事件
3、一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有那些事件,那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行
4、主线程不断重复上面的第三步
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。
“任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列”,就是读取里面有哪些事件。
当输入了URL的时候,首先会进行一个DNS的解析就是把你输入的网址转换成相对应的ip地址,然后进行TCP的建立这时候看它是http还是https如果是https的话还有一个SSR套阶层,这个主要是为了安全,然后回进行三次握手四次挥手,具体四次挥手的时候主要看有没有设置keep alive的属性,如果没有设置所有的请求都会进行三次握手四次挥手,但是非常浪费时间,但是现在从Http1.0之后,所有都会默认加keep alive属性,然后所有的访问http请求之后才会进行四次挥手,所有的数据都会进行网络五次模型,然后拉数据,如果是单页面的开发,他会首先拉我们的html文档,然后从上到下加载资源
当加载到html的时候他会生成dom,加载到css的时候会生成css tree,css tree和DOM会同步解析,但是加载到JS的时候不论是加载还是解析他都会阻塞到整个HTML的渲染,js内部又会分为同步任务和异步任务,同步任务从上到下执行,当碰到异步任务的时候,他会放在队列里面按照队列的顺序执行,异步任务又分为宏任务和微任务像promise.then promise.cath基本就是微任务;setTmieout定时器、文件操作等就是宏任务
同源就是客户端向服务器发送请求的时候,如果协议,域名(IP)和端口都一样就是同源,但凡有一个不一样就是跨域
解决跨域方法1:
利用script中src属性发送jsonp请求但是这种方式只支持get请求无法解决其他的请求类型
解决跨域方法2:
前端配置一个代理服务器proxy代理浏览器去发送请求:因为服务器与服务器之间是可以通信的不受同源策略的影响
服务端:
服务端通过配置cors来解决跨域,配置响应头:setHeader(Access-Control-Allow-Origin:*)
Vue的响应式指的式:data组件发生变化,立即触发视图的更新。
原理:Vue采用数据劫持结合发布者、订阅者模式的方式来实现响应式的数据,通过Object.definProperty数据劫持setter、getter,当数据发生改变的时候,立即通知给订阅者做出相对应的处理,通过原生JS提供的监听数据的API,数据发生改变时,在回调函数中修改DOM
特点:默认数据的属性不能修改,描绘属性和存取属性不能同时使用,使用会报错
缺点:1、一次性递归到底开销很大,如果数据很大会导致栈溢出
2、监听不到对象新增属性和删除属性
keep-alive是vue内置的一个组件,它主要用来保存组件的状态或者避免重新渲染,减少加载的时间,提高性能。他有三个属性include 只有被匹配到的组件被保存,exclude 只有被匹配到的组件不会被保存 ,max 最多可以缓存的组件 ,一旦数字达到了最大,在新的实例创建之前,在已缓存的组件最久没有被访问的组件的实例会被销毁掉,同时可以结合路由的meta的属性来控制,在其中设置keep-alive:true,但是有一个问题,因为组件缓存,并没有销毁,也不会调用created生命周期的函数,所以在进入之前触发activated()、退出时触发deactivated()
1、资源优化
利用webpack、gulp等模块化工具,将css代码进行压缩,让文件变小降低浏览器的加载时间
2、减少使用昂贵的属性
在页面发生重绘的时候,昂贵属性入 box-shadow、border-radius、filter、透明度等,会降低浏览器的渲染性能
3、不要使用@import
css有两种引入方式,一种是link元素,另一种是@import,@import可能会导致下载顺序紊乱,比如一个css文件 index.css包含了一下内容@import url(“reset.css”),那么浏览器就必须先把index.css下载执行后,才下载、解析和执行第二个文件reset.css
4、把小的icon图片转成base64编码
从两个方面入手,浏览器获取页面资源更快和浏览器页面渲染更快。浏览器获取页面资源更快:
1、减少文件打包的体积,通过webpack配置公共模块抽离,js/css代码丑化,tree-shaking 甩掉没用模块等方式减少文件体积
1.2、减少传输文件的体积,通过常见的压缩算法如gZIP,对打包文件压缩后传输
1.3、懒加载,让文件按需获取,减少首次获取文件的体积
1.4 、增加传输速率,通过CDN内容分发网络,缓存部分页面资源,选择较近的代理服务器返回资源
浏览器渲染页面更快
2.1、引入JS脚本后放在body标签的后面,引入css脚本放在body前面,防止页面渲染阻塞
2.2、批量操作dom,减少页面回流次数
2.3、防抖和节流,限制事件监听函数被触发频率减少页面重绘次数
重绘:当前节点需要更改外观而不会影响布局的,比如改变background就叫重绘
回流:布局或者几何属性需要改变就称为回流,比如改变盒子大小,改变字体,添加或删除样式等
回流一定发生重绘,重绘不一定引发回流。
减少回流的方案:1、减少css3的transform
2、减少display的使用
3、css选择符从右往左匹配查找,避免节点层级过多
在实际开发中手机端1px像素的线条看上去会比实际粗一点
解决方案:1、媒体查询利用设备像素比例缩放,设置小数像素,但是这种方法兼容性十分差,一般浏览器不支持小数
2、transform:scale(0.5)推荐使用
v8引擎使用的是准确式GC,GC算法采用分代式垃圾回收机制,分为新生代和老年代,这两个部分空间大小和生命周期是不一样的,新生代空间小,生命周期短;老年代空间大,生命周期也很长
var会提升变量 let const不会
var在全局命名会挂载到window上, let const 不会
let和const 有块级作用域,var没有
1、原型链继承 缺点:内存共享,一个发生改变,另一个也会发生改变
2、构造函数继承缺点:父类的引用属性不会被共享
3、组合继承
4、原型式继承 缺点:多个实例的引用类型属性指向相同的类型,存在篡改的可能
状态一般指通过pinia、vuex来保存的全局可用的变量,当页面被刷新的时候,之前存储的数据不见了,实现状态持久化:
vuex
1、安装 vuex-persistedstate包
2、在moudles文件里面配置引入vuex-persistedstate
3、它默认是存储在localStore或者是sessionStore里面,如果想实现部分持久化可以借助path参数
pinia
1、安装pinia-plugin-persistedstate插件
2、在main.ts引入持久化插件注册
3、在组件中使用persist可以设置key名字和存储的类型
Ajax是一种异步获取数据的技术,他的原理是通过XmlHttpRequest对象来向服务器发送异步请求,类似一个中间层,负责请求数据,而不影响浏览器其他事件执行,等到数据回来之后在通知浏览器,浏览器在进行处理
webpack的运行过程是一个串行的过程,从启动到技术会依次执行以下流程:
1、初始化参数:从配置文件读取合并参数,得到最终的参数
2、开始编译:用得到的参数初始化Complier对象,加载所有配置的插件,开始执行编译
3、确定入口:根据配置中的entry找到所有入口文件
4、编译模块:从入口文件出发,调用所有配置Loader对模块进行编译,在找出该模块依赖的模块,在递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
5、完成模块编译:在经过Loader翻译完所有模块后,得到了每个模块被翻译后 的最终内容以及他们之间的依赖关系
6、输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件加入到输出列表,这是可以修改内容的最后机会
7、输出完成:在确定好输出内容好根据配置确定的路径和文件名把文件夹内容写入到文件系统
webpack需要先打包才运行
vite比webpack更快不需要打包就直接可以在浏览器中运行,构建项目很快
vue3.2 中 只需要在 script 标签上加上 setup 属性,组件在编译的过程中代码运行的上下是 setup() 函数中不在需要一直return页面中使用数据或者方法
pinia对TS支持很友好,vuex 对TS支持不友好
pinia管理数据比vuex更直观,跨模块通信直接导入使用就可以了,但是在vuex里面跨模块需要指定这种this.$store.dispacth()
首先需要安装axios包然后在src目录中新建一个request的文件夹,在里面新建一个index.js和api.js文件在index.js文件里面封装axios,api.js用来统一管理我们的接口,我们的项目环境可能会有开发环境、测试环境和生产环境,通过node 的环境变量匹配默认的接口axios.defaults.baseURL设置axios的默认请求地址,也可以通过axios.defaults.timeout设置默认请求超时时间,假如超过了10s,就会通知当前用户请求超时,请刷新等
请求拦截器:发送请求前会先经过请求拦截器,在每次发送请求的时候判断是否存在token,如果存在token,则统一在http请求的header上都加上token,后台会根据你携带的token判断登录情况一般来说登录完成之后,token会存在localstore或者是存在cookie本地,然后用户在进入页面的时候,首先会存本地存储中读取token,如果token存在说明用户已经登录过了,则更新token的状态,如果没有token,就说明没有登录过然后在响应拦截器的在第二个函数响应失败的处理 、统一处理消息提示、如果token 过期则清空token跳转到登录页面
mixins混入的意思,是一种分发在Vue组件中可复用功能的非常灵活的方式,他只要将公用的功能以对象的方式传入mixins中当组件使用mixins对象是所有mixins对象的选项都将背混入到组件本身的选项中来,这样就可以提高代码的重用性,使代码更加简洁和易于维护。
这个项目涉及到主题色,各个组件都要使用这个主题色,需要在每一个组件里面引入这个主题色,很麻烦,所以使用了style-resoures-loader插件自动注入到各个组件里面
如果要是不使用路由懒加载,他是直接将项目中所有的组件一次性加载,页面首次加载会很慢,不利于用户体验 使用路由懒加载的目的是只有在这个路由被访问到了的时候,才会加载对应的组件,使用vue3新增的辅助函数defineAsyncComponent用来显示声明异步组件
组件数据懒加载是滚动到了组件的可视区,再去发送当前组件的ajax请求,避免页面一加载就发送出很多请求,减少服务器的压力使用@vueuse/core 里面有一个属性是useIntersectionObserver当滚动到可视区的时候发送Ajax请求,使页面数据加载更快
因为项目图片太多导致页面加载速度变慢,解决:默认不设置图片标签的src属性,自己做了lazy指令指令里的核心是通过vue3中@vueuse/core 里面有一个属性是useWindowScrool可以检测到滚动的x轴y轴的距离检测页面滚动的高度是否到了图片元素的可视区,如果到了再去动态的设置src属性,
检测滚动高度:1.原生js-scollp 2.vue3中@vueuse/core 里面有一个属性是useWindowScrool可以检测到滚动的x轴y轴的距离
<script>
import { defineAsyncComponent } from 'vue'
const child = defineAsyncComponent(() => import('@/components/async-component-child.vue'))
export default {
name: 'async-components',
components:{
'child': child
}
};
</script>
1、路由懒加载
2、组件数据懒加载
3、图片懒加载
4、代码压缩
5、精灵图使用
6、gzip压缩
7、减少未使用变量方法 的声明
@vueuse/core库和vue深度集成的里面的一个方法useMouseInElement 检测鼠标是否滑入了图片内,划入后记录鼠标的位置,让遮罩层跟随鼠标移动,设置大图的位置负方向位移2倍数,限制上下左右滑动的范围
定义一个名为“numbox”的组件,它包含三个部分:一个减少按钮、一个文本框和一个增加按钮。在组件的methods中定义两个方法:increment和decrement。increment方法用于增加数量的值,decrement方法用于减少数量的值。在父组件中使用v-model语法糖将numbox的数量值绑定到a属性上这样,当用户修改数量时,父组件中的quantity属性也会随之更新,我们就可以通过quantity属性来获取用户选择的商品数量,从而实现商品数量功能。
sku是最小库存量单位,路径字典是将商品的sku信息转化成一个字典,其中每个键代表一个属性名称,每个值代表该属性下的所有选项,例如一个T恤的sku信息,可能包括颜色、尺码等属性,在实现商品的选择与禁用功能,我们可以根据用户的选择,动态跟新路径字典,如果选了红色的T恤,那么路径字典中颜色这个键的取值就会变成红色,如果商品的sku信息没有红色,那么在颜色这个键下的红色就回被禁用
点击选择地区展示一个容器,容器中展示所有的省份,点击省份要切换到像对应的省下面的市,点击市的时候在切换到下级的区,这里面的核心就是点击的时候获取到省市县的下标值实时切换数据
先安装vee-validate,在main.js中引入vee-validate并配置、在需要校验的表单中使用和组件来包裹表单控件,通过设置rules属性来指定该控件需要遵守的校验规则、通过v-if来控制提示信息的显示。如果该表单控件未通过校验,则会显示相应的提示信息,否则不会显示任何内容。
先安装pinia和 pinia-plugin-persistedstate的依赖,然后创建pinia实例配置,通过pinia.use()方法使用了pinia-plugin-persistedstate插件,将用户登录信息自动同步到localstorage中,创建store并定义状态null和mutations属性中定义两个方法,分别用于设置和清除用户登录信息,在登录页面中使用AuthStore,在获取到的实例使用handlesubmit方法调用设置用户登录信息的方法,同时调用另一个方法,清除用户登录信息
在封装通用倒计时函数时,我们可以使用Vue3提供的ref()函数和computed()函数来创建响应式变量和计算属性,我们可以使用ref()函数创建2个名为响应式变量,用于存储倒计时的剩余时间和存储倒计时的计时器;使用computed()函数创建一个名为isCountingDown的计算属性,用于判断当前是否正在倒计时。在短信登录功能中,我们可以在点击发送验证码按钮时调用startCountdown()方法开始倒计时。同时,在每次更新计时器时,我们还需要根据isCountingDown变量的值来更新发送验证码按钮的文本内容,以提示用户当前的倒计时状态。
安装Vue-roter创建一个路由的实例挂载到vue实例上,并使用vue.use方法注册vueRouter定义路由,每个路由规则配置path路径、name名称和component组件。然后在创建一个VueRouter实例,传入路由规则,然后在需要使用路由的页面配置路由的入口和router-link
先在路由配置中添加meta属性,用来标识该页面需要登录,然后设置requiresAuth为true,表示该页面需要登录,在创建一个路由首位,路由守卫分为全局首位和路由独享守卫,这里使用全局守卫来实现路由权限控制。在守卫中判断该页面是否需要登录就是设置的requiresAuth是否为true,然后在判断用户是否登录,如果需要登录但用户未登录,就跳转到登录页面,否则就继续访问
先创建一个form表单,在表单提交数据里面创建一个FormData对象,使用append方法将表达数据添加到对象中
复选框可以使用v-model指令实现双向绑定,在数据模型里面添加一个checked属性,保存每个商品的状态,初始值设为false,在模板中使用v-model指令和checked属性和复选框绑定起来,实现双向绑定,在点击某个复选框,通过change事件监听调用checkitem方法,更新商品的状态,在通过!取反,实现选中和取消的切换,使用allchecked计算属性判断所有商品是否被选中,在使用v-model指令将计算属性和全选框绑定,结算的时候遍历购物车里面所有选中的商品,计算他们的总价展示给用户,再提供一个结算按钮,将选中的按钮通过完整计算属性