面试杂技第一篇
1.探究微前端
https://mp.weixin.qq.com/s/997pVVxdgpOH6ZsDsFAh2g
2.通讯产品
https://yunxin.163.com/im?from=bd_IM_bdjj20230236
3.jquery+bootstrap基础参考案列
https://www.51fapiao.cn/fpcx/query.html
4.二次封装
基于Ant Design+VUE3 二次封装 antd 选择器
目的:
解决后台需要选择中数据的多个字段
注意:
不要使用v-model:key =>因为key 是vue 关键字;
双向绑定字段需要与change事件options中的key对应
记得一键三连哦
gitee:https://gitee.com/liliangpeng/vueUI
5.使用Nginx搭建流媒体服务器:构建高性能的视频流传输平台
https://mp.weixin.qq.com/s/wPnwuIuX1RZetVmpQcx1CQ
6.im-uikit-uniapp 是基于网易云信 IM SDK 的一款 uniapp UI 组件库,它提供了一些通用的 UI 组件,包含会话、聊天、群组等功能。
基于 UI 组件您可以像搭积木一样快速搭建起自己的业务逻辑。im-uikit-uniapp 本身基于 UIKitStore 开发,API 参考 UIKitStore。
im-uikit-uniapp 界面效果如下图所示:https://github.com/netease-kit/nim-uikit-uniapp
看看别人的代码,学习。
7.Nginx代理
# 项目打包
pnpm run build:prod
# 上传文件至远程服务器
将打包生成在 `dist` 目录下的文件拷贝至 `/usr/share/nginx/html` 目录
https://mp.weixin.qq.com/s/e_ipvAZ-LIYCgxpTXzJrtg
# nginx.cofig 配置
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 反向代理配置
location /prod-api/ {
proxy_pass http://vapi.youlai.tech/; # vapi.youlai.tech替换成你的后端API地址
}
}
8.websocket实现实时消息推送
https://mp.weixin.qq.com/s/iEYyclkwzQvC607Irs3nUQ
9.基于SpringBoot实现的快递之家管理系统
https://pan.baidu.com/s/1KUzXRusbPeTPc7f34GX3Ow?pwd=phnr
10.简单大屏
https://github.com/sj1406576460/Dashboard-Design
11.Vue2和Vue3的不同
Vue 2原理
响应式系统:Vue 2使用`Object.defineProperty`实现响应式,但在处理数组和对象变化时存在局限性。
虚拟DOM:Vue 2的虚拟DOM机制高效,但实现相对复杂。
Vue 3原理
响应式系统:Vue 3采用`Proxy`,提供更深层次的数据响应,包括数组变化和复杂对象结构。
虚拟DOM重构:Vue 3的虚拟DOM重构提高了性能,同时简化了实现。
难易程度对比
Vue 2难易程度
学习曲线平缓,适合新手。
随着应用复杂度提升,Options API可能变得难以管理。
Vue 3难易程度
引入Composition API,对新手可能稍微陡峭。
提供更好的逻辑复用和组织方式,适合大型应用维护
性能对比
Vue 3在性能上进行了显著优化,尤其增加key值查找优化:
虚拟DOM重写和组件初始化更快。
`Proxy`响应式系统更高效。
通过Tree-shaking减少打包体积。
12.Vue3 + Element-Plus + TypeScript开源后台系统
在线预览
https://www.vuecms.cn
开发文档
https://doc.vuecms.cn/vueCms/intro.html
源码
https://gitee.com/derekgo/vue-cms_xg/tree/master
13.SpringSecurity+Vue3权限系统视频教程
https://mp.weixin.qq.com/s/_uFwfSGkbR__kSWhzeKMcA
14.vue3使用vite+ant Design+Vue Router+Vuex+axios搭建项目
https://blog.csdn.net/qq_41403494/article/details/116890314
https://blog.csdn.net/XH_jing/article/details/112232930
15.Vite 中引入 ant-design-vue 的方法总结
https://segmentfault.com/a/1190000042082904
16.基于Vue3+Vite+TS+AntDv+ Pinia从零搭建一个项目
https://blog.csdn.net/wangshuo0520ai/article/details/125740092
17.vue路由切换滑动效果 vue页面跳转交互 vue实现动画跳转
https://mp.weixin.qq.com/s/qdZy2Rg7h_wcOeZT3gbLwQ
18.Vue.js 从 Axios 响应中解析 XML,将其推送到 Vue 数据数组
https://deepinout.com/vue-js/vue-js-questions/328_vuejs_parse_xml_from_axios_response_pushing_to_vue_data_array.html
axios.get('api/xml').then(response => {
this.parseXML(response.data);
});
function parseXML(xmlData) {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlData, 'application/xml');
const items = xmlDoc.getElementsByTagName('item');
for (let i = 0; i < items.length; i++) {
const title = items[i].getElementsByTagName('title')[0].textContent;
const description = items[i].getElementsByTagName('description')[0].textContent;
this.xmlData.push({
title: title,
description: description
});
}
}
1.闭包是什么?
闭包就是能够读取其他函数内部变量的函数。(闭包的理解是,能够读取其他函数内部变量的函数)
1、读取函数内部的变量;2、让这些变量始终保持在内存之中
通俗的讲就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();//外部的变量
JavaScript 中的 this 关键字是一个动态的上下文引用,它与当前代码的执行上下文有关。
在不同的使用场景下,this 可以指代不同的对象,因此深入理解 this 是开发人员必备的技能之一。
下面通过示例来说明 this 的作用域。
一、全局作用域:
在全局作用域中,this 指向全局对象 window(在浏览器中),或者 global 对象(在 Node.js 等环境中)。
console.log(this); // window/global
二、函数作用域:
在函数作用域中,this 的值取决于函数的调用方式。
① 作为普通函数调用:
当函数作为普通函数调用时,this 指向全局对象。
function foo() {
console.log(this);
}
foo(); // window/global
② 作为对象的方法调用:
当函数作为对象的方法调用时,this 指向该对象。
const obj = {
foo() {
console.log(this);
}
};
obj.foo(); // obj
③ 使用 call、apply 或 bind 方法调用:
使用 call、apply 或 bind 方法可以改变函数的执行上下文,从而改变 this 的值。
function bar() {
console.log(this);
}
const obj = {};
bar.call(obj); // obj
bar.apply(obj); // obj
const boundBar = bar.bind(obj);
boundBar(); // obj
④作为构造函数调用:当函数作为构造函数调用时,this 指向正在创建的新对象。
function Foo() {
console.log(this);
}
const obj = new Foo(); // obj
三、箭头函数作用域: 在箭头函数中,this 的值取决于外部作用域中 this 的值。
箭头函数没有自己的 this。
const obj = {
foo: () => {
console.log(this);
}
};
obj.foo(); // window/global
综上所述,this 的值是动态绑定的,它依赖于代码的执行上下文和运行环境。
了解 this 的作用域可以帮助我们更好地理解 JavaScript 中的上下文引用机制,从而更好地编写代码和调试程序。
Js事件循环
JS事件循环是指JavaScript在执行过程中处理各种事件的机制。
它是基于事件驱动的编程模型,将任务分为宏任务和微任务,并按照一定的规则执行。
具体来说,JS事件循环主要由以下几个步骤组成:
1.执行全局同步代码,初始化环境。
2.执行一个宏任务,从宏任务队列中取出一个任务进行执行。
3.在执行宏任务过程中,如果遇到异步任务(如setTimeout、Promise等),
将其加入对应的任务队列中(如定时器队列、微任务队列等)。
4.宏任务执行完毕后,检查微任务队列,如果有微任务则按顺序执行,直到微任务队列为空。
5渲染页面,更新UI。
6.如果存在嵌套的宏任务队列,则继续执行下一个宏任务,重复步骤2-5。
重复上述步骤,直到所有宏任务队列和微任务队列都为空,JS事件循环结束。
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof Array) {
return obj.reduce((arr, item, i) => {
arr[i] = deepClone(item);
return arr;
}, []);
}
if (obj instanceof Object) {
return Object.keys(obj).reduce((newObj, key) => {
newObj[key] = deepClone(obj[key]);
return newObj;
}, {});
}
}
1.箭头函数和普通函数的区别
2.深拷贝和浅拷贝的区别,JS中实现深拷贝的几种方法
3.数组的扁平化处理(flat)
4.let var const区别,用于声明变量的不同关键字
作用域:
var:具有函数作用域,即在函数内部声明的变量可以在函数外部访问,如果尝试在函数外部访问,
则会导致错误。此外,由于变量提升的存在,
var声明的变量在声明之前就已经被提升到函数作用域的顶部。
let:具有块级作用域,即在代码块(如if语句、for循环等)中声明的变量只能在该代码块内部访问。
这种作用域限制有助于避免变量冲突和提高代码的可读性。
const:同样具有块级作用域,但主要用于声明常量,即声明的变量不可更改其值。
使用const定义的对象可以修改其属性值,但不能重新分配新的对象给这个常量。
const定义的对象值能修改吗
在JavaScript中,const关键字保证的是变量的引用不可变,即变量指向的内存地址不变。
对于基本数据类型(如数值、字符串、布尔值等),const确保其值不可变。
但对于对象和数组这样的复合类型,const保证的是引用(即内存地址)不变,
而不是对象或数组的内容不可变。因此,虽然对象的内容可以被修改(例如修改对象的属性),
但无法将一个新的对象赋值给这个const变量,因为这将会改变变量的引用,而这是const所不允许的.
变量提升:
var:存在变量提升现象,即无论变量声明在代码中的位置如何,都会被提升至函数或全局作用域的顶部。
这可能导致意外的行为,尤其是在声明之前的代码段中尝试访问该变量时。
let和const:没有变量提升现象,即如果在声明之前尝试访问这些变量,会导致错误。
这有助于避免由于变量提升导致的潜在错误。
重复声明:
var:允许在同一作用域内多次声明同一个变量,后一次声明会覆盖前一次的声明。
let和const:不允许在同一作用域内重复声明同一个变量,如果尝试这样做会导致语法错误。
这些差异使得let和const相比var更加安全和灵活,特别是在处理复杂的代码逻辑和避免变量命名冲突时。
5.彻底理清防抖和节流(前端性能优化)
防抖(Debounce)
确保在指定的时间间隔内,无论连续触发了多少次事件,只有最后一次事件会在该间隔结束后执行。
(触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。)
核心逻辑:
重置计时器:每次事件触发时,都会重置计时器。
执行时机:只有在用户停止触发事件指定时间间隔后,才会执行最后一次事件。
举例:
想象一台自动售货机,里面都是不同价格的商品,当你投入相应的硬币,
会自动选择对应商品。但是为了避免还没投完就出商品,售货机设计不是投完立即掉出商品,
而是有一个短暂的延迟,在这个延迟期间,如果你再次投入硬币,售货机重新进入延迟,
只有当延迟期过后,之前投入硬币才会被处理。这样可以避免因为误操作或快速连续操作导致的错误购买。
节流(Throttle)
确保在指定的时间间隔内,无论触发了多少次事件,只有第一次事件会被执行,
后续事件在这个间隔内都不会执行。(连续触发事件但是在 n 秒中只执行第一次触发函数)
核心逻辑:
单次执行:在时间间隔内只执行一次事件处理函数。
忽略后续触发:在时间间隔内,后续的事件触发将被忽略。
举例:
想象一个繁忙的十字路口,交通信号灯每60秒变换一次。不论有多少车辆通过,信号灯都不会更快地变换。
这就像节流,无论事件触发的频率多高,每个周期内只执行一次。
https://blog.csdn.net/qq_62799214/article/details/138204516
https://blog.csdn.net/qq_62799214/article/details/138169046
一文搞懂computed和watch:Vue中的响应式双胞胎
https://blog.csdn.net/qq_62799214/article/details/138169046
什么是Vue.nextTick()??
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。
所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,
简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,
Vue.nextTick(callback) 使用原理:
原理是,Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,
然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。
如果这个watcher被触发多次,只会被推送到队列一次。
这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOm操作。
而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。
当你设置 vm.someData = 'new value',DOM 并不会马上更新,而是在异步队列被清除,
也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。
如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。
为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。
这样回调函数在 DOM 更新完成后就会调用。
Promise.all 与 Promise.race
1. Promise.all的使用
第一点字面意思:all意思为所有,全部的意思。
所以Promise.all可以将多个Promise实例包装成一个新的Promise实例。
同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,
而失败的时候则返回最先被reject失败状态的值。
通俗讲就是 Promise.all会等所有请求完成之后返回一个array包裹。
Promise.all([
postAction('url',data),
getAction('url'),
getAction('url'),
]).then(resolve => {
console.log(resolve)
})
2. Promise.race的使用
第二点字面意思:race意思为比赛,赛跑的意思。
所以Promise.race里面哪个结果获得的快,就返回那个结果,不管结果状态是成功还是失败,都会返回。
通俗讲就是 Promise.race是根据请求接口的速度来决定返回的先后顺序的。
Promise.all() 和 Promise.race() 两个方法可以在需要管理多个 Promise 对象的情况下提供便利。Promise.all() 可以等待所有 Promise 对象都完成,并统一处理它们的结果,
而 Promise.race() 可以等待只需要一个 Promise 对象完成即可,并使用其结果。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
看到了一个博文下面的评论中 谈到了race的场景使用:
race的使用场景就是,多台服务器部署了同样的服务端代码,假如我要获取一个商品列表接口,
我可以在 race 中写上所有服务器中的查询商品列表的接口地址,
哪个服务器响应快,就从哪个服务器拿数据。
19.electro打包vue项目
https://blog.csdn.net/weixin_43842567/article/details/112364484
20.白屏优化
https://mp.weixin.qq.com/s/h7a0_fM6VkGI_TckeuPpVw
开源项目h5
源码:https://gitee.com/guchengwuyue/yshop-drink
后台登陆:https://dc.dayouqiantu.cn 账号/密码:admin/admin123
门店登陆:https://dc.dayouqiantu.cn 账号/密码:yixiang001/123456789
yshopmall开源web
yshop是一个基于SpringBoot2、MybatisPlus、SpringSecurity、jwt、redis和Vue的前后端分离Mall Shop 系统,
集成了丰富的Mall Shop 功能,适合企业或个人进行二次开发。
后端:https://gitee.com/guchengwuyue/yshopmall
前端:https://gitee.com/guchengwuyue/yshopmall_qd
管理后台体验:https://demo2.yixiang.co