文章目录
一.前端项目概述1.系统登录注册模块1.对注册的密码进行加密 (使用加密中间件bcrypt.js)2.登录成功后返回token3.前端登录页面有用到弹性布局,ref和reactive4.登录头像:文件上传 2.系统设置模块2.系统首页模块(轮播图+栅格布局+dialog弹窗)1.弹窗+富文本编辑器wangeditor 3.系统概览模块(echart组件可视化信息,快速点击入口)1.用了哪些echart图? 4.用户管理模块1.前端完成分页功能(实现一个算法)2.用户赋权问题 二.针对项目可能问的问题1.用ts吗?说一下你常用的知识点。2.vue3和vue2的区别。3.说一下你项目中的难点,是怎样解决的?4.我看你项目中用过node.js,说一下你对前端用node.js的看法5.你为什么选择用express框架,express和koa的区别6.说一下computed和watch的区别,及实现原理7.你工作中有没有自己写过组件,你觉得写组件的原则是什么?8.用过哪些设计模式?什么场景下会遇到9.你对高内聚,低耦合怎么理解?10.做过哪些性能优化?11.用过哪些加密方式,都怎么用的?12.ref和reactive的区别?(组件间传值会用上)13.Dialog对话框是什么?14.解构赋值是什么?15.你这里的文件上传是怎么做的?16.项目中有遇到哪些错误吗?17.项目中前端你是如何发送请求的?(写一下原生ajax发送请求)18.基于promise怎么封装这个axios请求?19.说一下事件循环?20.多端适配怎么做?21.echart了解到什么程度,底层是用canvas和re-render22.路由传参query和params区别23.
一.前端项目概述
1.系统登录注册模块
前端通过ts限制数据类型,后端通过joi限制数据类型
这里的这个joi是对输入数据进行限制的中间件
!!
1.对注册的密码进行加密 (使用加密中间件bcrypt.js)
对密码进行加密bcrypt.jsreginfo.password = bcrypt.hashSync(reginfo.password,10)//10是指加密后的长度
这里后端解密(compareSync),其实也不是真正的解密,这种密码一般都是不可逆的
const compareResult = bcrypt.compareSync(loginfo.password,result[0].password)
2.登录成功后返回token
生成返回给前端的token
res.send({results:results[0]status:0message:"登录成功"token:'Bearer'+tokenStr})
3.前端登录页面有用到弹性布局,ref和reactive
弹性布局:flex
display:flexjustify-content:space-between
ref:通常用来定义基本数据类型
reactive:如果使用的是数组和对象,就要使用reactive
const activeName = ref('first')const loginData = reactive({account:'',password:'',})
4.登录头像:文件上传
Multer是一个node.js中间件
用于处理multipart/form-data类型的表单数据
它主要用于上传文件
!!!
通常情况下,上传图片后,这个图片会和上传该图片的用户绑定
我之前做这个部分的时候,用的是image_url绑定的,事实上,用image_url绑定容易出错,可能会出现相同的url地址。
后来的解决方案是使用onlyid去分别绑定图片的地址,然后用这个onlyid去绑定用户
onlyid是使用node.js的crypto库随机生成的。
2.系统设置模块
pinia:因为我们当前的数据是多组件共用的一个数据
pinia是vue的专属状态管理库
它允许你跨组件或页面共享状态
封装了一个面包屑组件
2.系统首页模块(轮播图+栅格布局+dialog弹窗)
首页基本布局:
1.弹窗+富文本编辑器wangeditor
3.系统概览模块(echart组件可视化信息,快速点击入口)
1.用了哪些echart图?
饼状图,柱状图,环形图,折线图
4.用户管理模块
1.前端完成分页功能(实现一个算法)
2.用户赋权问题
本系统做的是一个企业管理系统,在企业中不同的岗位有不同的权限,因此我们需要做一个用户赋权的判断。
其实就是一个dialog弹窗,里面有一个单选
二.针对项目可能问的问题
1.用ts吗?说一下你常用的知识点。
2.vue3和vue2的区别。
1.vue3中引入组合式api,在setup()中可以更加灵活的组合和复用逻辑,vue2中逻辑分布在data,computed,methods中,有局限性。
2.vue3更好的支持ts
3.生命周期不同,vue3生命周期是setup(),onbeforeMount,onMounted,onbeforeUpdate,onUpated,onbeforeUnMount,onUnmounted
4.vue2使用vuex,vue3使用pinia
3.说一下你项目中的难点,是怎样解决的?
图片上传部分,不能直接根据图片url进行绑定用户,因为它这个图片地址可能是一样的,我们需要为头像创建一个唯一id,通过这个唯一id去绑定用户
4.我看你项目中用过node.js,说一下你对前端用node.js的看法
node.js是一个基于chorme V8引擎的JavaScript运行环境。
5.你为什么选择用express框架,express和koa的区别
6.说一下computed和watch的区别,及实现原理
7.你工作中有没有自己写过组件,你觉得写组件的原则是什么?
写过一些小组件,比如面包屑组件,就是一个导航列表,显示你现在正在哪个功能目录下,比如:用户管理模块–>产品管理员这种
还有头组件,页面底部组件这些
原则是可复用性高,能够是代码更简洁,减少代码量比较好
8.用过哪些设计模式?什么场景下会遇到
发布订阅模式
像数据双向绑定,事件总线都是用的发布订阅模式
9.你对高内聚,低耦合怎么理解?
10.做过哪些性能优化?
数据缓存机制,将用户信息缓存在本地,因为很多组件都要用到这个信息
上传大文件是用的异步上传,几个切片并行上传,节省了时间,提高了性能
11.用过哪些加密方式,都怎么用的?
1.有用过一个加密中间件,是一个密码哈希函数,叫bcrypt.hashSync()
用在系统登录注册模块,前端将用户密码传到数据库的时候,传的其实是加密后的密码,下次再判断用户密码是否正确时,就把用户输入的密码加密,将加密后的内容与数据库中存放的加密密码比较,如果相同,就表示用户输入的密码是正确的。
12.ref和reactive的区别?(组件间传值会用上)
ref和reactive都可以用来创建响应式数据
1.ref一般用来定义基本数据类型的响应式数据,而reactive通常用来定义对象数组这种复杂的数据类型。
2.当你给ref赋值时,vue会自动将值包装到一个带有.value
属性的对象中,因此,后面访问,可以通过ref.value
来修改这个值
import {ref} from 'vue'const count = ref(0)console.log(count.value)count++console.log(count.value)
3.当你用reactive创建一个响应式数据时,赋值给他的对象不会被包装,你可以直接访问他的属性
import {reactive} from 'vue'const state = reactive({count:0;})console.log(state.count)state.count++console.log(state.count)
13.Dialog对话框是什么?
就是一个弹窗,这个对话框的内容可以是任何东西,甚至可以是一个表格或表单。
//控制弹窗,默认关闭const state = reactive({forgetpasswordDialog:false})//打开弹窗const open=()=>{state.forgetpasswordDialog=true}
14.解构赋值是什么?
15.你这里的文件上传是怎么做的?
上传头像部分,是使用node.js里面的multer来实现的。
16.项目中有遇到哪些错误吗?
通常情况下,上传图片后,这个图片会和上传该图片的用户绑定
我之前做这个部分的时候,用的是image_url绑定的,事实上,用image_url绑定容易出错,可能会出现相同的url地址。
后来的解决方案是使用onlyid去分别绑定图片的地址,然后用这个onlyid去绑定用户
onlyid是使用node.js的crypto库随机生成的。
17.项目中前端你是如何发送请求的?(写一下原生ajax发送请求)
我的项目是基于vue做的,我用的是axios方法
axios.get("https://api.example.com/data").then(response=>{console.log(response.data)}).catch(error=>{console.error('Error fetching data: ', error)}
18.基于promise怎么封装这个axios请求?
定义一个函数将axios封装起来
function fetchData(url){return new promise(resolve,reject)=>{axios.get(url).then(response=>{resolve(response.data)}).catch(error=>{reject("error",error)})}}//调用封装好的函数fetchData("https://api.com/data").then(data=>{console.log(data)}.catch(error=>{console.error('Error fetching data: ', error)}))
19.说一下事件循环?
20.多端适配怎么做?
21.echart了解到什么程度,底层是用canvas和re-render
22.路由传参query和params区别
query类似于get,参数会拼接到地址栏中显示,数据不会丢失
params类似于post,参数不会显示在地址栏,相对于query传参比较安全,但是传参过去后,参数保存在内存中,再次刷新页面或跳转到其他页面时数据会丢失。