文章目录
- 最常见问题
- javascript篇
-
- Javascript的运行机制
- javascript的数据类型
- 怎样判断变量的类型
- 数据类型转换
- 闭包的优缺点
- [v-if和v-for哪个优先级更高? 如果两个同时出现,应该怎么优化得到更好的性能?](#v-if和v-for哪个优先级更高? 如果两个同时出现,应该怎么优化得到更好的性能?)
- HTML5的新特性和CSS3的新特性
- [div 上下居中对齐的几种方式](#div 上下居中对齐的几种方式)
- js中操作数组的方法
- 伪类和伪元素的区别
- [css 选择器的优先级排序](#css 选择器的优先级排序)
- 深拷贝与浅拷贝
- HTTPS的工作流程,,HTTPS证书的验证
- JSONP原理
-
- [.....数组快速去重 数组扁平化](#.....数组快速去重 数组扁平化)
- [Cookie(4kb)、 storage (5MB) localStorage(5MB)](#Cookie(4kb)、 storage (5MB) localStorage(5MB))
- [什么是CSS盒模型 >>> -IE盒模型和W3C盒模型](#什么是CSS盒模型 >>> -IE盒模型和W3C盒模型)
- 实现继承的几种方式
- 浏览器垃圾回收
- [js重复的问题 作用域链、原型、原型链、闭包? 面相对象 继承](#js重复的问题 作用域链、原型、原型链、闭包? 面相对象 继承)
- 如何处理不让别人盗用你的图片,访问你的服务器资源?
- 如何优化网站性能
- [DOM 事件流和事件委托](#DOM 事件流和事件委托)
- 操作数组和对象的常见方法
- new内部做了什么
- [防抖、节流 , 函数节流的应用场景](#防抖、节流 , 函数节流的应用场景)
- this指向
- [let const var 的区别](#let const var 的区别)
- 浏览器与服务器的交互原理
- [ES5 与 ES6新特性](#ES5 与 ES6新特性)
- 说一下对promiss的理解
- vue面试题
-
-
- 对于MVVM的理解?
- vue中的跨域问题
- vue深度监听(watch)
- [vue 怎么缓存 keep-alive](#vue 怎么缓存 keep-alive)
- vue原理
- [你知道vue中的key 和工作原理么?说说你对它的理解](#你知道vue中的key 和工作原理么?说说你对它的理解)
- [你怎么理解vue中的 diff 算法?](#你怎么理解vue中的 diff 算法?)
- [对keep-alive 的了解?](#对keep-alive 的了解?)
- `route\`和\`router`的区别
- vue.js的两个核心是什么?
- vue几种常用的指令
- vue常用的修饰符?
- [v-on 可以绑定多个方法吗?](#v-on 可以绑定多个方法吗?)
- [vue中key 值的作用](#vue中key 值的作用)
- [nextTick的使用](#nextTick的使用)
- 父组件调用子组件方法
- 项目初始化页面闪动问题
- Vue3
-
- Vue3带来了什么
- ref与reactive
- [vue3中使用vue-router,useRoute和useRouter ?](#vue3中使用vue-router,useRoute和useRouter ?)
- vue3中废弃了过滤器
- vue2
-
- Vue2的生命周期
- 什么是vue2生命周期?
- vue生命周期总共有几个阶段?
- 第一次页面加载会触发哪几个钩子?
- [DOM 渲染在 哪个周期中就已经完成?](#DOM 渲染在 哪个周期中就已经完成?)
- Vue实现数据双向绑定的原理:Object.defineProperty()
- [Vue组件间的参数传递 和父子组件方法调用](#Vue组件间的参数传递 和父子组件方法调用)
- [Vue的路由实现:hash模式 和 history模式](#Vue的路由实现:hash模式 和 history模式)
- vue路由的钩子函数 (路由守卫)
- Vue-router的跳转原理:
- vuex是什么?怎么使用?哪种功能场景使用它?
-
- 前端面试算法题汇总(持续更新...)
-
-
- [**1. 算出字符串中出现次数最多的字符**](#1. 算出字符串中出现次数最多的字符)
-
- Git使用
- [webpack 常见面试题](#webpack 常见面试题)
-
-
- [1 什么是 webpack ?打包原理?](#1 什么是 webpack ?打包原理?)
- 2核心概念
- webpack与grunt、gulp的不同?
- webpack有哪些优点
- webpack的缺点
- 如何利用webpack来优化前端性能?
- 如何提高webpack的构建速度?
- [什么 是模块热更新?](#什么 是模块热更新?)
-
- vite面试题
-
- [什么是vite ?它解决了什么问题 ? Vite的工作原理是什么?](#什么是vite ?它解决了什么问题 ? Vite的工作原理是什么?)
- vite.config.js文件是做什么用的?
- Vite与Webpack相比有何不同?
- [vue3.0 生命周期](#vue3.0 生命周期)
- [vue2 与vue3 的区别](#vue2 与vue3 的区别)
- react面试题
-
- React有什么特点
- 什么是虚拟DOM?
- [React 中 key 的重要性是什么?](#React 中 key 的重要性是什么?)
- 类组件和函数组件之间的区别是什么?
- [React 生命周期](#React 生命周期)
- react生命周期方法有哪些?
- react中refs是什么?
- state和props区别是什么?
- 如何创建refs?
- 什么是jsx?
- 为什么不直接更新state?
- 什么是高阶组件?
- 受控组件和非受控组件区别是啥?
- [什么是 React Context?](#什么是 React Context?)
- [React 性能优化](#React 性能优化)
- tsx转换成真实DOM过程
- [使用 React Hooks 好处是啥?](#使用 React Hooks 好处是啥?)
- [什么是Redux?列出 Redux 的组件?](#什么是Redux?列出 Redux 的组件?)
- [Redux 有哪些优点?](#Redux 有哪些优点?)
- 常用的hooks?
- 后续。。。待补充
最常见问题
javascript篇
Javascript的运行机制
是 单线程的 重上到下 按顺序执行
代码运行的两个阶段:
1、预解析---把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前
2、执行---从上到下执行(按照js运行机制)
javascript的数据类型
Boolean null String Number Object Undefined
常见的基本数据类型
:Number、String 、Boolean、Null和Undefined。基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值
引用类型
比如:Object 、Array 、Function 、Data等。
怎样判断变量的类型
typeof
能够区分除数组和对象和null外的所有类型 [] {} null 都返回objectinstanceof 及原理
object.toString().call()
数据类型转换
= ==相等 ===全等 强制转换和 隐式转换
闭包的优缺点
A 这里b函数访问了构造函数a里面的变量,所以形成了一个闭包
bash
function a(){
var n =0;
function b(){
n++;
console.log(n);
}
B 因为我们想要持续的使用一个变量,放在全局中会造成全局污染,放在函数中,函数执行完后会销毁,变量也随之销毁,因此需要使用闭包。
拓展: 闭包函数是在window作用域下执行的,也就是说,this指向windows
缺点
: 内存泄露问题, 所以不能滥用闭包
v-if和v-for哪个优先级更高? 如果两个同时出现,应该怎么优化得到更好的性能?
结论 :
显然v-for 优先于 v-if
(怎么知道的
。。。。源码可以查看 搜索 fenElement 可查看for比if判断优先 亲自也测过)
HTML5的新特性和CSS3的新特性
HTML5的新特性
语义化标签 :header,nav、 aside、footer, article, section
可以更清晰地描述网页的结构和内容,提高网页的可读性和可访问性,同时也有利于搜索引擎优化(SEO)。
表单控件验证功能
:如日期选择器、颜色选择器、滑块等,使表单更加易用,同时内置了表单验证功能,减少了前端验证代码的编写量。
多媒体支持 video audio
等
CSS3的新特性改善布局和样式 如边框圆角、边框阴影、渐变、文本装饰
动画和过渡 transition 属性和 @keyframes 规则制定动画效果
多列布局和弹性盒子布局
媒体查询 不同屏幕的尺寸使用不同的css
自定义字体和背景
网格布局 上下居中水平对齐方式
display: grid; place-items: center;
/* 水平和垂直都居中 */
div 上下居中对齐的几种方式
第一种:flex布局
.parent {
display: flex;
justify-content: center; /* 水平居中 /
align-items: center; / 垂直居中 /
height: 100vh; / 或者其他需要的高度 */}
第二种使用Grid 网格布局.parent {
display: grid;
place-items: center; /* 水平和垂直都居中 / height: 100vh; / 或者其他需要的高度 */
}
第三种使用相对定位和绝对定位.parent { position: relative; height: 100vh; /}
.child {
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%, -50%);
}
第四中使用line-height 适用于单行文本.parent {
line-height: 100vh;
text-align: cente
}
js中操作数组的方法
伪类和伪元素的区别
伪类:伪类用于选择DOM树之外的信息:hover 伪类用于选择鼠标悬停在其上的元素,:visited 用于选择已访问的链接等
伪元素:伪元素为DOM树没有定义的虚拟元素 例如,::before 和 ::after 伪元素允许在元素内容之前或之后插入内容
css 选择器的优先级排序
优先级排序从高到低: !important 行内样式 ID选择器 类选择器
深拷贝与浅拷贝
浅拷贝 在栈内存中重新开辟一块内存空间,并将拷贝对象储存在栈内存中的数据存放到其中。
存在问题
:浅拷贝只复制了引用,所以修改新对象会影响到原对象
实现方法: 使用赋值运算符(=)或者Object.assign()函数进行拷贝
示例:
const a = [1, 2, 3];
const b = a; // 浅拷贝
b[0] = 4;
console.log(a); // [4, 2, 3]
console.log(b); // [4, 2, 3]
深拷贝 会另外创造一个一模一样的对象优点:修改新对象不会影响到原对象
实现方法:递归拷贝 JSON.parse(JSON.stringify(obj)) ...扩展运算符
示例
const a = [1, 2, 3];
const b = [...a]; // 这只适用于一层深拷贝
const c = JSON.parse(JSON.stringify(a)); // 深拷贝
c[0] = 4;
console.log(a); // [1, 2, 3]
console.log©; // [4, 2, 3]
HTTPS的工作流程,,HTTPS证书的验证
ruby
客户端发起HTTPS请求:客户端向服务器发起HTTPS请求,并指定要访问的HTTPS资源的URL。
服务器返回公钥证书:服务器将包含公钥的证书发送给客户端。
客户端验证证书:客户端验证证书的合法性,包括证书是否由受信任的CA(证书颁发机构)签发、证书是否过期等。
生成并发送对称加密密钥:如果证书验证通过,客户端将生成一个对称加密密钥,并使用服务器公钥对该密钥进行加密后发送给服务器。
服务器解密对称加密密钥:服务器使用自己的私钥解密得到对称加密密钥。
加密传输数据:双方使用协商好的对称加密密钥对传输的数据进行加密和解密。
JSONP原理
利用script
标签 的 src 没有跨域限制的"漏洞" 来达到与第三方通讯的目的
只能处理get请求
CORS:
服务器端对于CORS的支持,主要就是通过设置**Access-Control-Allow-Origin
**来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
...数组快速去重 数组扁平化
js
let a=[1,6,8,4,9,5,3,2,5,4,8,1,2,3]
let arr=[...new Set(a)]
console.log(arr);//[1, 6, 8, 4, 9, 5, 3, 2]
let b=[1,1,2,2,3,[1,2,3],[1,2,[2,3]]]
b=b.flat(Infinity)
console.log(b);// [1, 1, 2, 2, 3, 1, 2, 3, 1, 2, 2, 3]
Cookie(4kb)、 storage (5MB) localStorage(5MB)
它们的区别在于存储的有效期和作用域的不同
cookie 默认的 有效期很短暂 一旦用户关闭浏览器,Cookie保持的数据就会丢失。
cookie存储空间比较小 一般在4KB左右
作用域通过文档源和文档路径确定
localStorage存储的数据是永久性的 除非手动删除
存储大小通常为5MB
作用域限制在文档源级别 同源的文档间共享同样的localStorage数据
sessionStorage存储的数据存在会话期
通常可以达到5MB左右
一旦窗口或者浏览器标签页关闭存储的数据也会被删除
作用域也是限定在文档源中
什么是CSS盒模型 >>> -IE盒模型和W3C盒模型
标准模式下,一个块的宽度 = width+padding(内边距)+border(边框)+margin(外边距)
;
怪异模式下,一个块的宽度 = width+margin(外边距) (即怪异模式下,width包含了border以及padding);
实现继承的几种方式
1、原型链继承
2、构造继承
3、实例继承
4、拷贝继承
5、组合继承
浏览器垃圾回收
怎么回收的
当JavaScript代码运行时,需要分配内存空间来存储变量和值。当变量不再参与运行时,就需要系统收回被占用的内存空间,这就是垃圾回收
常见内存泄露的原因
- 全局变量引起的内存泄露
- 闭包引起的内存泄露:慎用闭包
- dom清空或删除时,事件未清除导致的内存泄漏
- 循环引用带来的内存泄露
优化写法
在对象结束使用后 ,令obj = null
js中开辟空间的操作有new(), [ ], { }, function (){...}。最大限度的实现对象的重用;
慎用闭包。闭包容易引起内存泄露
js重复的问题 作用域链、原型、原型链、闭包? 面相对象 继承
**面相对象
:**是一种编程思想,将现实世界的事物抽象为对象,并使用类和对象来创建各种功能
1.1作用域链
内部环境可以通过作用域链来访问外部环境的属性和方法,但是,外部环境不能访问内部环境的任何属性和方法。注意,只能通过定义函数来延长作用域链条。
1.2闭包
- 概念:闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
- 例子:函数b就是一个闭包函数,用于获取函数a内部的变量i。当函数a的内部函数b,被函数a外的一个变量c引用的时候,就创建了一个闭包。
作用
:闭包可以用在许多地方。它的最大用处有两个
可以读取函数内部的变量
让这些变量的值始终保持在内存中
1.3 原型链
原型
:所有的函数都有一个特殊的属性prototype(原型),prototype属性是一个指针,指向的是一个对象(原型对象),原型对象中的方法和属性都可以被函数的实例所共享。所谓的函数实例是指以函数作为构造函数创建的对象,这些对象实例都可以共享构造函数的原型的方法。
原型链
:原型链是用于查找引用类型(对象)的属性,查找属性会沿着原型链依次进行,如果找到该属性会停止搜索并做相应的操作,否则将会沿着原型链依次查找直到结尾。常见的应用是用在创建对象和继承中。
如何处理不让别人盗用你的图片,访问你的服务器资源?
1 .如果你用的是nginx,那可以考虑用location 通配你的图片后缀,根据refer,再决定是否返回图片资源。
2. 又拍云 七牛云 都有防盗链配置
3. 假设没有使用cdn,即需要自己做防盗链。
一是对refer做判断看来源是不是自己的网站,如果不是就拒绝,这个适用范围最大,也很容易破解, 因为refer可以伪造。第二个是通过session校验,如果不通过特定服务生成cookie和session就不能请求得到资源。这个最保 险,因为session在后端。
**4.**给图片加水印
如何优化网站性能
1 许多的小图片整合到一张大图片中(精灵图)减少网页的http请求 ,提升网页加载速度。
对于 一些小图标,可以使用base64位编码,以减少网络请求。但不建议大图使用,比较耗费CPU; 小图标优势在于:.减少HTTP请求; .避免文件跨域; .修改及时生效;
2 代码压缩 应用第三方资源库 cdn托管
3 控制资源文件加载优先级 css 优先 一般情况下都是CSS在头部,JS在底部。
4 利用浏览器缓存
5 减少页面重排
6 图片lazyload 懒加载 提高用户体验
7 禁止使用gif图片实现loading效果(降低CPU消耗,提升渲染性能);
8 、使用CSS3代码代替JS动画(尽可能避免重绘重排以及回流);
9 减少dom 操作 优化js
如果后端地址不带路径'/api', 路径:'http://www.xxxxxx.com/api' 改为'http://www.xxxxxx.com'即可。
DOM 事件流和事件委托
事件委托利用了事件冒泡
事件冒泡允许多个操作被集中处理(例如,把事件处理器添加到一个父级元素上,避免把事件处理器添加到多个子级元素上),并且可以在对象层的不同级别捕获事件。
事件委托是利用事件冒泡原理实现的,即事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素
阻止事件冒泡,可以通过event.stopPropagation()方法来阻止事件冒泡
操作数组和对象的常见方法
array: slice splice concat filter map reduce
obj : keys assign
示例:
bash
const fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
const citrus = fruits.slice(1, 3);
// ['Orange','Lemon']
const fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
const removed = fruits.splice(2, 2, 'Kiwi', 'Pineapple');
//替换了原数组['Kiwi', 'Pineapple', 'Lemon', 'Apple', 'Mango']
//fruits.splice(2, 2)// ['Lemon', 'Apple']
new内部做了什么
1.创建了一个新对象 var obj = {}
2 this关键字指向obj
3 prototype原型指向obj原型,
4 执行构造函数
防抖、节流 , 函数节流的应用场景
函数防抖和节流是优化高频率执行js代码的一种手段,js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。
函数防抖
: 在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现
函数节流
:每隔一段时间,只执行一次函数。
场景有
:1
滚动加载,加载更多或滚到底部监听2
谷歌搜索框,搜索联想功能3
高频点击提交,表单重复提交
this指向
1.普通函数调用,此时 this 指向 window
2.构造函数调用, 此时 this 指向 实例对象
3.对象方法调用, 此时 this 指向 该方法所属的对象
4.通过事件绑定的方法, 此时 this 指向 绑定事件的对象
5.定时器函数, 此时 this 指向 window
bash
1
function fn() {
console.log(this); // window
}
fn(); // window.fn(),此处默认省略window
2
function Person(age, name) {
this.age = age;
this.name = name
console.log(this) // 此处 this 分别指向 Person 的实例对象 p1 p2
}
var p1 = new Person(18, 'zs')
var p2 = new Person(18, 'ww')
3
var obj = {
fn: function () {
console.log(this); // obj
}
}
obj.fn();
4
<body>
<button id="btn">hh</button>
<script>
var oBtn = document.getElementById("btn");
oBtn.onclick = function() {
console.log(this); // btn
}
</script>
</body>
let const var 的区别
js
var 作用域是全域的; var允许重复声明变量
let 作用域是块级 let不允许重复声明变量
const 声明的是常量, 它跟let一样作用于块级作用域,没有变量提升,重复声明会报错,不同的是
const声明的常量不可改变,声明时必须初始化(赋值)
浏览器与服务器的交互原理
可以简单分为7 个步骤
1---> 输入网址
2---> 浏览器发送 http 请求
3---> 与dns 建立tcp/ip 3次握手
4---> 服务器 解析 并查找对应的域名
5---> 服务器相应数据返回
6--->浏览器 下载 解析 服务器的响应数据
7---> 创建dom树 并解析css 与js 知道页面渲染完毕
ES5 与 ES6新特性
说一下对promiss的理解
Promise是JavaScript中异步编程的一种解决方案,用于处理异步操作的结果
特点
:Promise对象的状态不受外界影响,只有异步操作的结果才能决定其状态
优点
解决了回调地狱问题,使得代码结构更加清晰和可维护
提供了统一的API,使得异步操作的控制更加容易
在ES8中引入了async/await,它是基于Promise实现的,使得异步编程更加简洁和直观
ruby
es5 数组的方法 foreach map filter every indexOf
es6 数组方法 find(callback) findIndex(callback) includes(callback)
let 块级作用域 不能重复声明
const 常亮 声明必须赋值
es6新
promise 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,
promise共有三个状态pending(执行中)、resolve(成功)、rejected(失败)
Promise 链式调用是一种编程模式,允许在异步操作之间顺序执行多个操作。在每个操作中,可以使用 `.then()` 方法返回一个新的 Promise,从而在异步流程中继续执行下一个操作。这样可以避免回调函数地狱,提高代码的可读性和可维护性。
链式调用的基本步骤包括:
创建一个新的 Promise 对象,并调用 `resolve` 或 `reject` 来变更其状态。
在 `then` 或 `catch` 方法中,处理成功或失败的状态。
在 `then` 方法中,可以使用 `return` 关键字返回一个新的 Promise 对象,或者直接返回普通值。
模块化 :就是把代码进行拆分,方便重复利用 、模块功能主要由两个命令构成:export和import。
箭头函数的简化 ()=>{}
ES6给数组新增了许多方法:
find(callback):把数组中的元素逐个传递给函数callback执行,如果返回true,则返回该元素
findIndex(callback):与find类似,不过返回的是品牌到的元素的索引
includes(callback):与find类似,如果匹配到元素,则返回true,代表找到了。
vue面试题
对于MVVM的理解?
1.MVVM 是 Model-View-ViewModel 的缩写。
2 mvvm的设计原理是基于mvc的
Model代表数据模型 .
View 代表UI 组件视图
ViewModel监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View
vue中的跨域问题
找到配置文件config.js **修改`proxyTable`**
javascript
proxyTable: {
'/api': {
target: 'http://www.xxxxxx.com/api',//指定代理的地址
changeOrigin: true,//是否允许跨越 改变源到url,在虚拟主机上很有用
pathRewrite: {
'^/api': '/',//重写,
}
}
}
vue深度监听(watch)
js
export default {
data(){
return{
name:'zhangsan'
}
},
watch:{
name(newValue,oldValue){
}
}
}
深度监听
js
export default {
data() {
return {
a: {
b: {
c: true
}
}
};
},
watch: {
//第一种
"a.b.c": function(newValue, oldValue) {
console.log(newValue, oldValue);
},
//第二种
a: {
deep: true, //deep为ture 意味着开启了深度监听a对象里面任何数据变化都会触发
handler(newValue, oldValue) {
//这个函数是固定写法
console.log(newValue, oldValue);
}
}
}
};
vue 怎么缓存 keep-alive
可以 在路由里设置需要缓存的组件 缓存 后 页面跳转回来 不会重新获取数据渲染
vue原理
**通过object.defineProperty 的数据劫持 **
你知道vue中的key 和工作原理么?说说你对它的理解
key的作用主要是为了高效的更新虚拟DOM
其原理是vue 在pacth过程中通过key 可以精准判断两个节点是否是同一个, 从而避免平凡更新不同元素 减少dom操作 提升性能
你怎么理解vue中的 diff 算法?
首先diff算法是虚拟DOM的 产物 通过新旧虚拟dom 对比, 将变化的地方更新在真实的dom上
vue中 diff 算法能精准找到发生的变化的地方
对keep-alive 的了解?
keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态
,或避免重新渲染
作用 页面状态保持
$route
和$router
的区别
答:$route是"路由信息对象",包括path,params,hash,query,fullPath,matched,name等``路由信息参数。 而$router是VueRouter"路由实例"对象包括了路由的跳转方法,钩子函数等
。
vue.js的两个核心是什么?
答:数据驱动、组件系统
vue几种常用的指令
答:
v-for 、
v-if 、
v-bind、
v-on、
v-show、
v-else等等
v-for的优先级高于v-if 在Vue 2中在同一个元素上同时使用这两个指令时 在Vue 3中,v-if的优先级高于v-for。不推荐一起使用 在外层包装一个template标签
vue常用的修饰符?
ruby
.prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用
v-on 可以绑定多个方法吗?
可以 ... 例: <p @click="one(),two()">点击
vue中key 值的作用
这个key值对数据改变之后的diff更新比较有很大的性能提升,或者说有了key和没有key是两种比较和更新机制
Key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,
其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果 就不会达到最小更新
index值不是一定不变的,如果不加key值的话,删除前面的项。后面的index可能变也可能不变,
比如加个定时器的时候会变,不加定时器不会变
$nextTick的使用
用法:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,
获取更新的 DOM
。例 -----如果在修改data数据之后立即获取dom 的话使用nexttick可以获取最新数据
父组件调用子组件方法
在父组件的方法中调用子组件的方法,很重要 this.$refs.mychild.parentfunction
("嘿嘿嘿");
代码文档
项目初始化页面闪动问题
vue页面在加载的时候闪烁花括号{}},v-cloak指令和css规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕。
go
/*css样式*/
[v-cloak] {
display: none;
}
<!--html代码-->
<div id="app" v-cloak>
<ul>
<li v-for="item in tabs">{{item.text}}</li>
</ul>
</div>
Vue3
Vue3带来了什么
更快的渲染速度:Vue3使用了Proxy代理对象
更小的体积
更好的TypeScript支持
更好的组件封装
ref与reactive
reactive:
(1)、它的响应式是更加'深层次'的,底层本质是将传入的数据包装成一个Proxy。
(2)、参数必须是对象或者数组,如果要让对象的某个元素实现响应式时比较麻烦。需要使用toRefs
ref:
(1)、函数参数可以是基本数据类型,也可以接受对象类型
(2)、如果参数是对象类型时,其实底层的本质还是reactive,系统会自动根据我们给ref传入的值转换成:reactive
(3)、在template中访问,系统会自动添加.value;在js中需要手动.value
(4)、ref响应式原理是依赖于Object.defineProperty()的get()和set()的。
vue3中使用vue-router,useRoute和useRouter ?
bash
1、在Vue.js中,useRoute和useRouter是Vue Router提供的两个钩子函数,用于在组件中访问路由信息和路由实例。
2、useRoute相当于是vue2中的this.$route
import { useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
console.log(route.path) // 当前路由路径
return {
route
}
}
}
3、useRouter相当于是vue2中的this.$router,可以使用useRouter进行路由跳转
import { useRouter } from 'vue-router'
export default {
setup() {
const router = useRouter()
console.log(router.currentRoute.value.path) // 当前路由路径
return {
router
}
}
}
4、区别:
useRoute函数返回当前路由的信息对象,包括路由路径、参数、查询参数等信息。
useRouter函数返回Vue Router的实例,我们可以在组件中使用useRouter函数来获取Vue Router的实例。
vue3中废弃了过滤器
vue3要精简代码,并且filter功能重复,filter能实现的功能,methods和计算属性基本上也可以实现。所以就干脆把filter这方面的vue源码给删掉,这样的话,更加方便维护。
vue2
Vue2的生命周期
什么是vue2生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为
Vue 的生命周期。
vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
第一次页面加载会触发哪几个钩子?
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。
Vue实现数据双向绑定的原理:Object.defineProperty()
vue实现数据双向绑定
主要是:采用数据劫持结合发布者
-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应监听回调
Vue组件间的参数传递 和父子组件方法调用
go
1.父组件与子组件传值
父组件传给子组件 :子组件通过`props`方法接受数据;
子组件传给父组件 :`$emit` 方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
`eventBus`,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。
项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。
技术只是手段,目的达到才是王道。)
3. 父组件调用子组件方法 this.$refs.mychildren.function()
4. 子组件调用父组件方法 this.$parent.function()
params 传值
js
//路由里:id
{path:/user/:id}
//组件传值 用 /id
<router-link to ="/user/123"></router-link>
//js代码中获取路由传递的id值
this.$router.params.id
query 传值
js
//路由
{path:'/user'}
//组件传值 使用?拼接 参数之间用&
<router-link to ="/user?id=123"></router-link>
<router-link to ="/user?id=123&name=zs"></router-link> //组件传值
this.$router.query.id //取值
this.$router.query.name //取值
Vue的路由实现:hash模式 和 history模式
1 hash模式:在浏览器中符号"#", 用window.location.hash读取
2 history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
vue路由的钩子函数 (路由守卫)
首页可以控制导航跳转,
beforeEach
,afterEach
等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。beforeEach主要有3个参数
to,from,next
:to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
Vue-router的跳转原理:
ruby
Vue-router的跳转原理:
vue-router实现单页面路由跳转,提供了三种方式: hash方式、history模式、abstract模式,根据mode参数来决定采用哪一种方式
● hash: 使用 URL hash 值来作路由。默认模式。
● history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
● abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端
路由之间的跳转:
声明式(标签跳转):<router-view>标签用于展示路由组件,DOM节点中使用v-link进行跳转,或使用router-link标签
编程式(js跳转)
怎么定义vue-router的动态路由以及如何获取传过来的动态参数?
在router目录下的index.js文件中,对path属性加上/:id
使用router对象的params id
Vue中,如何用watch去监听router变化
当路由发生变化的时候,在watch中写具体的业务逻辑
let vm = new Vue({
el:"#app",
data:{},
router,
watch:{
$router(to,from){
console.log(to.path);
}
}
})
vue-router有哪几种导航钩子?以及它的参数?
三种,一是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件
beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave
参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种
Vue的路由实现: hash模式和history模式(Vue的两种状态)
hash------即地址栏URL的#符号,特点: 通过window.onhashchange的监听, 匹配不同的url路径,进行解析,加载不同的组件,然后动态的渲染出区域内的html内容,不会被包含在HTTP请求中,对后端完全没有影响
HashHistory有两个方法:
HashHistory.push()是将路由添加到浏览器访问历史的栈顶
hashHistory.replace( ) 是替换掉当前栈顶的路由
因为hash发生变化的url都会被浏览器历史访问栈记录下来,这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来的,浏览器还是可以进行前进后退的
history ------ 利用了HTML5 History Interface中新增的pushState()和replaceState()方法。这两个方式应用于浏览器的历史记录栈,提供了对历史记录的修改功能。history模式不怕页面的前进和后腿,就怕刷新,当刷新时,如果服务器没有相应的响应或者资源,就会刷出404,而hash模式不会
$route从当前router跳转对象里面可以获取name、path、query、params等(<router-link>传的参数有this.$route.query或者this.$route.params接收)
$router为VueRouter实例。想要导航到不同URL,则使用$router.push方式,返回上一个history也是使用$router.go/$router.back方法
vuex是什么?怎么使用?哪种功能场景使用它?
Vuex可以理解为一种开发模式或框架,通过状态集中管理驱动组件的变化,应用级的状态集中放在store中,改变状态的方式是提交mutations,异步逻辑封装在action中
js
是状态管理,在main.js引入store,注入。只用来读取的状态集中放在store中;
改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
`场景有`:单页应用中,组件之间的状态、音乐播放、登录状态、
加入购物车vuex是一种集中式状态管理模式,它按照一定的规则管理状态,
保证状态的变化是可预测的。
state:定义初始化状态
getters:获取状态
mutations:设置状态
actions:异步提交mutations
modules:把状态管理模块化,各自的组件构成各自的模块
前端面试算法题汇总(持续更新...)
1. 算出字符串中出现次数最多的字符
bash
var str = 'afjghdfraaaa'
var obj={}
for (let i = 0; i < str.length; i++) {
var k=str[i];
if(obj[k]){
obj[k]++
}else{
obj[k]=1
}
}
console.log(obj); //a: 5 d: 1 f: 2 g: 1 h: 1 j: 1 r: 1
let num =0;
let val=null
for( var j in obj){
if(obj[j]>num){
num=obj[j]
val =j
}
console.log(val ,num);
}
Git使用
git使用总结
多人开发 避免版本冲突
webpack 常见面试题
1 什么是 webpack ?打包原理?
webpack 是一个现代 JavaScript 应用程序的静态模块打包器
webpack可以递归的打包项目中的所有模块(递归:指定一个入口,分析模块的依赖,它会递归的查找所有相关的依赖),
2核心概念
Entry Output Module Chunk Loader Plugin
Entry : 配置入口文件 webpack会找出有哪些模块是入库的依赖 , 相关的依赖会被处理 输出到bundles的文件中
Output :output属性会告诉webpack 他所创建的bundles 如何命名 默认值为 ./dist
module : 模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk : 代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。
loader :模块转换器,用于将模块的原内容按照需要转成你想要的内容
babel和webpack的区别: babel JS新语法编译工具,只关心语法,不关心模块化 webpack -打包构建工具,是多个Loader plugin的集合
webpack与grunt、gulp的不同?
Webpack与Gulp、Grunt没有什么可比性,Webpack它可以看作模块打包机
通过分析你的项目结构找到js模块以及一些浏览器不能直接运行的语言( scss typescript)
Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
webpack有哪些优点
可通过plugin扩展
使用场景不局限于web开发
良好的开发体验
webpack的缺点
webpack的缺点是
只能用于采用模块化开发的项目
如何利用webpack来优化前端性能?
代码压缩 按需加载 使用Dll进行分包
.
正常情况下node_module会被打包成一个文件,使用dll技术,对可以将那些不常更新的框架和库进行单独打包,生成一个chunk
如何提高webpack的构建速度?
1.减少需要构建的文件或代码
2.多进程打包 thread-loader,将其放在费时的loader之前
- 如何利用webpack来优化前端性能?
代码压缩
按需加载
什么 是模块热更新?
模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。
vite面试题
什么是vite ?它解决了什么问题 ? Vite的工作原理是什么?
前端构建工具。提供了快速的冷启动和即时的热模块更新,
解决了传统打包工具在开发阶段的缓慢问题
通过index.html的type="module"脚本标签直接从服务器加载模块
vite.config.js文件是做什么用的?
vite.config.js是Vite的配置文件,允许你自定义Vite的行为,如定义入口文件、基础路径、构建输出、插件等
Vite与Webpack相比有何不同?
Vite基于ES模块系统,不需要进行打包和构建,而Webpack则将所有代码打包成一个或多个bundle。Vite的冷启动速度更快,且支持原生ES模块和丰富的插件体系
vue3.0 生命周期
创建期setup()
挂载期:
onBeforeMount() 组件挂载到节点上之前执行的函数
onMounted() 组件挂载完成后执行的函数,此时可以访问和操作DOM
更新期:
onBeforeUpdate(): 组件更新之前执行的函数
onUpdated(): 组件更新完成之后执行的函数
销毁期:
onBeforeUnmount(): 组件卸载之前执行的函数,可以进行一些善后的工作,例如清理定时器等
onUnmounted(): 组件卸载完成后执行的函数,表示组件已经被完全销毁
vue2 与vue3 的区别
1.Vue 3在速度和体积上相较于Vue 2更小、更快
2.生命周期钩子函数有所变化 , 例如beforeCreate和created被setup()函数替代。而其他的生命周期钩子函数则需要在前面加上on前缀,如onBeforeMount、onMounted等
3.响应式系统 ,Vue 2使用Object.defineProperty()数据劫持来实现响应式数据绑定,Vue 3则使用Proxy来替代
react面试题
React有什么特点
它使用虚拟DOM 而不是真正的DOM。
它可以进行服务器端渲染。
它遵循单向数据流或数据绑定。
优点:
代码可读性很好
性能好
什么是虚拟DOM?
虚拟DOM是真实DOM在内存中的表示,ul的表示形式保存在内存中,并且与实际的DOM同步,这是一个发生在渲染函数被调用和元素在屏幕上显示的步骤,整个过程被称为调和
React 中 key 的重要性是什么?
key 用于识别唯一的 DOM 元素帮助 React 优化渲染
类组件和函数组件之间的区别是什么?
- 类组件可以使用其他特性,如状态和生命周期钩子,并且他有this
- 函数组件只能接收props渲染到页面,无状态组件,没有this,不能使用生命周期钩子,但可以使用hooks
- 函数组件性能要高于类组件 因为类组件使用要实例化,而函数组件直接执行取返回结果即可 为了提高性能,尽量使用函数组件
React 生命周期
不同版本中有所调整v16之前的,
类组件生命周期方法
初始化/挂载 constructor(props)
挂载 render()
挂载后 componentDidMount()
更新 render()
更新后 componentDidUpdate
卸载 componentWillUnmount()
函数组件生命周期钩子 Hook 方法初始化 useState()
挂载 useEffect()
卸载 useCleanup()
react生命周期方法有哪些?
componentWillMount:在渲染之前执行,
componentDidMount:在第一次渲染之后执行,
componentWillReceiveProps:在初始化render的时候不会执行
shouldComponentUpdate:确定是否更新组件。
componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前件之前执行。
componentDidUpdate:它主要用于更新DOM以响应props或state更改。
componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器。
react中refs是什么?
一种访问DOM节点的方法
state和props区别是什么?
相同点:都是js对象,包含页面渲染输出的信息
不同点: state是组件自己数据,可变,而 props是外部传入的数据参数不可变
如何创建refs?
通过React.createRef()创建的
什么是jsx?
在第一发布react时,还引入了一种新的js方言jsx,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babel和webpack等工具将其转换为传统的JS
为什么不直接更新state?
如果试图直接更新state,就不会重新渲染组件,需要使用setState()方法更新state,它对state对象进行更新,当state改变时,组件通过重新渲染来响应
什么是高阶组件?
高阶组件(HOC)是接受一个组件并返回一个新组件的函数,
因为它们可以接受任何动态提供的子组件,但不会修改或复制输入组件中的任何行为
受控组件和非受控组件区别是啥?
受控组件
在 HTML 中,表单元素如 < input>、< textarea>和< select>通常维护自己的状态,并根据用户输入进行更新,这种组件跟踪渲染表现为受控组件
非受控组件
是由 DOM 处理表单数据的地方,而不是在 React 组件中
什么是 React Context?
Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性
React 性能优化
1.组件优化 尽量通过props来处理数据避免不必要的重新渲染
2.使用reduce管理数据
3.利用本地存储
4静态资源压缩,优化CSS、JavaScript文件大小
tsx转换成真实DOM过程
TypeScript 编译阶段
JSX编译阶段
创建虚拟DOM
渲染虚拟DOM
DIFF算法与更新DOM
真实DOM更新
使用 React Hooks 好处是啥?
函数组件中可以使用类组件中的特性问题
什么是Redux?列出 Redux 的组件?
Redux 是当今最热门的前端开发库之一。它是 JavaScript 程序的可预测状态容器,用于整个应用的状态管理。使用 Redux 开发的应用易于测试,可以在不同环境中运行,并显示一致的行为
这里是引用Action -- 这是一个用来描述发生了什么事情的对象。
Reducer -- 这是一个确定状态将如何变化的地方。
Store -- 整个程序的状态/对象树保存在Store中。
View -- 只显示 Store 提供的数据。
Redux 有哪些优点?
1.结果的可预测性
2.可维护性
常用的hooks?
useState: 定义state的数据
useEffect:副作用函数
useMemo:用来计算数据
useMemo和useEffect 相比较来说,useMemo 是组件更新的时候触发生命周期
useCallback:当父组件向子组件传递函数的时候
useRef:相当于createRef的使用,创建组件的属性信息
useContext:相当在函数组件中获取context状态数的内容信息
useReducer:useReducer是用来弥补useState的补不足, 可以把数据进行集中式的管理,单独处理数据的逻辑信息