css部分
CSS如何画⼀个三⻆形?原理是什么?
(1)利用边框绘制三角形
.triangle{
width: 0;
height: 0;
border-width:10px;
border-style: solid;
border-color: pink transparent transparent transparent;
}
我们平时直接是border的复合写法,现在把他们分开就好
(2)利用伪元素绘制三角形
.triangle {
position: relative;
width: 0;
height: 0;
}
.triangle::before {
content: '';
position: absolute;
top: 0;
left: 0;
border-width: 10px;
border-style: solid;
border-color: pink transparent transparent transparent;
}
vue系列
你对SPA单页面的理解,它的优缺点分别是什么?
SPA (Single Page Application) 是一种 web 应用程序的架构模式,它的目标是在单个页面上提供更流畅的用户体验。传统的多页应用程序通过每次用户导航时重新加载整个页面,而 SPA 则是通过使用 JavaScript 动态地更新页面的部分内容,从而避免了页面的完全刷新。
在 SPA 中,初始页面加载时会下载一个包含所有必需资源(如 HTML、CSS、JavaScript 等)的单个页面。然后,通过 AJAX 或类似的技术进行异步数据交换,并根据用户的交互动态更新页面的特定部分,以实现页面的切换和内容的更新。
SPA 的一些主要特点和优势:
-
无刷新体验:SPA 可以在不刷新整个页面的情况下进行导航和内容更新,提供了更流畅的用户体验。
-
前后端分离:SPA 通常采用前后端分离的架构,由前端负责渲染视图和处理用户交互,后端提供 API 接口用于数据交换。
-
更快的加载速度:因为只需要加载初始页面一次,后续的页面操作和内容切换可以通过异步加载和更新,减少了网络请求的次数和数据的传输量。
-
良好的可维护性:由于前后端职责分离,开发团队可以更好地关注各自的领域,并且前端代码通常更易于管理和维护。
-
丰富的交互体验:SPA 可以通过动态加载内容、页面过渡效果、实时更新等功能提供更丰富的用户交互体验。
劣势:
- 不利于搜索引擎的抓取
- 首次渲染速度相对较慢
SPA⾸屏加载速度慢的怎么解决?
- ⽹络延时问题
- 资源⽂件体积是否过⼤
- 资源是否重复发送请求去加载了
- 加载脚本的时候,渲染内容堵塞了
解决方案
- 减⼩⼊⼝⽂件积
- 静态资源本地缓存
- UI框架按需加载
- 图⽚资源的压缩
- 组件重复打包
- 开启GZip压缩
- 使⽤S SR
1、减小入口文件体积
常⽤的⼿段是路由懒加载,把不同路由对应的组件分割成不同的代码块,待路由被请求的时候会单独打包路由,使得⼊⼝⽂件变⼩,加载速度⼤⼤增加。在 v u e -r o u t e r 配置路由的时候,采⽤动态加载路由的形式。routes:[path: 'Blogs' ,name : 'ShowBlogs' ,component : () => import ( './components/ShowBlogs.vue' )]以函数的形式加载路由,这样就可以把各⾃的路由⽂件分别打包,只有在解析给定的路由时,才会加载 路由组件
2、 静态资源本地缓存
后端返回资源问题:采⽤ H TTP 缓存,设置 C a c h e - C o n tr o l , L a s t- M o d i fi e d , Et a g 等响应头采⽤ Se r v i c e Wo r k e r 离线缓存前端合理利⽤ l o c a lSt o r a g e
3、UI框架按需加载
import ElementUI from 'element-ui'
Vue.use(ElementUI)
但实际上我⽤到的组件只有按钮,分⻚,表格,输⼊与警告 所以我们要按需引⽤
import { Button, Input, Pagination, Table, TableColumn, MessageBox } from 'element-ui';
Vue.use(Button)
Vue.use(Input)
Vue.use(Pagination)
minChunks: 3
v-show和v-if
共同点
为true时,都会占据页面位置,当表达式为false时,都不会证据页面位置
区别
-
渲染方式:
v-show
是通过 CSS 控制元素的显示与隐藏,将元素的display
样式属性设置为none
或恢复为默认值来切换元素的可见性,dom元素依旧存在。而v-if
是真正的条件渲染,根据表达式的值决定是否在 DOM 中创建、插入或移除元素。 -
初始渲染开销:
v-show
在初始渲染时,无论条件是true
还是false
,都会立即渲染并保留元素的 DOM 结构,但使用 CSS 将其隐藏。相对而言,v-if
会根据条件渲染决定是否创建该元素的 DOM 结构。因此,如果元素在初始渲染时很少出现或经常更改条件,v-show
的初始渲染开销较低,而v-if
可以减少初始渲染的开销。 -
切换开销:
v-show
在切换时只需改变元素的 CSS 显示属性,开销较小。而v-if
在条件发生改变时需要销毁或创建元素的 DOM 结构,开销相对较大。 -
惰性渲染:由于
v-show
在初始渲染时始终保留元素的 DOM 结构,所以对于频繁切换的元素,v-show
可能更适合,因为它不需要重复创建和销毁 DOM。而v-if
适用于一次性或较少变化的元素,可以节省内存。 -
v-show由false变为true的时候不会触发组件的生命周期,v-if由false变为true的时候,会触发组件的beforeCreate,create,beforeMount,mounted钩子,由true变为false的时候触发组件的beforeDestory,destoryed方法
总的来说,如果需要频繁切换元素的可见性,并且元素在初始渲染时经常出现,可以使用 v-show
。如果条件很少改变或元素在初始渲染时很少出现,可以使用 v-if
。v-if
有更高的切换消耗;v-show
有更高的初始渲染消耗。
Vue中的$nextTick有什么作⽤?
什么是NextTick
官方定义为:在下次 D O M 更新循环结束之后执⾏延迟回调。在修改数据之后⽴即使⽤这个⽅法,获取更新后的 D O M。
意思是:当 Vue 进行数据更新时,DOM 并不会立即更新。Vue 使用异步更新队列将所有的数据变化收集起来,并在下一个 DOM 更新周期中进行批量更新,以提高性能和效率。而 $nextTick 则是用于在 DOM 更新完成后执行额外的操作。
$nextTick 方法有以下作用:
-
DOM 操作同步化:在某些情况下,我们可能需要在更新 DOM 后立即操作或访问更新后的 DOM。例如,在使用 Vue 更新数据后,需要获取更新后的 DOM 尺寸、属性或对其进行手动操作时,可以通过 $nextTick 来确保这些操作在 DOM 更新后执行。
-
更新后的数据反映:当数据发生变化时,Vue 并不会立即更新相关的 DOM 元素。如果需要在数据更新后获取更新后的数据状态,可以使用 $nextTick 确保获取到最新的数据。比如,在修改数据后,希望获取更新后的数据值或状态,就可以使用 $nextTick 来确保数据已经更新。
-
异步操作处理:有时,我们需要执行一些异步操作,例如在数据更新后发送请求或执行其他耗时的操作。使用 $nextTick 可以确保在 DOM 更新完成后再执行这些异步操作,避免出现操作过早或 DOM 未更新的问题。
JavaScript系列
介绍一下undefined(了解)
undefined
是一个特殊的值,表示变量没有被显式赋值或不存在。
1、未定义的变量:如果在代码中使用了未声明的变量或访问了对象中不存在的属性,那么其值将会是 undefined
。例如:
let x; // 未定义的变量
console.log(x); // 输出 undefined
const obj = { name: 'Alice' };
console.log(obj.age); // 输出 undefined,因为 age 属性不存在
2、函数返回值:如果函数没有明确返回值或者函数中没有 return
语句,那么函数的返回值将会是 undefined
。例如:
function foo() {
// 没有明确的返回值
}
const result = foo();
console.log(result); // 输出 undefined
3、可选参数:如果调用函数时未传递某个参数,那么该参数的值将会是 undefined
。可以通过设置默认值来避免参数为 undefined
。例如:
function greet(name) {
console.log(`Hello, ${name}!`);
}
greet(); // 输出 Hello, undefined!
function greetWithDefault(name = 'Anonymous') {
console.log(`Hello, ${name}!`);
}
greetWithDefault(); // 输出 Hello, Anonymous!
4、检查未定义:可以使用严格相等运算符(===
)将变量与 undefined
进行比较来检查变量是否为 undefined
。例如:
let x;
if (x === undefined) {
console.log('变量 x 是未定义的');
}
说说JavaScript中的数据类型?仓储上的差别
分为俩种数据类型:基本数据类型和复杂数据类型
基本数据类型:Number,String,Bollean,Undefined,null,Symbol
引用数据类型:Object,Array,Function(还包括Date
、RegExp
、Map
、Set
等内置函数)
存储区别:基本数据类型存储在栈中,引用数据类型的存储与堆中。(引用类型数据存放在堆中,每个堆内存对象都有对应的引用地址指向它,引用地址存放在栈中)
- 声明变量时不同的内存地址分配:
- 简单类型的值存放在栈中,在栈中存放的是对应的值
- 引用类型对应的值存储在堆中,在栈中存放的是指向堆内存的地址
- 不同的类型数据导致赋值变量时的不同:
- 简单类型赋值,是生成相同的值,两个对象对应不同的地址
- 复杂类型赋值,是将保存对象的内存地址赋值给另一个变量。也就是两个变量指向堆内存中同一个对象
判定数据类型的方法
1、typeof 是用来判断数据的类型 结果是内容全小写
typeof 100 'number'
typeof '123' 'string'
typeof true 'boolean;
typeof undefined 'undefined'
typeof function(){} 'function'
typeof null 'object'
typeof [] 'object'
typeof {} 'object'
2、instanceof 判断一个任意类型对象的具体类型
判断前面的是不是后面构造函数的实例 按照原型链 可以判定Array ,object
[] indtanceof Array true
{} indtanceof Object true ....
3、Object.prototype.toString.call(值) '[object Number]'
console.log(Object.prototype.toString.call(123)); //[object Number]
console.log(Object.prototype.toString.call('123')); //[object String]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(true)); //[object Boolean]
console.log(Object.prototype.toString.call({})); //[object Object]
console.log(Object.prototype.toString.call([])); //[object Array]
console.log(Object.prototype.toString.call(function(){})); //[object Function]
console.log(Object.prototype.toString.call(null)); //[[object Null]]
4.constructor
console.log("123".constructor === String); // true
console.log(123.constructor === Number); // true
性能优化
前端性能优化的方法有什么
-
压缩和合并文件:通过压缩和合并CSS、JavaScript和HTML文件,减少文件大小和请求次数,从而加快页面加载速度。
-
图片优化:使用适当的图像格式(如JPEG、PNG或WebP),并压缩图片以减小文件大小。还可以使用懒加载技术,延迟加载屏幕上可见的图片,减少初始加载时间。
-
使用CDN加速:将静态资源(如CSS、JavaScript和图片)存储在内容分发网络(CDN)上,使用户可以从离其最近的服务器获取数据,加快页面加载速度。
-
延迟加载和按需加载:将非关键和不可见的内容延迟加载,只在需要时动态加载。例如,延迟加载图片、滚动到可见区域再加载更多内容等。
-
避免重定向:过多的重定向会增加额外的请求时间。确保使用直接的URL连接,避免过多的重定向链。
-
CSS和JavaScript优化:尽量减少CSS和JavaScript文件的数量和大小。可以使用工具进行压缩、合并和混淆代码,同时删除未使用的代码和注释以减小文件大小。
-
使用缓存:合理设置缓存策略,使重复访问的资源能够从缓存中获取,减少服务器请求。对于动态内容,可以使用客户端缓存技术(如LocalStorage)来保存临时数据。
-
响应式设计:采用响应式设计,使网站或应用程序适应不同屏幕尺寸和设备类型,提供更好的用户体验。
-
减少DOM操作:频繁的DOM操作会触发页面重新渲染,影响性能。通过批量处理DOM操作或使用虚拟DOM技术(如React、Vue等)来减少对DOM的直接操作。
-
性能监测和调优:使用工具进行性能监测和分析,识别潜在的性能瓶颈,并进行相应的优化调整。
-
脚本优化:减少重绘和回流、缓存DOM选择与计算、缓存.length的值、尽量使用事件代理、尽量使用id选择器、touch事件优化.尽量改变class而不是style,使用classList代替
git问题
常用的命令有那些
启动
一个git
项目的初始有两个途径,分别是:
- git init [project-name]:创建或在当前目录初始化一个git代码库
- git clone url:下载一个项目和它的整个代码历史
日常基本操作
- git init 初始化仓库,默认为 master 分支
- git add . 提交全部文件修改到缓存区
- git add <具体某个文件路径+全名> 提交某些文件到缓存区
- git diff 查看当前代码 add后,会 add 哪些内容
- git diff --staged查看现在 commit 提交后,会提交哪些内容
- git status 查看当前分支状态
- git pull <远程仓库名> <远程分支名> 拉取远程仓库的分支与本地当前分支合并
- git pull <远程仓库名> <远程分支名>:<本地分支名> 拉取远程仓库的分支与本地某个分支合并
- git commit -m "<注释>" 提交代码到本地仓库,并写提交注释
- git commit -v 提交时显示所有diff信息
- git commit --amend [file1] [file2] 重做上一次commit,并包括指定文件的新变化
分支操作
- git branch 查看本地所有分支
- git branch -r 查看远程所有分支
- git branch -a 查看本地和远程所有分支
- git merge <分支名> 合并分支
- git merge --abort 合并分支出现冲突时,取消合并,一切回到合并前的状态
- git branch <新分支名> 基于当前分支,新建一个分支
- git checkout --orphan <新分支名> 新建一个空分支(会保留之前分支的所有文件)
- git branch -D <分支名> 删除本地某个分支
- git push <远程库名> :<分支名> 删除远程某个分支
- git branch <新分支名称> <提交ID> 从提交历史恢复某个删掉的某个分支
- git branch -m <原分支名> <新分支名> 分支更名
- git checkout <分支名> 切换到本地某个分支
- git checkout <远程库名>/<分支名> 切换到线上某个分支
- git checkout -b <新分支名> 把基于当前分支新建分支,并切换为这个分支
远程同步
- git fetch [remote] 下载远程仓库的所有变动
- git remote -v 显示所有远程仓库
- git pull [remote] [branch] 拉取远程仓库的分支与本地当前分支合并
- git fetch 获取线上最新版信息记录,不合并
- git push [remote] [branch] 上传本地指定分支到远程仓库
- git push [remote] --force 强行推送当前分支到远程仓库,即使有冲突
- git push [remote] --all 推送所有分支到远程仓库
撤销
git checkout [file] 恢复暂存区的指定文件到工作区
git checkout [commit] [file] 恢复某个commit的指定文件到暂存区和工作区
git checkout . 恢复暂存区的所有文件到工作区
git reset [commit] 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
git reset --hard 重置暂存区与工作区,与上一次commit保持一致
git reset [file] 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
git revert [commit] 后者的所有变化都将被前者抵消,并且应用到当前分支
存储操作
你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作,但又不想提交这些杂乱的代码,这时候可以将代码进行存储
git stash 暂时将未提交的变化移除
git stash pop 取出储藏中最后存入的工作状态进行恢复,会删除储藏
git stash list 查看所有储藏中的工作
git stash apply <储藏的名称> 取出储藏中对应的工作状态进行恢复,不会删除储藏
git stash clear 清空所有储藏中的工作
git stash drop <储藏的名称> 删除对应的某个储藏
这个是git切换分支导致代码丢失找回链接,面试当然不问,但是在实际开发中会用到,为什么,因为我遇到了,当时慌啊
情景题
有一个按钮作用是点击上传文件,前端应该怎么做可以避免我如果点击多次就上传多次的
-
禁用按钮:在首次点击上传后,立即禁用上传按钮,直到上传完成或出现错误时再启用。这样可以防止用户连续点击触发多次上传。
-
显示上传状态:在上传过程中,可以显示一个上传状态的提示,告知用户当前正在进行上传操作。可以使用loading动画或进度条等方式显示上传进度,增加用户的等待感知。
-
阻止重复点击事件:在按钮点击事件触发后,立即取消后续的点击事件。可以通过在点击事件处理函数中添加一个标志位,来判断是否已经有一次上传操作正在进行,若有,则忽略后续的点击事件。
-
添加延迟效果:可以在点击事件触发后,增加一个短暂的延迟时间,在延迟结束前禁用按钮。这样可以确保只有第一次点击会触发上传操作,后续的点击会被忽略。
-
提示并阻止重复操作:在上传开始之前,可以弹出一个提示框告知用户已经有一个上传任务正在进行,请等待上传完成后再进行下一次操作。同时,可以阻止再次触发上传事件,或者给予相应的提示并阻止用户重复点击