1.请你说一下你在项目中负责哪几个模块。在这些模块中对最有挑战的是哪个?
这个项目是跟着老师讲解一起做的项目 相对于我来说都有不同程度上挑战项目中会有一些不了解方法不知道如何使用 再加上对组件库使用的不熟练 有些解决问题的答案不知道该去哪里查
2、在项目中,如果后端提供的接口并不能获得正确的数据,你会如何做?
首先确认是否是提供的接口出现得问题,检查自己的代码是否正确。也可以使用postman进项接口测试然后再联系后端开发人员。
3、在项目中你是如何解决svg图标展示的。请详细说明一下问题的解决思路。
1.直接使用SVG文件 思路:将svg文件下载 放置在项目中,然后通过HTML的标签或者css的background-image属性来引用svg文件
2.使用svg矢量图标库 思路:使用一些开源的矢量图标库例如 FontAwesome、Material Design Icons 等 只需要在html中引用相应的css文件,在需要使用图表的地方使用特定的html标签即可
上面两种方法都需要注意浏览器的兼容性问题
4、你在这个项目中是如何做登录权限鉴定的。
项目中的登录权限认证是在前置守卫中实现的,我们想要进行登录的时候需要从vuex中获取token,然后判断token是否存在,存在的情况下还要判断是不是要访问登录页,如果访问的是登录页就直接跳到主页,如果不是在登录页访问登录页就直接放过, 如果有token但未登录就返回登录页面 在判断有没有token的时候如果没有token的时候还要判断在不在白名单中 如果在就放行 如果不在就跳到登录页
5、你在项目中用到了RBAC的思想,请介绍下你在项目中是如何实现RBAC的,并且为什么要使用RBAC。
RBAC是Role-Based Access Control的缩写,意思是基于角色的访问控制,他是一种广泛应用于计算机系统的访问控制模型 将访问控制分成两大类 :授权和认证。 授权不分定义了访问策略,就是个对象应该被那些角色访问,认证就是核实用户的身份以及用户是否具有相应角色的权限
分配权限: 1.搭建权限页面 2.封装获取权限的方法 在data中声明一个空数组用来存储后端的数据 在初始化之前调用封装的方法 在方法中进行异步操作 使用递归调用将列表数据转化成树形结构将数据存储到空数组中
使用RBAC,系统管理员可以为用户分配特定的角色,从而限制他们访问系统和资源的能力。RBAC还可以改善安全性,并降低管理复杂性
6、在项目中使用到的ui框架是按需加载还是完整引入,原因是什么。
完整引入
7、你是如何做到vuex数据持久化存储的。
utils文件下的auth中从cookie包中引入cookie 将token存到cookie中 在用户页面中导入token的方法 在mutations中将token同步到缓存中 在state中读取缓存的初始值 将store中的数据存到cookie中 是因为关闭浏览器数据就会自动销毁 存到本地中关闭浏览器不会自动销毁 所以存到cookie中更安全 导出需要开启命名空间
8、你在项目中的什么位置获取的用户具体资料,理由是什么。
在导航守卫得位置就已经有token了,在这里获取用户自恋更好 因为导航守卫在页面发生跳转事触发,这时候无论从何时何地进来,如果发现你没获取资料,都可以非常直观的获取资料。 判断条件也是的不会发生重复的加载
9、你在生产环境和开发环境都是如何解决跨域问题的。
生产环境:配置nginx等HTTP服务器来解决跨域请求的问题 在nginx配置文件中加入 location /api/ { proxy_pass http://localhost:3000/api/; add_header 'Access-Control-Allow-Origin' '*'; } 配置
开发环境:代理api 可以通过devServer: { port: port, open: true, overlay: { warnings: false, errors: true }, proxy: { '/api': { target: 'heimahr.itheima.net' } } // before: require('./mock/mock-server.js') },来进行配置 需要注释掉before这个选项 这个是mock数据,会影响到我们的请求,修改之后一定要重启服务 JSONP协议
10、你在项目中用到axios了吗,你是如何进行的封装。
用到了 首先安装axios包 配置基地址 在请求拦截器中-统一注入token 在响应拦截器中-结构数据-处理异常
11、你在项目中的组件分成哪几个等级,是如何区分的
通用性组件 通用性组件放在src下的layout里的components 自定义组件 自定义组件放在src下的views里面
12、你的项目中token是存储在什么位置,你又是如何解决token失效的。
存在cookie中 在响应拦截器中做判断如果登录时后台数据是401 前端就提示用户登录过期 跳回登录页
13、你的行内编辑功能是如何实现的。
每一行数据自定义一个编辑标记
为了使数据具有响应式特点
使用vuex中的方法 this.$set(目标对象,属性名称,初始值)
点击编辑按钮时候 将标记变为true显示行内编辑
使用作用域插槽 进行页面渲染
14、请说明项目中左侧的菜单的渲染过程。
左侧菜单断数据来源于路由模块的信息 根据路由信息的hidden属性俩判断是否显示该路由到菜单 在sidebar中的计算属性中引入路由 渲染路由信息 遍历路由生成sidebar-item 组件根据条件渲染传递图标和表题给组件 item接收icon和title属性,使用函数型组件完成渲染
15、项目中的树形结构你是如何实现的。
列表转树形
导入封装的函数方法
传两个参数 第一个参数是声明的数组
第二个参数是传入的根植id 起始值是0
遍历数组
进行判断入股哦数组中的每一项的pid等于数组中每一项的id
那么pid就是id的子节点
利用递归 自身调用自身
将子节点赋值给当前节点
然后将拿到的这一项添加到声明的空数组中
16、实际开发场景中有用过变量吗?
在实际开发中,使用变量是必不可少的。变量可以用来存储数据,并在程序中进行读取和修改,以实现各种功能,例如我们需要在代码中频繁使用某个点数值时,可以将这个数值定义为变量,这样可以方便地在程序中修改该数值 另外,变量还可以用来传递数据,比如函数中的参数就是通过变量来传递到的。在处理大量数据时候,变量地使用页得场重要,可以通过定义不同的变量来存储和处理不同的数据。
17、怎么根据token的有无去控制路由的跳转?
在路由前置守卫中使用beforeEach钩子函数,在路由切换之前判断token的有无进行判断
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) => {
const token = sessionStorage.getItem('token'); // 获取存储在SessionStorage中的token
if (to.meta.requiresAuth && !token) { // 如果访问需要授权的路由但没有token
next('/login'); // 跳转到登录页
} else { // 否则
next(); // 继续访问路由
}
});
18、在工作中有对服务端返回的数据进行过二次处理吗?
1.对数据格式的转换:后端返回数据格式和前端返回需要格式不符,需要进行转换,比如时间戳转换为日期字符串,将对象数组转换为简单的数组等等 2.数据过滤:对后端返回数据进行过滤,前端只要需要的数据,提高页面加载速度,减少不必要的数据宽带 3.数据缓存:对于一些经常访问的数据,可以对服务端返回的数据进项缓存,减少服务器压力,提高页面响应速度 4.数据加工:在一些特定场景中。服务端返回的数据不能满足前端的需求,需要进行额外的数据加工,以实现某些功能或满足欧谢特定要求 这个项目中就将后端返回的列表数据结构转换成树形结构
19、关于项目中excel的导出实现步骤请简要描述一下。
首先安装file-saver 在员工页面引入 点击导出按钮使用file-saver将blob转化成文件下载 excel导出首先axios配置respobseType为blob接收二进制流文件为blob格式 在响应拦截器进行判断返回的是不是blob类型,如果是blob类型直接返回数据不再进行解构
20、有封装过组件吗?请介绍一下你封装过的组件。
项目中有多次用到组件封装 例如:级联组件、弹窗组件 级联组件 首先新建一个存放级联组件的vue文件 通过elementui文档确认将Cascader级联选择器为实现这个组主要结构 该组件有三个属性:options-绑定的数据 separator-自定义数据之间间隔的符号 props-自定义绑定的数据属性 使用步骤:从接口获取数据,将列表数据转化成树形数据;此组件使用的是 value label,而后端返回的数据是id和name,所以需要通过props重置属性为:id和name;将数据赋值给options绑定的数据
21、有封装过v-model相关的双向绑定组件吗?
在级联组件中使用v-model双向绑定 在props中value属性用来存储数据
export default {
props: {
value: {
// 存储的是部门的id
type: Number,
default: null
}
}
}
在联级组件上接收改变触发input事件
<el-cascader
:value="value"
size="mini"
:options="treeData"
:props="props"
separator="-"
@change="changeValue"
/>
changeValue(list) {
// 取到数组的最后一次
if (list.length > 0) {
this.$emit('input', list[list.length - 1]) // 将最后一位的id取出来 传出去
} else {
this.$emit('input', null) // 如果长度为0 说明值为空
}
}
在父组件上使用v-model双绑
<select-tree v-model="userInfo.departmentId" class="inputW" />
23、你的这个项目中vuex是如何划分模块的?
用户模块:负责管理用户的身份信息、登录状态等 主页模块:负责管理主页的相关状态和逻辑,主页的内容、导航菜单、可视化图表等 角色模块:负责管理用户角色的相关状态和逻辑 比如不同角色对应的权限、角色的创建和管理等 员工模块:负责管理员工的相关状态和逻辑,比如员工列表。员工详情。员工创建、编辑。删除等。
24、请说一下项目中左树右表的实现思路以及二者是如何实现联动的。
左树 使用到ei-tree组件,将后端提供的列表数据使用递归转化成树形结构,初始化一级pid高亮 首先初始化部门的id,使用elementui里面的setCurrentPage和node-key方法实现,因为是异步操作所以需要使用$nextTick方法
右表: 首先将当前页码设置为1 将当前行的员工id赋值给初始化记录部门的id通过这个id获取相应员工数据并渲染表格
联动效果:
- 给左侧的数据注册点击事件
- 将当前页码设置为1
- 通过点击事件可以获取到当前部门的ID,并将当前部门的id赋值给queryParams.departmentId
- 重新渲染列表数据
25、针对模糊搜索你是如何进行优化的。
在模糊搜索时会向后端请求数据,为了减少想能浪费,进行防抖处理,设置定时器 在每次处触发事件的时候清空上一次定时器开启新的定时器。在停止触发时候,定时器结束,再向后端请求数据
26、新增、编辑员工公用一个组件,如何区分并实现对应的功能。
为新增和编辑员工是指同一个点击事件名,通过传递不同参数进行区分 例如:新增参数为1 编辑参数为2
27、如何根据权限筛选出动态路由。
首先从后端获取包含用户访问权的数据 然后导入全部路由信息 通过filter和include方法筛序拿出能访问的路由信息
28、项目中按钮标识权限如何分配。
给员工分配角色 给角色分权限 首先我们将路由拆分为静态路由和动态路由,静态路由是在没有权限的情况下都能访问 动态路由只能在员工拥有相应的权限才能访问
29、你的项目中为什么要将路由拆分成动态路由和静态路由。
为了实现权限管理,静态路由为公共路由所有用户都可以访问,动态路由需要根据用户的权限来进行规定
30、项目中是否用过自定义指令,你是如何实现的。
通过给按钮添加相应的标识,然后我们在main.js里面编写一个全局自定义指令,通过在自定义指令里面获取当前员工包含操作权限的数据point与操作按钮的标识进行对比若返回true即说明此员工有操作权限,否则没有
31、vue-router中路由模式你用的哪一种,有什么区别。
在开发途中使用hash模式,带#地址的变化不会引起页面的刷新,因为它兼容所有的浏览器和服务器,是最安全的模式。hash值变化浏览器不会重新发起请求,但是会触发window.hashChange事件,假如我们在hashChange事件中获取当前的hash值,并根据hash值来修改页面内容,则达到了前端路由的目的。 history:没有#,地址变化会引起页面刷新,更符合页面地址的规范(开发环境不刷新—webpack配置),它包括back/forward/go三个方法,对应浏览器的前进、后退、跳转操作。 abstrat:在已存在的路由页面中内嵌其他的路由页面,而保持在浏览器当中依旧显示当前页面的路由path,这就利用到了abstract这种与浏览器分离的路由模式。
32、项目上线前你都做了哪些工作。
将路由模式修改为history模式 npm run preview -- --report --打包分析 将大的包排除,使用CDN外链引入 使用nignx打包,解决404与跨域问题