目录
10、说说 像素点、px、em、rem、vh、vw 的联系区别?
18、项目富文本怎么封装,上传图片到哪里?什么格式?有多大?如何存储?
22、给你一个一维数组,如何转化成想要的 element-ui tree格式的数据?
24、什么是HTTP ? HTTP 和 HTTPS 的区别 ?
34、script、script async 和 script defer 的区别
39、浏览器输入url到页面渲染经历了什么步骤 ? 三次挥手 发生在什么步骤?
41、vuex是什么 如何使用? 项目只有一个store吗?
46、苹果手机 上面有** header 下面有个** ,移动端如何做到自适应呢?
47、v-show与v-if的区别,v-if 在哪个生命周期执行?
54、Flex 布局都有什么? flex-grow 解释下?
55、Sass less 有用到吗 ?reset css 什么作用?
1、函数式编程是什么简单说下?
- js 的函数式编程,是写js每个功能封装成函数相互调用
- vue 的函数式编程,每个组件都使用vue提供的h函数渲染模板而不是直接写标签
2、打包工具代码管理 git svn 了解多少?
Git和SVN都是代码管理工具,用于帮助开发团队管理和跟踪代码的版本控制。Git和SVN都是用于代码管理的工具,但Git是分布式版本控制系统,适用于多人并行开发和分布式环境;而SVN是集中式版本控制系统,适用于小团队协作开发。
Git具有以下功能和作用:
- 版本控制:Git可以跟踪每个文件的改变,并记录每个版本的变化,开发人员可以随时回退到之前的版本。
- 分支管理:Git允许开发人员在不同的分支上进行并行开发,每个分支都可以独立进行修改和提交。
- 协作和合并:多个开发人员可以同时在一个项目上进行开发,并使用Git合并各自的修改。
- 高效性能:Git具有高效的性能,可以快速处理大量的代码文件和版本。
- 分布式架构:Git的分布式架构使得开发人员可以在本地进行版本控制,而不需要依赖于网络连接。
SVN具有以下功能和作用:
- 版本控制:SVN可以跟踪每个文件的改变,并记录每个版本的变化,开发人员可以随时回退到之前的版本。
- 文件锁定:SVN可以对文件进行锁定,以确保同一时间只有一个人可以修改文件,避免冲突。
- 简单易用:SVN的命令简单易懂,适合不熟悉命令行的开发人员使用。
- 集中控制:SVN的代码仓库集中存储在一个中央服务器中,所有的修改都需要连接到服务器进行操作。
以下是一些常用的SVN和Git指令:
SVN指令:
- svn checkout URL:从远程仓库检出代码。
- svn add file:将文件添加到版本控制中。
- svn commit -m “message”:提交代码到版本控制仓库。
- svn update:更新本地代码到最新版本。
- svn log:查看提交日志。
- svn diff:查看修改的文件内容。
- svn revert file:撤销对文件的修改。
Git指令:
- git clone URL:从远程仓库克隆代码到本地。
- git add file:将文件添加到暂存区。
- git commit -m “message”:提交代码到本地仓库。
- git push:将本地代码推送到远程仓库。
- git pull:从远程仓库拉取最新代码到本地。
- git log:查看提交日志。
- git diff:查看修改的文件内容。
- git branch:查看分支列表。
- git checkout branch:切换到指定分支。
- git merge branch:将指定分支合并到当前分支。
3、什么是Webpack?它的主要功能是什么?
WebPack是一个现代JS应用程序的静态模块打包工具。Webpack的主要功能包括:
1. 模块打包:将项目中的所有模块(JavaScript、CSS、图片等)当作一个整体,通过依赖关系将它们打包成一个或多个静态资源文件。
2. 依赖管理:Webpack可以分析模块之间的依赖关系,根据配置的入口文件找出所有依赖的模块,并将其整合到打包结果中。
3. 文件转换:Webpack
本身只能处理JavaScript
模块,但通过加载器(Loader)
的使用,可以将其他类型的文件(如CSS、LESS、图片等)转换为有效的模块,使其能够被打包到最终的结果中。
4. 代码拆分:Webpack支持将代码拆分成多个模块,按需加载,实现按需加载和提升应用性能。
5. 插件系统:Webpack提供了丰富的插件系统,可以通过插件实现各种功能的扩展,例如压缩代码、自动生成HTML文件等。
4、Webpack的核心概念是什么?
- entry 入口 这是打包的入口文件,所有的脚本将从这个入口文件开始
- output 出口 打包后输出的文件,文件名跟入口的保持一致,但后面加上了hash的后缀让每次生成的文件名是唯一的。
- mode 模式 用于模块的源码的转换,
- plugins 插件 有一些loader无法实现的功能,就通过plugin去扩展,
- loader 转化器 mode一共有production,development,node三种,如果没有设置,会默认为production
webpack 详细请参考相关文章 👉 Webpack介绍大全_unwebpack-CSDN博客
5、如何获取到父节点dom 祖父节点呢?
首先要先了解这两个概念,parentNode:文本节点或文档节点; parentElement: 元素节点。
- var grandparentNode = parentNode ? parentNode.parentElement : null; // 获取祖父节点
- var grandparentNode = parentNode ? parentNode.parentNode : null; // 获取祖父节点
- (selector).parents(selector); // 获取祖先元素
- $(selector).parent(selector); // 获取父节点
- $(selector).parentNode; // 以node[]的形式存放父节点,如果没有父节点,则返回空数组
6、登录流程? 登陆时token 放在服务端还是客户端?
基于Token的认证(如JWT,JSON Web Tokens)
- 用户提交登录表单,包含用户名和密码。
- 服务器验证用户凭证,如果凭证正确,生成包含用户信息的Token(如使用JWT格式)。
- 服务器将Token返回给前端。
- 前端存储Token(通常在LocalStorage、SessionStorage或内存中)。
- 后续请求携带Token。
- 服务器校验Token,如果有效,处理请求并返回资源。
7、图片懒加载流程?图片懒加载几秒?
- 基本原理: 监听图片是否位于页面的可视区域内,若在则加载图片,不在则不加载图片
- 实现方案: 自定义属性-将图片真实地址 url 存储在自定义属性中,当监听到图片进入可视区 域 时,将自定义属性值赋值给 img 的 src 属性
- 具体方法: 可以用
image.offsetTop <= document.documentElement.clientHeight + document.documentElement.scrollTop
判断图片是否可以在可视区域内。
如果希望在图片出现在视口内之前有一定的延迟再加载(例如为了平滑滚动效果),可以在计算出图片出现在视口内后,使用setTimeout
函数来设置一个短暂的延迟(如500毫秒)
8、Vue权限管理怎么做的?
Vue权限管理主要涉及两个层面:界面权限控制和接口权限控制。
下面是一个基本的实现思路和步骤:
① 用户登录与权限获取
- 用户登录成功后,后端通常会返回一个包含用户角色和权限信息的token(如JWT)。
- 前端在接收到这个token后,应存储起来(如存入localStorage或cookie),并在后续的请求中携带此token以验证用户身份和权限。
② 路由权限控制
- 静态路由(constantRoutes):定义不需要权限即可访问的页面,如登录页、404页等。
- 动态路由(asyncRoutes):根据用户角色动态加载可访问的路由。在Vue中,可以在用户登录后,根据后端返回的权限信息,筛选出用户有权访问的路由,然后使用
router.addRoutes()
方法动态添加到路由表中。
③ 组件内的权限控制
- 可以通过自定义指令(Vue指令)或计算属性来控制组件内元素(如按钮、链接)的显示与否。例如,创建一个
v-has
指令,检查当前用户是否有权限访问某个功能。
Vue.directive('has', {
inserted(el, binding, vnode) {
const { value } = binding;
if (!value) return;
const permissions = vnode.context.$store.getters.permissions; // 假设权限存储在Vuex中
if (!permissions.includes(value)) {
el.parentNode && el.parentNode.removeChild(el);
}
}
});
在组件模板中使用:
<button v-has="'createUser'">创建用户</button>
④ 接口请求权限控制
- 在发起API请求时,前端应确保请求头中包含有效的token。
- 使用axios等HTTP客户端时,可以在请求拦截器中自动添加token。
- 后端会对每个接口请求进行权限校验,如果用户没有权限访问某个接口,后端会返回错误码,前端根据错误码处理(如提示无权限)。
⑤ Vuex管理权限状态
- 将用户的权限信息存储在Vuex的状态管理器中,方便全局访问和更新。
⑥ 动态菜单生成
- 根据用户权限动态生成侧边栏菜单或顶部导航。这通常在路由动态添加后,根据路由信息生成菜单项。
9、说说你对闭包的理解?闭包使用场景
闭包允许一个内部函数中访问到其外部函数的作用域,内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。闭包作为函数内部与外部连接起来的一座桥梁。
①三大特性:
- 函数嵌套函数
- 函数内部可以引用外部的参数及变量
- 参数和变量不会被垃圾回收机制回收
②应用场景:
1)防抖(Debounce)
防抖确保某函数在一定时间内只执行一次,如果在这段时间内又被调用,则重新开始计时。
function debounce(func, wait) {
let timeoutId; // 利用闭包存储timeout标识
return function(...args) {
if (timeoutId) {
clearTimeout(timeoutId); // 如果已有定时器,则清除重新开始
}
timeoutId = setTimeout(() => {
func.apply(this, args); // 使用apply确保func能访问调用debounce时的上下文和参数
}, wait);
};
}
// 使用防抖处理搜索输入
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
console.log("搜索关键词:", e.target.value);
// 这里执行实际的搜索逻辑
}, 300)); // 等待300毫秒后执行搜索
2)节流(Throttle)
节流确保某函数在一定时间间隔内只执行一次,无论期间被调用多少次。
function throttle(func, limit) {
let inThrottle; // 利用闭包存储是否在节流状态
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用节流处理滚动事件
window.addEventListener('scroll', throttle(function() {
console.log("滚动事件处理...");
// 这里执行实际的滚动处理逻辑
}, 200)); // 每200毫秒最多执行一次
10、说说 像素点、px、em、rem、vh、vw 的联系区别?
像素点(Pixel):
- 像素点是数字影像中的最小单位,代表着一个具有固定位置和特定色彩或亮度值的图像单元。
- 在显示器、数码相机、摄像机等设备中,像素点数量越多,能够表示的细节就越精细。
- 像素(px)是相对于显示器屏幕分辨率而言的,是web开发中最常用的像素单位。
px(像素):
- 像素(px)是CSS中用于设置元素尺寸或位置的基本单位之一。
- 它是相对于显示器屏幕分辨率而言的,与设备的物理像素相对应。
- 在不同的设备上,由于屏幕分辨率的不同,相同的像素值可能会呈现出不同的视觉效果。
em:
- em是相对长度单位,参照物是父元素的font-size字体大小。
- 当使用em的时候,em转为像素的大小取决于它们使用的字体大小。这个字体大小受从父元素继承过来的字体大小影响,除非显式重写与一个具体单位。
- em具有继承的特点,如果元素自身定义了font-size属性,那么就会按照自身来计算;如果都没有设置,就会按照当前所有浏览器或者设备的默认文字大小来计算调整。
rem:
- rem是CSS3新增的一个相对单位,它是相对于HTML根元素的字体大小(font-size)来计算的长度单位。
- 如果没有设置HTML的字体大小,就会以浏览器默认字体大小(一般是16px)来计算。
- rem可以实现响应式布局,因为当HTML根元素的字体大小改变时,所有使用rem单位的元素尺寸都会相应地改变。
vh和vw:
- vh和vw是CSS3中推出的新单位。
- vh是视窗高度(viewpoint height)的缩写,1vh等于视窗高度的1%。
- vw是视窗宽度(viewpoint width)的缩写,1vw等于视窗宽度的1%。
- 这些单位使得元素尺寸可以相对于视窗的大小进行调整,从而实现响应式布局。
11、如何实现父子组件通讯?
- 父->子
props
,子->父$on、$emit
- 获取父子组件实例
$parent、$children
Ref
获取实例的方式调用组件的属性或者方法Provide、inject
官方不推荐使用,但是写组件库时很常用- 父子关系的组件数据传递选择
props
与$emit
进行传递,也可选择ref
12、vue 有哪些通讯方式?
- 父子关系的组件数据传递选择
props
与$emit
进行传递,也可选择ref
- 兄弟关系的组件数据传递可选择
$bus
,其次可以选择$parent
进行传递 - 祖先与后代组件数据传递可选择
attrs
与listeners
或者Provide
与Inject
- 复杂关系的组件数据传递可以通过
vuex
存放共享的变量
13、Vue中Key 是什么作用?
diff算法依赖key值,来判断该节点是否需要更新。key值推荐使用后端返回来的唯一id。
14、首屏加载如何优化?项目优化目前几秒 优化到几秒?
常见的几种SPA首屏优化方式
- 减小入口文件积
- 静态资源本地缓存
- UI框架按需加载
- 图片资源的压缩
- 组件重复打包
- 开启GZip压缩
- 使用SS
15、防抖节流 一般频率是几秒?
防抖(Debounce)
防抖确保某函数在一定时间内只执行一次,如果在这段时间内又被调用,则重新开始计时。
function debounce(func, wait) {
let timeoutId; // 利用闭包存储timeout标识
return function(...args) {
if (timeoutId) {
clearTimeout(timeoutId); // 如果已有定时器,则清除重新开始
}
timeoutId = setTimeout(() => {
func.apply(this, args); // 使用apply确保func能访问调用debounce时的上下文和参数
}, wait);
};
}
// 使用防抖处理搜索输入
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {
console.log("搜索关键词:", e.target.value);
// 这里执行实际的搜索逻辑
}, 300)); // 等待300毫秒后执行搜索
节流(Throttle)
节流确保某函数在一定时间间隔内只执行一次,无论期间被调用多少次。
function throttle(func, limit) {
let inThrottle; // 利用闭包存储是否在节流状态
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用节流处理滚动事件
window.addEventListener('scroll', throttle(function() {
console.log("滚动事件处理...");
// 这里执行实际的滚动处理逻辑
}, 200)); // 每200毫秒最多执行一次
16、简单说下单点登录流程 和 基本原理?
特点:用户在SSO系统登录一次后,可以访问所有集成了SSO的应用,无需重复登录
- 用户首次尝试访问应用时被重定向到SSO服务器进行认证。
- 用户提供凭证并登录到SSO服务器。
- SSO服务器返回一个认证令牌 给应用。
- 应用使用该票据向SSO服务器确认用户身份。
- 确认成功后,用户可在不同的应用间自由切换而无需重新认证。
17、nginx 有何作用? 不使用它,如何解决?
- Nginx 是一个高性能的 HTTP 和反向代理服务器,它常用来作为负载均衡、反向代理、静态文件服务器等。
- Nginx 的作用主要是:负载均衡、反向代理、静态文件服务器等。
18、项目富文本怎么封装,上传图片到哪里?什么格式?有多大?如何存储?
安装
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --saveyarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save
可通过 toolbarConfig
和 editorConfig
来修改菜单栏和编辑器的配置,
详细文档参考 👉用于 Vue React | wangEditor
- 工具栏配置 - 插入新菜单,屏蔽某个菜单等
- 编辑器配置 - 兼听各个生命周期,自定义粘贴
- 菜单配置 - 配置颜色、字体、字号、链接校验、上传图片、视频等
-
当编辑器渲染完成之后,通过
editorRef.value
获取 editor 实例,即可调用它的 API
19、怎么封装一个组件?
- 创建组件模板
- 定义组件逻辑
- 添加样式(可选)
- 使用组件
20、后端数据存放在哪里?图片放在那里,如何存放?
前端通过后端上传接口,将上传的 file 文件对象以表单形式,传递给后端,后端会将传递的图片文件放在服务器的特定目录文件夹下,上传接口返回得到具体路径。然后提交调用提交接口表单。
21、ES6新特性有哪些
- let 和 const: 引入了新的变量声明关键字
let
和const
,提供了块级作用域的变量声明 - 箭头函数: 提供了一种更简洁的函数表达方式
- 模板字符串: 使用反引号(``)包围的多行字符串,支持字符串插值
- 解构赋值: 允许从数组或对象中快速提取值到变量中,简化了数据处理。
- 展开运算符: 用三个点(
...
)表示,用来展开数组或对象的属性,用于合并数组或复制对象。 - 模块(Module): 引入了模块系统,使用
import
和export
语句管理代码的导入和导出,提高了代码的组织和重用性。 - Promise: 用于处理异步操作,提供了一种更优雅的链式调用方式来处理异步操作的结果,替代了传统的回调地狱。
- async/await: 异步编程的新语法糖,使得异步代码看起来像同步代码,基于Promise,但更易于理解和编写。
22、给你一个一维数组,如何转化成想要的 element-ui tree格式的数据?
①定义一维数组:包含每个元素的 ID、名称以及可能的父级 ID。
②创建一个空的树形结构数组:这将是你将要填充的最终结果。
③遍历一维数组:对于每个元素,检查它是否有父级 ID。
1).如果没有父级 ID(可能是根节点),则直接添加到树形结构数组中。
2).如果有父级 ID,则首先找到或创建对应的父节点,然后将当前元素作为子节点添加 到父节点的 children
数组中。
④ 返回树形结构数组:这将是你为 el-tree
准备的最终数据。
23、v-model 双向绑定原理?具体场景?
v-model 双向绑定原理:
- 数据层(Model):应用的数据及业务逻辑
- 视图层(View):应用的展示效果,各类UI组件
- 业务逻辑层(ViewModel):框架封装的核心,它负责将数据与视图关联起来
MVVM
这里的控制层的核心功能便是 “数据双向绑定”
Vue
中的双向绑定流程:
new Vue()
首先执行初始化,对data
执行响应化处理,这个过程发生Observe
中- 同时对模板执行编译,找到其中动态绑定的数据,从
data
中获取并初始化视图,这个过程发生在Compile
中 - 同时定义⼀个更新函数和
Watcher
,将来对应数据变化时Watcher
会调用更新函数 - 由于
data
的某个key
在⼀个视图中可能出现多次,所以每个key
都需要⼀个管家Dep
来管理多个Watcher
- 将来data中数据⼀旦发生变化,会首先找到对应的
Dep
,通知所有Watcher
执行更新函数
双向绑定应用场景:
文本输入:最常见的场景是在文本输入框(<input type="text">
)中,用户输入的内容会实时同步到Vue实例的数据属性上,同时,如果数据属性值在外部改变,输入框的内容也会自动更新。
24、什么是HTTP ? HTTP 和 HTTPS 的区别 ?
HTTP
(HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范。- 为了保证这些隐私数据能加密传输,让
HTTP
运行安全的SSL/TLS
协议上,即 HTTPS = HTTP + SSL/TLS,通过SSL
证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密
HTTP 和 HTTPS 的区别:
- HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TLS协议进行了加密处理,相对更安全
- HTTP 和 HTTPS 使用连接方式不同,默认端口也不一样,HTTP是80,HTTPS是443
- HTTPS 由于需要设计加密以及多次握手,性能方面不如 HTTP
25、箭头函数有什么特点?
- 函数没有自己的
this
对象,就是定义时所在的对象,箭头函数的this指向外层作用域的this - 不可以当作构造函数,也就是说,不可以使用
new
命令,否则会抛出一个错误 - 不可以使用
arguments
对象,该对象在函数体内不存在。如果要用,可以用rest
参数代替 - 不可以使用
yield
命令,因此箭头函数不能用作 Generator 函数
26、vue生命周期有哪些?每个生命周期做了什么?
- beforeCreate :刚开始创建实例化。
- created:创建实例化完成。
- beforeMount:真实dom挂载之前,虚拟dom创建完成,即将开始渲染。
- mounted:真实dom挂载已完成,双向数据绑定,并且DOM已经渲染完成。(此时可以使用$refs属性对Dom进行操作,即vue2版本 ,此时可以操作this)
- beforeUpdate:响应式数据更新,但是DOM还未更新。(dom更新之前)
- updated:数据发生变化,并且DOM已经更新。
- beforeDestroy:组件实例被销毁之前。(实例即将被销毁)
- destroyed:组件实例已被销毁。
27、你的接口一般放在哪个生命周期中?为什么这样做?
①在Vue等前端框架中,接口请求通常放在created
或mounted
生命周期钩子中。
created
钩子:在这个阶段,Vue实例已经创建完成,数据观测和事件配置已经完成。此时可以进行一些不需要DOM元素参与的接口请求。mounted
钩子:在这个阶段,Vue实例已经被挂载到了DOM上,可以访问到DOM。- 如果在
mounted
钩子函数中请求数据可能导致页面闪屏问题,加个loading,即可解决。
②为什么这样做?
- 用户体验: 放在
created
或mounted
中可以确保数据在组件初次渲染时就已经准备就绪,或尽快准备就绪,从而提升用户体验,避免白屏时间过长。 - 逻辑清晰: 将数据获取逻辑集中在生命周期钩子中,可以让组件的初始化逻辑更加集中和易于理解。
- 资源管理: 在合适的生命周期中调用接口可以更好地管理资源和优化性能,例如在数据真正需要时才发起请求,避免不必要的网络消耗。
总的来说,选择哪个生命周期钩子主要取决于你的具体需求,是否需要立即获取数据,以及是否依赖于DOM操作。
28、JSON 与 JSONP 的区别
- JSON 则是一种轻量级的数据交换格式,也是JavaScript对象。
- JSONP 实现跨域数据获取的技术,只支持get方式。
- JSON是一种数据交换格式,也是一种js对象;JSONP是跨域访问的技巧,二者没什么关系。
29、CSS 隐藏元素的几种方法(至少说出三种)
- opacity: 0; ---- 设置透明度来隐藏元素,隐藏对应的元素会占页面空间。
- isibility:hidden; ---- 隐藏对应的元素会占页面空间。
- display:none; ---- 隐藏对应的元素不会占页面空间。
- position:absolute; top:-9999px; ---- 让该元素脱离文档流移出视觉区域。
- height: 0; width: 0; ---- 将元素的尺寸缩小到0,但这种方法对于具有固定宽高的元素更有效。
- transform: scale(0); ---- 通过缩放将元素缩小到看不见,同样可以保持元素在布局中的位置。
30、请描述一下var、const、let三者的区别
- var可以变量提升,const、let不会提升
- var没有块级作用域,const、let存在块级作用域
- var可以重复定义变量,const、let不能重复定义,是常量
- 我个人目前实际编程中应用优先级:const > let > var
31、cookie、sessionStorage、localStorage的区别
①存储大小
- cookie:一般不超过4k
- sessionStorage:5M甚至更多
- localStorage:5M甚至更多
②数据有效期
- cookie:一般由服务器生成,可以设置失效时间;若没有设置时间,关闭浏览器cookie失效,如果设置了时间,cookie就会存储在硬盘中,过期失效
- sessionStorage:仅在当前浏览器窗口关闭之前有效,关闭页面或者浏览器会被清除
- localStorage:永久有效,窗口或者浏览器关闭也会一直保存,除非手动永久删除
③通信
- cookie:cookie在浏览器和服务器之间来回传递,如果使用cookie保存过多数据会造成性能问题
- sessionStorage:仅在客户端(浏览器)中保存,不参与服务器的通信
- localStorage:仅在客户端(浏览器)中保存,不参与服务器的通信
④ 作用域
- cookie:在所有同源窗口中都是共享的
- sessionStorage:在同一个浏览器窗口是共享的(不同浏览器,即使是统一页面也不共享)
- localStorage:在所有同源窗口中共享
⑤应用场景
- cookie:判断用户是否登录过网站,以便实现下次自动登录或记住密码;保存事件信息
- sessionStorage:敏感账号一次性登录,单页面用的较多
- localStorage:用于长期登录,适于长期保存在本地的数据
32、Vue 组件中 data 为什么必须是函数
- 保证组件实例间数据的独立性。
- 当Vue创建组件实例时,如果
data
是一个对象,那么所有实例将共享这个对象的引用,导致一个实例改变数据会影响到其他实例。 - 而如果是函数,每个实例化过程都会调用这个函数,返回一个全新的数据对象,这样每个组件实例都有自己的独立作用域和数据副本,避免了数据交叉污染。
33、如何水平垂直居中一个盒子?
- 知高度,父line-height 等于高度一半(垂直居中); text-align:center(水平居中);
- 父display:flex; align-items:center;justify-content:center;
- 父position: relative; 子 position: absolute; top:0;left:0;right:0;bottom:0;margin:auto;
- 子绝父相 ,子 top: 50%; left: 50%;transform: translate(-50%, -50%);
34、script、script async 和 script defer 的区别
<script>
- 当浏览器遇到这样的脚本标签时,它会立即停止解析HTML文档,去加载并执行这个脚本。
- 这个过程会阻塞文档的解析和渲染,直到脚本执行完毕。
- 所有
<script>
标签默认都按照它们在文档中出现的顺序执行。
<script async>
- 异步加载脚本,意味着脚本的加载不会阻塞文档的解析,可以与其他资源并行加载。
- 脚本的下载不会暂停HTML的解析,但是脚本的执行仍然会阻塞文档的渲染。
- 当脚本下载完毕后,会立即执行,不保证执行顺序,即使它们在文档中的顺序有先后。
<script defer>
- 同样允许脚本异步加载,不阻塞文档解析。
- 与
async
不同,所有带有defer
属性的脚本会保证按照它们在文档中的顺序进行执行,这发生在HTML解析完成之后,DOMContentLoaded事件触发之前。 - 适合那些需要在文档解析完成后,但在DOMContentLoaded事件触发前执行的脚本,例如那些可能修改DOM的脚本,但又不必阻塞页面渲染的场景。
总结:
async
主要用于那些不影响页面初次渲染且不依赖于文档顺序的脚本。defer
则适用于需要维持脚本执行顺序,同时又不想阻塞渲染的脚本。- 没有指定这两个属性的
<script>
则会按照传统方式阻塞文档的解析和渲染。
35、new一个对象的时候发生了什么?
new操作符的执行过程:
(1)首先创建了一个新的空对象
(2)设置原型,将对象的原型设置为函数的 prototype 对象。
(3)让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)
(4)判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
具体实现:
function objectFactory() {
let newObject = null;
let constructor = Array.prototype.shift.call(arguments);
let result = null;
// 判断参数是否是一个函数
if (typeof constructor !== "function") {
console.error("type error");
return;
}
// 新建一个空对象,对象的原型为构造函数的 prototype 对象
newObject = Object.create(constructor.prototype);
// 将 this 指向新建对象,并执行函数
result = constructor.apply(newObject, arguments);
// 判断返回对象
let flag = result && (typeof result === "object" || typeof result === "function");
// 判断返回结果
return flag ? result : newObject;
}
// 使用方法
objectFactory(构造函数, 初始化参数);
36、HTTP的状态码有哪些?并代表什么意思?
HTTP状态码是由三位数字组成的代码,用于表示客户端向服务器发起请求后,服务器对请求的响应状态。状态码可以大致分为五类,包括信息性状态码、成功状态码、重定向状态码、客户端错误状态码和服务器错误状态码。
常见的HTTP状态码:
1xx(信息性状态码):
- 100 :客户端应继续其请求。
2xx(成功状态码):
- 200 :请求成功。
- 201 :请求已经被实现,并因此创建了一个新的资源。
- 204 :服务器成功处理了请求,但没有返回任何内容。
3xx(重定向状态码):
- 301:请求的资源已被永久移动到新的URL上。
- 302 :请求的资源现在临时从不同的URL响应请求。
- 304 :客户端已经执行了GET请求,但文件未发生变化。
4xx(客户端错误状态码):
- 400 :服务器无法理解请求。
- 401 :请求要求进行身份验证。
- 403 :服务器理解请求,但拒绝执行它。
- 404:服务器无法找到请求的资源。
- 405 :请求中指定的方法不被允许。
5xx(服务器错误状态码):
- 500 :服务器遇到了一个未曾预料的情况,导致其无法完成对请求的处理。
- 501:服务器不支持当前请求所需要的某个功能。
- 503 :由于临时的服务器维护或者过载,服务器当前无法处理请求。
37、vue2、vue3的区别
1)响应式系统的改变
Vue 2 使用 Object.defineProperty
来实现数据的响应式
Vue 3 引入了 Proxy
,它能够代理整个对象,从而实现了更全面的响应式,属性的添加、删除等。
2)API结构的变化
Vue 2 主要依赖于选项API,其中数据、计算属性、方法等被组织在不同的选项中。
Vue 3 引入了组合API,通过 setup() 函数集中管理组件的状态和行为,使代码更模块化。
3)生命周期钩子的变化
vue3生命周期
- onBeforeMount()
- onMounted()
- onBeforeUpdate()
- onUpdated()
- onBeforeUnmount()
- onUnmounted()
4)v-if和v-for的优先级
- Vue 2 中 v-for的优先级高于v-if。
- Vue 3 中 v-if的优先级高于v-for。
详见 👉 https://blog.csdn.net/qq_53895518/article/details/137227292
38、webpack打包做了什么 ?
- 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
- 编译:从 entry 出发,针对每个 Module 串行调用对应的 loader 去翻译文件的内容,再找到该 Module 依赖的 Module,递归地进行编译处理
- 输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中
详见 👉 对webpack的理解?
39、浏览器输入url到页面渲染经历了什么步骤 ? 三次挥手 发生在什么步骤?
- URL 解析
- DNS 域名解析
- 建立 TCP 连接
- 发送 HTTP 请求
- 服务器对请求进行处理并做出响应
- 浏览器解析渲染页面
- 断开 TCP 连接
详见 👉 这一次彻底弄懂,在浏览器输入URL,按下回车之后发生了什么?
40、Axios是什么? 写在项目什么文件夹下?
- 路径 src /api / request.js
import { service } from './service'
function createRequest(service) {
function request(config) {
// config 自定义配置
// axios默认配置
const configDefault = {
baseURL: import.meta.env.VITE_APP_API_BASEURL, // 所有通过此配置的基础地址 在.env文件配置
timeout: 15000, // 请求超时时间
responseType: 'json', // 响应类型
headers: {
// 请求头配置...
}
}
const requestConfig = Object.assign(configDefault, config)
return service(requestConfig)
}
return request
}
export const request = createRequest(service)
41、vuex是什么 如何使用? 项目只有一个store吗?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
这个状态自管理应用包含以下几个部分:
- 状态,驱动应用的数据源;
- 视图,以声明方式将状态映射到视图;
- 操作,响应在视图上的用户输入导致的状态变化。
“单向数据流”理念的简单示意:
42、 跨域是什么?几种方式解决?
- 跨域本质是浏览器基于同源策略的一种安全手段。
- 同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能。
- 反之非同源请求,也就是协议、端口、主机其中一项不相同的时候,这时候就会产生跨域。
所谓同源(即指在同一个域)具有以下三个相同点
- 协议相同(protocol)
- 主机相同(host)
- 端口相同(port)
43、Sass less 预处理有何作用?
- 嵌套:反映层级和约束
- 变量和计算:减少重复代码
- Extend和Mixin:代码片段复用
- 循环:适用于复杂有规律的样式
- import:CSS文件模块化
44、vue $Bus 事件总线 怎么实现传值呢?
- 首先eventBus通过各种技术手段实现的一种功能 既不是vue的也不是js原生的,如果是vue实现 那eventBus是一个vue根实例 可以通过根$emit $on 实现通信
45、ES6模块和CommonJS规范 的区别?
1)加载机制
ES6模块(ESM):
- 静态加载(编译时加载):ESM的导入(
import
)和导出(export
)在编译阶段完成解析,这意味着模块的依赖关系在运行之前就已经确定。这允许打包工具优化加载顺序和代码分割,提高性能。 - 异步加载:在浏览器环境中,ESM默认采用异步加载方式,避免了阻塞页面渲染,提高了用户体验。
CommonJS(主要在Node.js中使用):
- 动态加载(运行时加载):CommonJS模块在代码运行时加载,使用
require()
函数来加载模块,这时模块的代码才会被执行。这导致模块加载顺序和执行顺序成为运行时的行为。 - 同步加载:CommonJS模块加载是同步的,意味着在加载一个模块时,所有依赖必须等待这个模块加载完毕,这在服务器端不是问题,但在浏览器端可能导致性能瓶颈。
2)语法
ES6模块使用import
语句来导入模块,使用export
(可以是默认导出export default
或命名导出export const/var/function...
)来导出模块内容。
// 导出
export const myFunction = () => { /* ... */ };
export default MyClass;
// 导入
import MyClass from './MyClass.js';
import { myFunction } from './myModule.js';
CommonJS使用require()
来导入模块,使用module.exports
或exports
来导出模块内容。
// 导出
exports.myFunction = function() { /* ... */ };
module.exports = MyClass;
// 导入
const myModule = require('./myModule');
const MyClass = require('./MyClass');
46、苹果手机 上面有** header 下面有个** ,移动端如何做到自适应呢?
- iphone X刘海屏的安全区域头部有44px,底部有34px 可以使用媒体查询判断横屏还是竖屏
- 移动端可以通过rem 第三方库lib-flexible、px-to-viewport 来进行适配
47、v-show与v-if的区别,v-if 在哪个生命周期执行?
- 两者都是用于控制元素的显示隐藏 v-show 修改css的display属性;v-if则是销毁和创建dom。
- v-if是在beforeCreate 和created 以及 beforeDestroy和desroyed 生命周期执行的。
48、请你说下什么是数据持久化?
可以使用客户端存储sessionStorage和localStorage存储实现。详见👇
前端开发攻略---解决Vue中仓库持久化的问题,不借助插件用原生JS实现仓库持久化。
49、上拉刷新 下拉加载
可以使用相关插件实现 比如mescroll.js(http://www.mescroll.com/index.html、better-scroll(https://better-scroll.github.io/docs/zh-CN/)等。详见 👉 如何实现 上拉加载 下拉刷新
50、菜单、按钮 权限 如何实现 ?
- 在项目中菜单数据是通过后台接口获取的 返回的数据根据不同用户权限来决定的
- 自定义权限指令判断哪些用户不能看某个按钮直接删除dom
51、简单说下前端路由守卫?
- 用于在路由跳转前后的拦截操作 在vue项目中可以使用全局守卫beforeEach和afterEach 独享守卫beforeEnter在某个路由对象里面配置
- beforeRouteEnter和beforeRouteUpdate beforeRouteLeave 组件守卫 在进入组件前和复用当前组件前 以及离开后调用
- 使用场景 可在router.js文件中配置全局路由 判断当前页面是否需要登录后访问
52、axios封装
- 在项目的src目录中 新建一个api文件夹,然后在里面新建一个request.js和一个service.js文件 以及每个模块的api文件
- request.js文件用来封装我们的axios service.js用来定制拦截器
53、移动端 给你从0到1 搭建流程是什么?要考虑什么?
首先考虑技术栈vue vite构建项目 移动端适配方案 rem等, 观察ui设计图、确定布局、封装相同组件,然后进行开发;要考虑与后端的交流必须保持同步进行
54、Flex 布局都有什么? flex-grow 解释下?
有flex-direction justify-content align-items flex-wrap flex-flow flex-grow flex-shrink flex-basis等
扩展下👇
- flex是弹性布局里面的3个项目属性的缩写:flex:1等价于flex-grow:1;flex-shrink:1;flex-basis:auto
- flex-grow:默认为0,意思是当有剩余空间时,该flex元素也不扩大
- flex-shrink: 默认为1,意思是当内存空间不够时,该flex元素将缩小
- flex-basis:默认为auto,意思是在分配多余的内存空间时,该flex项目的大小,默认是该项目原本体积大小
55、Sass less 有用到吗 ?reset css 什么作用?
- 有的 ,sass less都是css的预处理器 可以赋予css更多的功能 比如变量 嵌套 循环 函数等功能
- reset css用于清除浏览器页面css的默认样式可自己定制
56、数组数据类型?怎么判断数据类型?
可以使用typeof instanceof Object.prototype.toString.call() 等方式判断
57、数组去重简单说下?
set就是es6版本才有的一种数据结构 利用这种结构本身的唯一性处理
let array = [1, 2, 3, 4, 9, 7, 2, 4, 8, 1];
let uniqueArray = [...new Set(array)];
58、watch computed 区别
首先这两个都可以起到监听数据的变化, watch支持异步操作,还有较为复杂的逻辑,在乎过程。而computed用于计算处理,具有缓存功能,重视结果。
59、怎么写组件才能达到复用的效果?
尽可能封装 简洁 不写接口
使用props接收外部传入的数据 利用插槽使内容自定义 使用emit与外部保持通信 把样式进行scoped隔离
60、diff算法
通过新旧虚拟dom作对比(即diff)将变化的地方更新在真实dom上
61、key 值特点
为了更高效的更新虚拟dom
62、vue2 vue3 的响应式分别是 具体说下?
- vue2用Object.defineProperty()对数据进行劫持,利用发布订阅模式,数据变化时发布消息给订阅者,订阅者收到消息后更新视图
- vue3用Proxy对数据进行劫持,利用es6的reflect反射机制修改状态,数据变化时发布消息给订阅者,订阅者收到消息后更新视图 ,弥补了对象在vue2中的不足 ,就是新增属性和删除会丢失响应式
63、原型与原型链?
- 每一个函数都有个prototype属性 属性值就是原型对象
- 每个对象都有个__proto__属性指向的也是原型对象 而原型对象也是个对象也有一个__proto__ 它指向的是继承上一级的原型对象 这样就形成了一个链式结构 叫做原型链
64、简单说下promise
就是处理异步的一种方式 promise在执行的过程中有三种状态
- pending
- fulfilled
- rejected
这三种状态只会有两种结果 从padding到fulfilled或者到rejected,当执行时 如果里面new Promise里面的异步代码时间长的话就一直是pending状态,然后异步结束 只会出现两种结果 一种是成功(fulfilled)
Peomise是个构造函数 需要使用new创建下才能使用里面的方法比如 then() 、catch()
静态方法: Promise.all([ ])
用Promsie点的直接调用的都是promise的静态方法
何为静态方法 —— 就是不用创建对象 能直接这样调用的都是静态方法
65、箭头函数与普通函数的区别
- 写法不同,箭头函数没this依赖上层作用域this ,普通函数有this
- 箭头函数没有arguments对象 ,普通函数有
66、改变 this 指向的方法
- call()自动调用函数,参数以逗号分割传递
- apply()自动调用函数,参数以数组形式传递
- bind()不自动调用函数
67、组件传值
- 使用props父传子
- 用emit子传父
- vuex全局共享
- event Bus 跨组件传值
- provide/inject 深层及传值
- $ref $parent $children等
68、vuex 管理简单说下
- vuex是vue的状态管理工具,有五大核心
- state 存储状态 mutations 同步修改状态 ,actions 异步修改状态 getters 状态中的计算属性 modules 模块化处理
69、防抖节流
- 防抖就是在事件被触发n秒后再执行回调 如果在这n秒内又被触发 则重新计时
- 节流就是每隔一段时间 只执行一次函数
70、什么是闭包
函数嵌套 内部函数访问外部函数中的变量就是闭包 , 场景有定时器传参
function f1(a) {
function f2() {
console.log(a);
}
return f2;
}
var fun = f1(1);
setTimeout(fun,1000);
71、es6新特性有哪些?
- let const
- 箭头函数
- 模板字符串
- 展开运算符
- 模块化import/export
- 类
- promise
- async/await
- Map/Set数据结构
- Proxy/Reflect
- Symbol
- 数组字符串方法的扩展
72、express 是什么? 框架 渲染?
express 是一个基于nodejs的服务端web框架 可以快速搭建web应用 express框架的渲染是ejs模板引擎渲染html页面