目录
一、vue2和vue3的区别?
二、vue2的下拉框的key值被push改变后会发生什么事情?
三、路由的钩子函数(路由的api)?
四、介绍vuex,说说每一个模块的功能?
五、vuex的持久化存储怎么做,原理是什么?
六、怎么实现token的持久化?
七、说说对promise的理解?
八、小程序的底部tabbar怎么配置,最多有几个,为什么最多有五个?
九、自定义的tabbar,组件库的tabbar和微信自带的有什么区别?
十、es6新增,了解过asycn和await吗?
十一、说说var,const,let区别?
十二、age=18;console.log(age)的结果? 18
十三、age=18;let age;console.log(age)的结果? 、
十四、this的指向问题?
十五、typeof(NaN),typeof(arr)结果?
十六、undefined和null 的区别?
十七、一个字段前端需要使用,但后端返回结果却没有,后端没办法增加这个字段,前端怎么办?
十八、js中isNaN和Number.isNaN的区别?
一、讲一下Hooks ?
二、关于虚拟dom?
三、useMemo和useCallback?
四、后端相关逻辑 有没有接触过?
五、useeffect 模拟哪些生命周期函数 ?
六、react和vue的dom渲染机制?
七、项目难点,亮点?
八、如何控制权限菜单不可见?
九、父子组件间参数传输?
十、接口跨域产生的条件【违背同源策略】?
十一、使用过TS没?
十二、如何设计一个登录的逻辑?
十三、浏览器持久化存储?
十四、flex布局?
十五、使用过 ant design Pro吗?
十六、一万条数据如何展示不会造成卡顿 ?如何优化?
十七、虚拟列表【Vue长列表优化】接触过没?
十八、移动端如何适配异形屏 ?env 环境变量?
十九、SEO优化【搜索引擎优化】有什么见解?
二十、了解服务端渲染 ssr sso?
/*=============华帝创新============*/1.js的几个定位
2.js中属性消失的方法
3.vue中通信方式
4.父子通信中子组件能修改父组件传递过来的数据吗?为什么?
5.如果我在vue中想要获取节点,怎么获取?
6.watch和computed的区别
7.箭头函数?
8.jquery中的事件绑定除了on以外还有什么可以作为事件绑定
9.js的数据类型有哪些
10.讲一下深浅拷贝
11.讲一下事件冒泡,冒泡排序
12.讲一下递归,递归的应用场景
13.讲一下vue中如何使用递归
14.vue中的传值有哪些
15.父组件如何调用子组件方法
16.子组件如何调用父组件方法
17.vue中的路由模式有哪些
18.说一下hash,和history的区别
19.vue router有那些方法
20.讲一下请求拦截器和相应拦截器,以及应用场景
25.讲一下element ui中layout布局怎么做
27.讲一下token
28.react中如何实现vue中watch的监听
1.介绍一下vue和react的生命周期
2.react组件通信方式
3.你封装过哪些组件
4.监听和深度监听的区别
5.场景:echarts想要实现曲线图断开(中间有的没值,实现曲线断开效果)
6.场景:前端设置请求超时时间(已经知道一个接口请求时间比较长,如何修改默认请求时间)比如数据量比较大,导出的时候时间比较长,将默认请求时间延长?
7.你认为原生和vue或react的区别是什么
1:声明式是什么意思?
2:组件化是什么意思?
3:如何理解React的单向数据流?
4.你的理解原生是单线程还是多线程【多线程】
5.那vue是单线程还是多线程
10.vue双向数据绑定原理
11.computed哪些场景下使用
12.v-if v-show区别,怎么使用的
13.v-if怎么就造成内存泄露了
14.diff算法原理
15.如果一个dom元素有100个什么什么忘了,如何快速找到改变的那一个
16.软件开发和硬件开发
17.怎么实现token的持久化
18.组件库组件的二次封装
1、mvvm和jq的区别
2、jquery中odd
3、window. onload作用
4、window .onload和vue中哪个api比较像
5、created和mounted的区别
6、讲讲Vue. nextTick
7、数组方法
8、垂直居中的方法
1.闭包,你用过没,怎么用的
2.watch和computed的区别 computed怎么传参的有什么特征
3.http与https的区别?
4.http的请求状态有哪些?
5.css怎么画一条0.5像素的线?
6.felx布局的优缺点?
7.css的优先级?
8.c3新增的属性选择器和伪类选择器?
9.伪类选择器和属性选择器的权重?
10.怎么让一个盒子中的图片水平垂直居中?
11.css预处理语言?
12.js的事件委托?
13.事件流?三个阶段?
14.new了一个person/创建一个对象都在内存中做了什么事情?
15.闭包?垃圾回收怎么处理?——标记清除,引用计数法
16.浏览器上怎么实现跨域?
17.promise对象返回一个异常,怎么去处理这个异常?
18.vue在实例化的时候做了什么事——new Vue实例化对象时会做哪些事?
19.项目中权限管理是怎么做的?如何让不同的用户访问的页面不同
1.清除浮动方法
2.怎么提交表单,有几种方法
3.apply和call的区别
4.怎么进行性能优化
5.怎么控制元素的显示隐藏,有哪几种方法
6.回调地狱是什么
回答:
1.双向数据绑定原理不同
2.vue3默认进行懒观察(lazy observation)
3.Vue3 对ts的支持更好
4.项目目录结构发生了变化
5.更精准的变更通知
6.vue3.0组件属性方式变成CompositionAPI(组合式)函数式风格。
7.ref、computed、watch、生命周期、过滤器、插槽slot、组件、组件传值、路由模式、路由导航、动态路由匹配等方面语法不同
更详细的说明见xmind的私人笔记
回答:用this.$router.push根据不同key值可以跳转至不同页面
最近遇到一个问题,当我想在一个下拉框中选值时,另一个下拉框的值清空。可vue有个v-model属性,当我清空另一个下拉框v-model的值为空,就会再一次出发下拉框的@change事件,这样就会导致两个下拉框的值都为空,再次选择下拉框,里面的值才会出来,用户体验非常不好。
当我在JS中将v-model里的值置为空时,会接着调用change方法,这样就会接着将里面两个内容都清空。 再加一个参数为判断条件时,这样的问题就会避免。
回答:
全局前置守卫 router.beforeEach
全局解析守卫 router.beforeResolve
全局后置钩子 router.afterEach
路由独享的守卫 beforeEnter
组件内的守卫 beforeRouteEnter beforeRouteUpdate beforeRouteLeave
回答:
概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态
功能:
state : 数据存储状态,
mutations : 修改状态,唯一可以修改state数据的场所
actions : 可以包含异步操作,
getters : 计算属性,类似于vue组件中的计算属性,可对state中的数据进行计算(会被缓存)
modules : 模块化管理store(仓库),每个模块拥有自己的 state、mutation、action、getters
回答:
因为vuex本质上是一个公共变量,存储于浏览器内存中,刷新页面,浏览器内存重置,清空数据
持久化存储:
方式一:vue-persist插件
先安装npm install vue-persist -D,再在store/index.js中引入
方式二:首先要保证vuex中的数据在修改之前,先保存在localStorage或者sessionStorage中
其次需要异步更新vuex中的同步任务,来达到更新state 中的值,使得vuex中的数据不因为浏览器的刷新而丢失
回答:
在对token进行初始化的时候先从本地取一下,优先使用本地取到的值
在设置token的时候除了在vuex中存一份,在本地也同步存一份
在删除token的时候除了把vuex中的删除掉,把本地的也一并删除
回答:
promise作用:解决异步编程
...两个特点:(1)Promise对象的状态【pending 初始状态、fulfilled 成功状态、rejected 失败状态】不受外界影响
(2)状态一旦改变,就不会再变:只能由 pending变成fulfilled或者由pending变成rejected
...用法:Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
它们是两个函数,由 JavaScript 引擎提供,不用自己部署
...语法:const promise=newPromise(function(resolve,reject){// ... some codeif(/* 异步操作成功 */){resolve(value);}else{reject(error);}});
...三种方法:第一种: then表示异步成功执行后的数据状态变为resolve;
第二种: catch表示异步失败后执行的数据状态变为reject;
第三种: all表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。
...all&race:Promise.all场景:一个页面需要同时发送多个请求,等待所有请求结束时,统一接收响应.[一起获取]
Promise.race场景:获取同样的数据,有N个服务器,可以一次发多个请求,谁快获得谁的响应.[打印快的]
回答:未学
回答:未学
回答:
async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成
详细回答:
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。
因此对async函数可以直接then,返回值就是then方法传入的函数
await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待
回答:
相同点:都是用来修饰变量的
区别:(1)var具备声明提升;
(2)let定义的变量必须“先定义后使用”;
在同一作用域下,let修饰的变量“不能重复定义”;
暂时性死区【当内部变量与外部变量同名时,内部变量屏蔽外部变量】;
块级作用域【在当前作用域内的数值不会消失】;
(3)const修饰的变量称为只读变量;必须初始化;其他4个特性同let;
报错【在初始化之前无法访问‘ age’】
回答:
① 在普通函数/定时器中,this指向window
② ...构造函数中,...创建的对象
③ ...方法声明中,...调用者
⑤ ...事件中,...事件源
typeOf is not defined
如果是console.log(xxx)的话===========》number undefined
回答:
1.数据类型不一样【null和undefined 两者相等,但是当两者做全等比较时,两者又不等】
示例: console.log(typeof null) // object
console.log(typeof undefined) // undefined
2.转化成数字的值不同【Number(null) //0 Number(undefined) //NaN】
4.null代表"空",代表空指针;undefined是定义了没有赋值
回答:
把查询数据的方法放在method。再通过mounted里面调用这个method的方式就可以解决了
回答:
isNaN只是判断传入的参数是否能转换成数字,并不是严格的判断是否等于NaN
Number.isNaN判断传入的参数是否严格等(===)NaN,并且不存在类型转换的行为
二十、多个表格数据要通过一个表格组件呈现,这个数据怎么处理配置?怎么促成组件的强制更新?
回答:
表格组件的属性:data
组件的强制更新:
不妥的方式:使用 v-if
较好的方法:使用Vue的内置forceUpdate方法
最好的方法:在组件上进行 key 更改
/*==================顺丰科技一&二面试题===================*/
回答:
Hooks是React的一个新功能,更好地体现了React的开发思想,即从State => View的函数式映射。解决了Class组件存在的一些代码冗余、难以逻辑复用的问题。
useState:管理当前本地的状态
useRef:让函数组件使用ref
useEffect:让函数组件使用生命周期
useContext:直接获取到context对象的Consumer消费者中的数据
useCallback
useReducer:对一个state有多次修改时,就使用useReducer来对其内容进行简化
回答:用普通js对象来描述DOM结构
作用:
可以维护视图和状态之间的关系、复杂视图情况下提升渲染性能
虚拟DOM除了可以渲染成DOM节点,还可以渲染到其他平台如ssr(nuxt.js/next.js)、原生应用(weex/rn)、小程序等,增加了跨平台能力
回答:
useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;
并且这两个hooks都返回缓存的值,useMemo返回缓存的变量,useCallback返回缓存的函数。
回答:不确定
回答:【componentDidMount、componentDidUpdate、componentWillUnmount】
回答:
1、React是通过JSX渲染模板;而Vue是通过一种拓展的HTML语法进行渲染。
2、Vue在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树;
而React在应用的状态被改变时,全部子组件都会重新渲染。
回答:依据个人情况回答
回答:
采用树形菜单,所有的菜单项都存储在一个表中,便于分级授权
回答:
正向传值、逆向传值【2.0&3.0】
回答:
跨域解决方法:
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
回答:JS的超集
回答:
用户输入账户、验证码
然后登录,请求后台接口,服务端验证账户和验证码
验证通过生成一个唯一标识token保存至cookie并将登录成功的信息存储到本地(localStorage)中
访问需要登录状态显示为登录后才可以访问的页面,检测token的登录状态,来决定是否可以访问页面如果cookie过期,则清除本地存储的用户信息,让用户跳转到登录页面重新登录
回答:
localStorage、SessionStorage
回答:
设为Flex布局【父元素设为display:flex】以后,子元素的float、clear和vertical-align属性将失效
flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content【容器的6个属性】
回答:
Ant Design是阿里蚂蚁金服团队基于React开发的ui组件,主要用于中后台系统的使用;
Ant Design Pro 是基于Ant Design的一个开箱即用的,企业级中后台前端/设计解决方案
使用:
第一步:将ant-design-pro-master.zip解压到任意目录
第二步,导入项目到Idea中
第三步:进行初始化以及启动:
tyarn install #安装相关依赖
tyarn start #启动服务
回答:
一般后端会进行分页处理再发送接口,否则得前端分页+setTimeout===>使用window.requestAnimationFrame
代替setTimeout减少重排次数,极大地提高了性能===》借助文档碎片DocumentFragments进行极致优化
回答:
虚拟列表就是固定dom节点数量,通过修改dom节点的内容二达到不重新增加(或删除)dom节点来实现列表的更新
实现原理:
1.监听页面滚动,获取滚动的高度scrollTop;
2.根据scrollTop可以知道当前应该展示哪段数据(获取展示数据的index);
3.根据当前展示的数据在长列表中的index,对列表进行偏移
回答:
原理如下 :
动态修改html的fontsize的大小,页面元素在设置尺寸时候,以rem为单位,在不同尺寸下就可以实现页面元素宽度等具有动态变化的效果
方案一: 根据设计稿宽度算出来html字体的大小,并且以vw作为单位
方案二:通过js动态的获取屏幕的宽度,然后自计算底层字体的大小,并修改字体.原理与方案一相同
方案三:通过CSS的用法(媒体查询)【@media screen and (min-width: 360px) {html{font-size:56.25px;}}】
回答:
在了解搜索引擎自然排名机制的基础上,对网站进行内部及外部的调整优化,
改进网站在搜索引擎中的关键词自然排名,获得更多流量,从而达成网站销售及品牌建设的预期目标。
回答:
服务端渲染:
将组件或页面通过服务器生成html字符串,再发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序
SSR优势:
1. 更利于SEO
2. 更利于首屏渲染
SSR劣势:
1.服务端压力较大
2.开发条件受限
3.学习成本相对较高
单点登录(SSO):
在多个系统中,用户只需一次登录,各个系统即可感知该用户已经登录
本质就是在多个应用系统中共享登录状态,如果用户的登录状态是记录在 Session 中的,
要实现共享登录状态,就要先共享 Session。
所以实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享
scrollHeight: 获取对象的滚动高度。
scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth:获取对象的滚动宽度
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
event.clientX 相对文档的水平座标
event.clientY 相对文档的垂直座标
event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标
document.documentElement.scrollTop 垂直方向滚动的值
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量
①delete delete 对象.属性名
②es6之解构赋值
③es6之反射 语法Reflect.deleteProperty(对象,属性名)
正传、逆传、同胞、传跨层级传
vuex可以跨层级进行修改操作
①通过事件源获取
②通过ref获取
③通过自定义指令获取
计算属性 : 计算属性是依赖data的数据 当data的数据改变之后 计算属性会重新计算返回一个新的结果
watch: watch是监听data的数据 当data的数据改变之后 watch会调用一个回调函数完成一些特定的逻辑
计算属性是同步的 watch是异步的
定义:ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义
特点:①如果形参只有一个,则小括号可以省略;
②函数体如果只有一条语句,则花括号可以省略,并省略return,函数的返回值为该条语句的执行结果;
③箭头函数 this 指向声明时所在作用域下 this 的值;
④箭头函数不能作为构造函数实例化;
⑤不能使用 arguments
JQuery绑定事件有4种方式,分别为:bind()、live()、delegate()和on()方法;
其中bind()方法只能针对已经存在的元素进行事件的绑定,而live()、on()、delegate()均支持未来新添加元素的事件绑定。
基本数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)。
引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function)。
特殊的对象:正则(RegExp)和日期(Date)。
特殊类型:underfined 未定义、Null 空对象、Infinate 无穷、NAN 非数字
深拷贝和浅拷贝只针对于引用类型
浅拷贝:只拷贝地址,但并不开辟空间,两个对象共享同一空间,其中一个改变了数值,另一个
也会被修改。
深拷贝:开辟空间且赋值,两个对象都有独立的空间,被拷贝的对象,只是和原对象数值相同
事件冒泡:开始时由最具体的元素接受,然后逐级向上传播到DOM最顶层节点
冒泡排序:每次从当前序列中两两元素比较并且必要时交互两个元素的位置来实现将当前序列中最大或最小的元素“浮”到序列末端。
以此类推是递归的基本思想,具体来讲就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。
Vue组件是天然支持递归使用的,只需要在引用自己时使用跟该组件name相同的tag就行了
正传、逆传、同胞、传跨层级传
①通过ref直接调用子组件的方法
②通过组件的$emit、$on方法;
①直接在子组件中通过this.$parent.event来调用父组件的方法
②在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了
hash、history
hash
是vue路由的默认路由模式 如果你不指定 那么就是hash模式
url带#号 上线之后刷新不会丢失 浏览器兼容性好
history
url不带#号 上线之后刷新会丢失(需要让你们后端服务器人员给你配置服务器的重定向) 浏览器兼容性一般
router-link标签
router.push()
router.replace()
router.go()
请求拦截器 在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;
响应拦截器 同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。
页面发送http请求,很多情况我们要对请求和其响应进行特定的处理;例如每个请求都附带后端返回的token,拿到response之前loading动画的展示等。如果请求数非常多,这样处理起来会非常的麻烦,程序的优雅性也会大打折扣。在这种情况下,建议使用拦截器
通过基础的 24 分栏,迅速简便地创建布局。
通过 row 和 col 组件,并通过 col 组件的 span 属性我们就可以自由地组合布局。
见面试题图片
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。
我自己理解的token是一个身份卡,有权限的作用。
在react中实现监听效果有一个比较简单的方法,就是使用useEffect 这个hook,在我们刚接触这个hook时经常会被代入到类组件中的生命周期上,其实它不光有生命周期的功能更是可以实现监听的效果。
======================北斗天地一面==================================
介绍一下自己和工作经历
介绍你的项目
项目的流程,工作流
逮着项目问中间穿插技术点的问
生命周期就是实例从创建到销毁的过程。
vue2: vue3:
**实例创建**实例创建之前-----beforeCreate setup
实例创建之后-----created setup
**模板渲染**
模板渲染之前-----beforeMount onBeforeMount
模板渲染之后-----mounted onMounted
**数据更新**
数据更新之前-----beforeUpdate onBeforeUpdate
数据更新之后-----updated onUpdated
**实例销毁**
实例销毁之前-----beforeDestory onBeforeUnMount
实例销毁之后-----destoryed onUnMounted
React
旧:
挂载阶段
constructor(初始化) -----componentWillMount(组件即将渲染)----------render(组件渲染虚拟DOM)---------componentDidMount(虚拟DOM已挂载到页面成为真实DOM)
更新阶段
1.setState修改
shouldComponentUpdate(判断是否重新渲染组件,通常会返回布尔值ture或 false ture会继续向下执行而false则直接结束)------componentWillUpdate(即将更新组件)------render------componentDidUpdate(更新组件完成)
2.父组件更新
componentWillReceiveProps(接到新的属性值)-----shouldComponentUpdate-----componentWillUpdate----render-----componentDidUpdate
3.强制更新forceUpdate
componentWillUpdate----render-----componentDidUpdate
销毁阶段
componentWillUnMount
新:
挂载阶段
constructor(初始化)--------componentDidMount
更新阶段
1.setState修改
shouldComponentUpdate----getsnapshotBeforeUpdate(prevprops,prevstate)-----render------componentDidUpdate
2.父组件更新
getDerivedStateFromprops(nextprops,prevstate)------shouldComponentUpdate----getsnapshotBeforeUpdate(prevprops,prevstate)-----render------componentDidUpdate
3.强制更新forceUpdate
getsnapshotBeforeUpdate(prevprops,prevstate)-----render------componentDidUpdate
销毁阶段
componentWillUnMount
组件传值组件默认是一个完整独立的个体。组件与组件之间的数据默认是不能相互使用的
正向传值--props
类组件:this.props.xxx
函数组件:把props当成形参传入,用props.xxx
逆向传值--使用props接收的是一个函数同胞传值Pubsub-js
react中默认是不能进行同胞传值的 如果我们要进行 那么必须依赖 pubsub-js
1.npm install --save pubsub-js
2.抛出 在需要传递的组件中使用 Pubsub.publish(“自定义事件名”,"数据") publish创建自定义事件
3.接收 在需要接收数据的组件中使用Pubsub.subscribe("你监听的事件",()=>{})subscribe 监听自定义事件
状态提升--中间人模式
将多个组件需要共享的状态提升到它们最近的父组件上.在父组件上改变这个状态然后通过props分发给子组件跨组件传值
1.context对象--上下文对象
context很好的解决了跨组件传值的复杂度,可以快速的进行跨组件数据的传递。
createContext()方法中给我们提供了两个对象:
Provider对象 生产者---->用来生产数据
Consumer对象 消费者---->用来使用数据
2.redux
redux就是一个javascript的状态管理工具 可以集中的管理react中多个组件的状态 让我们组件之间数据传递变得非常的简单
redux的三大原则
1.单一数据源 :整个项目的数据都被存储在一个store对象中
2.state是只读的:如果我们想改变state的数据 那么必须触发action里面的修改动作来执行修改
3.使用纯函数来进行修改:reducer就是一个函数 我们通过reducer中的state和action动作来进行数据的修改
读取redux中的数据store.getState().你要读取的数据
基本数据修改我们需要通过dispatch()来调用写在action中的修改动
使用subscribe() 监听redux state的状态 改变就会触发进行重新渲染
合并reducer(把redux拆分成一个个的模块)
分成模块化之后读取数据需要夹上模块名如:store.getState().模块名.xxxx
react-redux 就可以简化我们在react中使用redux的复杂度
我用vue开发的所有项目,都是采用组件化的思想开发的。
vue组件封装的优点
组件是Vue.js最强大的功能之一,组件可以扩展HTML元素。封装可复用的代码组件是一个可复用的Vue实例
组件可以提高项目整体的开发效率。 可以将页面抽象为多个相对独立的模块,解决了效率低下、维护难度大、复用性低等传统项目开发问题。
监听watch当数据变了watch就会触发 从而调用函数处理一些逻辑
语法:写在与el data methods 同级位置
watch:{
你要监听的data数据(newval,oldval){
}
}
deep就是深度监听使用之后它会把对象中的**所有属性都监听到**不管你用不用 反正都会给你监听**但是这样性能开销就会非常大了,我们可以是使用字符串形式监听*
在vue2中watch默认是无法监听到对象中的属性 必须手动开启deep深度监听
在vue3中强制开启deep深度监听,watch在监听基本类型和复杂类型的时候语法有所不同,基本数据监听和vue2中一样只是语法不一样;监听复杂类型默认开启deep如果直接监听复杂数据会出现问题问题:数据改变了,但是监听函数中的newval和oldval相同 解决方式:把第一个参数变成一个函数return我们要监听的内容即可解决,如果监听的数据的属性也是复杂类型,默认的就失效:需要手动开启第三个参数:设置deep: true
如果折线图上的数值为0会在,x轴有一段水平线,如果能将这段隐藏就达到了折线图切割的效果。
echarts中有个折线图渲染属性 visualMap, 可以利用这个属性对折线进行修饰。让被选中的区间透明就达到切割的目的了。
因为我有多条折线,在后台返回的数据后操作获取渲染区间 pieces 就可以了
全局设置网络超时:axios.defaults.timeout = 30000;
可直接在请求头上添加属性:headers: { 'ApplyNo': applyNo }
框架不同
先要说说MVC和MVVM之间的区别
1.MVC指的是Model-View-Controller,分别代表着模型层、视图层、控制器。
Model(模型层),主要管理的是业务模型的数据和处理数据的逻辑。
View(视图层)主要是接收用户的交互请求并展示数据信息给用户。
Controller(控制器层)主要担任的是Model和View之间的桥梁,用于控制程序的流程。Controller负责确保View可以访问到需要显示的Model对象的数据,View接收到用户的交互请求之后,会将请求转发给控制器,控制器解析请求之后,会交给对应的Model处理。
2.MVVM架构指的是Model-View-ViewModel,我们可以看到MVVM架构和MVC架构的区别在于有一个ViewModel部分,首先我们要知道在已经有了MVC架构的时候,为什么还要衍生出MVVM架构,这是因为View中很多控件的数据类型和Model中的属性不相同,例如Model中的时间数据可能是一串数字,View想要展示成日期的格式,这就需要一种转化,这个转换如果放在View不合适,因为View中不应该出现逻辑代码,放在Model中也不合适,这回导致Model臃肿庞大,因为这种问题的存在诞生了ViewModel,这一层可以帮助View转化为相应的数据给Model或者从Model中转化成View可以显示的内容。
核心思想不同
Vue的核心思想是尽可能的降低前端开发的门槛,是一个灵活易用的渐进式双向绑定的MVVM框架。
React的核心思想是声明式渲染和组件化、单向数据流,React既不属于MVC也不属于MVVM架构。
组件写法上不同
Vue的组件写法是通过template的单文件组件格式。
React的组件写法是JSX+inline style,也就是吧HTML和CSS全部写进JavaScript中。
Diff算法不同
Diff算法前置知识:虚拟DOM
在了解Diff算法之前,我们首先要知道什么是虚拟DOM,虚拟DOM是一个用来描述真实DOM的对象,本质是对象。
什么是Diff算法?
Diff算法是一种对比算法,主要是对比旧的虚拟DOM和新的虚拟DOM,找出发生更改的节点,并只更新这些接地那,而不更新未发生变化的节点,从而准确的更新DOM,减少操作真实DOM的次数,提高性能。
Diff算法是深度优先算法,时间复杂度是O(n)。
为什么不建议使用index作为节点的key?
假如我们在一组节点的首部添加了一个新节点,使用index作为key,diff算法通过key判断是相同类型的节点之后,会进行进一步的比较,把其内容进行更改,这样就会造成这一组的节点都被更新了,最后一个节点还被当做新节点创建了,这样会造成很大的性能浪费,因此不建议使用index作为key。
React的diff和Vue的diff算法的不同之处
vue和react的diff算法都是进行同层次的比较,主要有以下两点不同:
vue对比节点,如果节点元素类型相同,但是className不同,认为是不同类型的元素,会进行删除重建,但是react则会认为是同类型的节点,只会修改节点属性。
vue的列表比对采用的是首尾指针法,而react采用的是从左到右依次比对的方式,当一个集合只是把最后一个节点移动到了第一个,react会把前面的节点依次移动,而vue只会把最后一个节点移动到最后一个,从这点上来说vue的对比方式更加高效。
响应式原理不同
React的响应式原理
React主要是通过setState()方法来更新状态,状态更新之后,组件也会重新渲染。
Vue的响应式原理
vue会遍历data数据对象,使用Object.definedProperty()将每个属性都转换为getter和setter,每个Vue组件实例都有一个对应的watcher实例,在组件初次渲染的时候会记录组件用到了那些数据,当数据发生改变的时候,会触发setter方法,并通知所有依赖这个数据的watcher实例调用update方法去触发组件的compile渲染方法,进行渲染数据。
声明式与之相对应的是命令式,命令式指的是通过DOM操作一步步把网页变成想要的样子,而声明式则是只需要通过状态去形容最后的网页长什么样子即可。
组件化指的是尽可能的将页面拆分成一个个较小的、可以复用的组件,这样让我们的代码更加方便组织和管理,并且拓展性页更强。
React的单向数据流指的是数据主要从父节点通过props传递到子节点,如果顶层某个props改变了,React会重新渲染所有的子节点,但是单向数据流并非单向绑定,React想要从一个组件去更新另一个组件的状态,需要进行状态提升,即将状态提升到他们最近的祖先组件中,触发父组件的状态变更,从而影响另一个组件的显示。单向数据流的好处是能够保证状态改变的可追溯性,假如,父组件维护了一个状态,子组件如果能够随意更改父组件的状态,那么各组件的状态改变就会变得难以追溯。
单线程:单线程就是一个进程只有一个线程。程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
单线程:在需要串行化执行代码(不可分割)时,就不需要多线程了。比如一个代码块里面要往数据库插入三条数据,插入第二条数据时必须要等待第一条数据插入完成,插入第三条数据时必须要等待第二条数据插入完成。这种情况肯定是要使用单线程
多线程:多线程就是一个进程有多个线程。在程序执行时,所有线程会交替执行。后面的线程不用等待前面的线程处理完毕。
多线程:多线程只有需要处理并发任务,或者需要长时间等待的任务时才更有上场的意义。比如下载时,需要一边下载一边展示进度条,这时就需要开辟两个线程去处理,否则下载完毕才执行进度条逻辑代码没有意义
单线程和多线程的使用场景:因为多线程不一定比单线程快,在很多时候,都是单线程会更快一点儿。
vue是多线程
原因
A=5;--------线程1
Function(A);--------线程2(可能最快执行)导致A还是null,并没有赋值。
解决方法:就是嵌套,控制运行顺序
人事
介绍了一下公司的业务
什么时候离职的,离职原因
上家薪资,期待薪资
你对出差怎么看,家里人呢
你还有什么想问的
=====================天机算一面=========================
先用leetcode做题
在vue中基于**数据劫持==>数据代理**与**发布者订阅者模式**完成的.
数据劫持:数据拦截 就是对data中的数据在**初始化的时候**监听起来**(Object.defineProperty 来进行监听/代理)
当数据改变setter之后 vm就会知道 在视图改变getter 他就会通知模型你要修改了 模型改变了也会通知视图改变。
vue2和vue3双向数据绑定区别:
vue2是基于object.defineproperty中的set和get方法能够监听数据对象的变化,监听不到对象属性的增删,数组元素和长度的变化。只有在vue初始化的时候把所有的观察者都建立好,才能观察到数据对象属性的变化。
vue3是用proxy来替代object.defineproperty,可以做到监听对象属性的增删,数组元素和长度的修改.利用“惰性监听”不会在初始化的时候就建立所有的观察者,而是在用到的时候才去监听。
computed的使用场景是一个值受多个值影响,computed只能在当前组件使用,不能跨组件使用。
1.v-show是使用css的方式对dom元素进行显示和隐藏的 在频繁切换的时候效率更高 在初始化的时候对性能的损耗比较高
2.v-if是直接把这个dom元素移除或者是添加 在频繁切换的时候效率比较低 在初始化的时候对性能的损耗比较低
当 `v-if` 与 `v-for` **不推荐同时使用**,**`v-for` 具有比 `v-if` 更高的优先级**,这意味着 `v-if` 将分别重 复运行于每个 `v-for` 循环中,影响速度
Diff算法是一种对比算法,主要是对比旧的虚拟DOM和新的虚拟DOM,找出发生更改的节点,并只更新这些接地那,而不更新未发生变化的节点,从而准确的更新DOM,减少操作真实DOM的次数,提高性能。
深度优化,同层比较
添加唯一标识符key,可以快速准确找到要操作的dom元素
硬件开发主要是指各类芯片的开发,包括运算类,逻辑类以及存储类的产品,应用范围非常广泛。软件类包括通用类和专用类,他是以硬件为平台,实现各种功能。硬件开发主要是做电路的搭建,然后pcb板的制作做好了之后,再把驱动打上底层程序调好,而软件开发主要是做安卓类软件。或者系统之上的软件调试。
软件是一种逻辑的产品,与硬件产品有本质的区别
token 需要做持久化存储方案一 :
vuex 配合 localStorage:
token 数据一式两份存储的原因:
vuex 基于内存进行存储,速度快,但是刷新就会丢失,
localStorage 基于磁盘进行存储,存取较慢,但是刷新不会丢失
vuex 和 localStorage 结合使用就能实现 token 的持久化存储
组件封装一般是为了提高功能复用性,减少相同功能多次开发的浪费,以及保证项目整体的一致性以及规范性。 我们一般需要进行现有UI组件的二次封装。 目前UI 组件样式不能满足当前项目要求,需要对组件统一进行样式的封装改造。
==============================================================
航宇卫星一面
自我介绍
介绍项目负责模块
概念上:vue:前端js库,是一个精简的MVVM,它专注于MVVM模型的viewModel层,通过双向数据绑定把view和model层连接起来,通过对数据的操作就可以完成对页面视图的渲染;
jquery:轻量级的js库
在操作思想上: vue是使用数据驱动的方式,通过vue对象将数据和view完全分离开,对数据操作,不在引用相应的DOM对象,通过vue对象,将数据和相应的DOM对象相互绑定起来;主要是操作数据基于一种MVVM模式,jQuery是使用选择器($)选取DOM对象,并对其进行赋值、取值、事件绑定等 操作,主要是操作DOM
应用场景的区别: vue适用的场景:复杂数据操作的后台页面,表单填写页面;
jquery适用的场景:比如说一些html5的动画页面,一些需要js来操作页面样式的页面。 二者也是可以结合起来一起使用的,vue侧重数据绑定,jquery侧重样式操作, 动画效果等,则会更加高效率的完成业务
过滤器选择器中的获取奇数,此选择器匹配索引值为奇数的元素,从0开始计数。
语法结构:$(“li:odd)”).css(“color”,”green”)
此选择器一般也要和其他选择器配合使用,比如类选择器、元素选择器等等。
如果没有和其他选择器配合使用,那么默认和*选择器配合使用。$(“: odd”)等同于$(“*: odd”)
1)延迟加载。遇到该事件,先跳过该函数体,执行完页面所有代码后,再执行该事件体(大黄版本)
2)window.onload() 方法用于在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻执行某个方法。window.onload() 通常用于 元素,在页面完全载入后(包括图片、css文件等等)执行脚本代码。(网上版本)
$nextTick
created在渲染页面之前使用,通常是用来渲染页面
mounted通常是在渲染页面之后,用来操作dom节点
通常情况下使用created比较多,使用mounted相对少一些,一些情况使用mounted可能会报错。
Vue.nextTick( [callback, context] ):在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM.
为什么需要它呢?
Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop)
当中观察到数据变化的 watcher 推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。
这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOm操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。假使你设置 vm.someData = 'new value',DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环
开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。
为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。
这样回调函数在 DOM 更新完成后就会调用。在什么地方用它呢?
1、在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。
原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,
所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,
因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。
2、在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候
(譬如v-if/v-show根据字段变化显隐),这个操作都应该放进Vue.nextTick()的回调函数中。
push(新值)向数组的尾端插入一个新的元素
unshift(新值)向数组的前端插入一个新的元素
pop()删掉数组中最后一个元素
shift()删掉数组中第一-个元素
splice(删除的下标,1)从某-个下标上删除一个元素,有副作用splice(要插入的下标,0,要插入的数据)从中间插入一个元素
concat()拼接数组,返回值为合并成的新数组,原数组不会改变
join()将数组转换为字符串,参数为分隔符,原数组不会改变
reverse()颠倒数组中元素的顺序,会改变原数组
slcelstat.nd)通过开始下标和结束下标截取数组元素,原数组不会发生改变 toString()将数组转换为字符串可以被join 完美代替
sort()通过Unicode 进行排序,在原数组上排序,不生成副本
var arr=[1,5,6,1,3.4,11,2, 5]
//排序固定写法升序
arrsort(function(num1, num2) { return num1一num2:;) console.log(arr);
//排序固定写法降序
arr.sort(function(num1, num2) { return num2 - num1:}) console.log(arr);
arr.forEach(allback)遍历数组,无return 即使有return, 也不会返回任何值,并且会影响原来的数组
rrmap(callback)映射数组(遍历数组),有return 返回一个新数组。
riltl(eallack)过滤数组,返回一个满足要求的数组
1、方式一:(推荐)
先子绝父相
水平居中:left:50%;margin-left:负的自身宽度一半;
垂直居中:top:50%;margin-top:负的自身高度一半;
2、方式二:
先子绝父相
margin:auto;
left:0;right:0; top:0; bottom:0;3、absolute+transform
绝对定位
left和top:50%
transform:translate(-50%,-50%)4、table-cell
display:table-cell
vertical-align:middle
text-align:center5、margin,transform配合
margin:50% auto;
transform: translateY(-50%);
西安鲲鹏易飞无人机
用过 使用场景:防抖、节流、setTimeout、封装私有变量等等,比如原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。
比如防抖,在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。实现的关键就在于setTimeOut这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现。
(1)、computed是计算属性,依赖于data数据的,当data的数据改变之后,计算属性会重新计算返回一个新的结果
(2)、watch是监听data数据的,data数据改变之后,watch会调用一个回调函数完成一些特定的逻辑
(3)、computed支持缓存,当其依赖的属性的值发生变化时,计算属性会重新计算,反之,则使用缓存中的属性值;watch不支持缓存,当对应属性发生变化的时候,响应执行。
(4)、computed是同步的不支持异步,有异步操作时无法监听数据变化;watch支持异步操作。
(5)、computed第一次加载时就监听;watch默认第一次加载时不监听。
(6)、computed中的函数必须调用return;watch不是。
(7)、computed默认深度依赖,watch默认浅度观测
(8)、使用场景:
computed:适合做筛选,一个属性受到多个属性影响,如:购物车商品结算。
watch:适合做异步或开销较大的操作,一个数据影响多条数据,如:搜索数据。
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
1xx:信息提示(这类状态代码表示临时的响应。客户端在收到常规响应之前,应准备接收一个或多1xx 响应。)
100 继续。
101 换协议。2xx:成功(这类状态代码表明服务器成功地接受了客户端请求。)
200 确定。客户端请求已成功。
201 已创建。
202 已接受。3xx:重定向(客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同页面,或通过代理服务器重复该请求。)
301 已永久重定向。 (此请求和之后所有的请求都应该转到指定的 URI)
304 未修改。 (客户端请求的文档已在其缓存中,文档自缓存以来尚未被修改过。客户端使用文档的缓存副本,而不从服务器下载文档)
307 临时重定向。4xx:客户端错误(发生错误,客户端似乎有问题。例如,客户端请求不存在的页面,客户端未提供有效的身份验证信息。)
400 错误的请求。
401 访问被拒绝。
403 服务器拒绝请求 (可以理解为没有权限访问此网站,服务器能够收到请求但拒绝提供服务。)
404 服务器找不到请求的网页。 (例如,访问网站中不存在的页面,或者原有页面被移走或删除,则可能会出现该状态码)
405 用来访问本页面的 HTTP 谓词不被允许 (方法不被允许)
408:(请求超时) 服务器等候请求时发生超时
5xx:服务器错误(服务器由于遇到错误而不能完成该请求。)
500 内部服务器错误。
502 错误网关。
503 目前服务器无法使用,一般是因为服务器超载或停止维护。
504 网关超时。
505 HTTP 版本不受支持
1、采用meta viewport的方式(viewport只针对于移动端,只在移动端上才能看到效果)
2、采用transform: scale()的方式
transform: scale(0.5,0.5);
1、优点在于其容易上手,根据flex规则很容易达到某个布局效果。
2、缺点是浏览器兼容性比较差,只能兼容到ie9及以上。
css选择器优先级最高到最低顺序为:
1.id选择器(#myid)
2.类选择器(.myclassname)
3.标签选择器(div,h1,p)
4.子选择器(ul < li)
5.后代选择器(li a)
6.伪类选择(a:hover,li:nth-child)**最后,需要注意的是:**
!important的优先级是最高的,但出现冲突时则需比较”四位数“;
优先级相同时,则采用就近原则,选择最后出现的样式;继承得来的属性,其优先级最低。
属性选择器
标志:中括号[]
常见书写方式
1)[属性名字]====只要带有这个属性即可
2)[属性名字="属性值"]===精准查找,要求属性名和属性值必须完全一致
3)[属性名字~="值"]===模糊查找,要求属性值满足其中的一个单词即可
4)[属性名字*="值"]===更模糊查找,要求属性值满足其中的一个字即可
5)[属性名字^="值"]===要求以。。。开头
6)[属性名字$="值"]===要求以。。。结尾
伪类选择器
1)结构伪类
:first-child====找第一个
:last-child=====找最后一个
:nth-child()=====正着数
数字====写几就是找第几个
2n或者even===找偶数
2n+1或者odd===找奇数
:nth-last-child()====倒着数。
2)目标伪类
:target
必须结合锚点一起使用
谁被激活了就可以做一些。。。事情
3)否定伪类
:not(你要否定的标签)
4)动态伪类
:link
:visitied
:hover
:active
:focus=====焦点
5)UI状态伪类
:enabeld=====可用状态
:disalbled====禁用状态
:checked===默认选中状态
::section====实现鼠标滑过一段文字后的高量效果
属性选择器和伪类选择器权重都是10,
1、line-height和text-align:center实现图片的水平垂直居中
2、display:table和display:table-cell实现图片水平垂直居中
3、position实现图片水平垂直居中
4、背景background实现图片水平垂直居中
利用background:urlno-repeatcentercenter实现图片的水平垂直居中
预编译语言主要包含:sass、less和stylus。
stylus是一种新型语言,主要用来给Node项目进行Css预处理支持。
事件委托正是利用事件流的冒泡特性,将本来要绑定到多个元素的事件函数,委托到了其祖先元素上。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
DOM事件流分为三个阶段,分别为:
捕获阶段:事件从Document节点自上而下向目标节点传播的阶段;
目标阶段:真正的目标节点正在处理事件的阶段;
冒泡阶段:事件从目标节点自上而下向Document节点传播的阶段。
1:先将硬盘上指定位置的Person.class文件加载进内存。
2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
5:对空间中的属性进行显示初始化。
6:进行实体的构造代码块初始化。
7:调用该实体对应的构造函数,进行构造函数初始化。()
8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)
闭包的概念:函数嵌套函数,被嵌套的函数称为闭包函数。
闭包的作用:可以在函数外部使用函数的局部变量。
闭包实现的步骤: 主函数定义局部变量,嵌套定义子函数。 子函数中使用主函数的局部变量,主函数将子函数作为返回值, 在外部通过一个全局变量,绑定主函数的返回值, 从而将子函数和子函数中使用的局部变量变为全局生命周期, 这样就可以在主函数外界使用局部变量了。
闭包的缺陷: 大量使用闭包,打破了垃圾回收机制,延长了局部变量的生命周期,可能会造成内存泄露。
垃圾回收怎么处理?
引用计数
标记清除
标记整理
分代回收
3.1、设置document.domain
因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie。(此方案仅限主域相同,子域不同的跨域应用场景。)
3.2、window.postMessage()
页面和其打开的新窗口的数据传递、多窗口之间消息传递、页面与嵌套的iframe消息传递,上面三个场景的跨域数据传递
3.3、JSONP
3.4、CORS
3.5 webpack本地代理
3.6、websocket
3.7、Nginx反向代理
解决 Promise 异常捕获
Promise 异常是最常见的异步异常,其内部的错误基本都是被包装成了 Promise 对象后进行传递,所以解决 Promise 异常捕获整体思路有两个:
1、使用 Promise 的 catch 方法内部消化;
2、使用 async 和 await 将异步错误转同步错误再由 try catch 捕获;
在new Vue实例化对象的时候,主要执行了_init这个初始化的方法
而_init这个初始化的方法是在调用initMixin函数时给Vue.prototype加的方法
那么_init做了什么也就是new Vue实例化对象会做什么那么_init()函数做了什么呢?
0.给vm加上$options配置
1.初始化生命周期
2.初始化事件
3.初始化渲染
4.调用callHook函数去执行beforeCreate这个钩子函数
5.初始化initInjections
6.初始化状态 也就是初始化data,computer,watch等等这些
7.初始化initProvide方法
8.调用callHook函数触发create钩子函数
权限管理主要思想就是采用RBAC(Role-Based Access Control)的设计方法。
在我们的项目中使用的是基本的5张表设计方法,包括(用户表,用户角色关系表,角色表,角色权限关系表,权限表)
1、用户表:包含用户的基本信息
2、角色表:包含该角色具有的基本信息
3、用户角色表:包含用户和角色的基本关系,一般由管理员分配
4、权限表:主要包含具体可以操作的权限内容
5、权限角色关系表:主要包含角色和权限的关系,一般也是由管理员分配如何让不同的用户访问的页面不同
不同的权限用户登陆之后,会获取属于当前角色的权限菜单,然后使用循环将菜单渲染到导航部分。导航菜单获取之后,使用addroutes动态的添加路由规则
27.一个三行三列的表格?怎么取到第二行第二列的内容
多维数组
=====================西安启望计算机系统公司===================
方式一:overflow:hidden;
好处:简单
缺点:会把超出的元素隐藏掉(万一里面有超出父元素的元素,这个元素会被隐藏掉)
方式二:隔墙法
(在所有浮动元素的最后面创建一个空的div标签,在里面写一个行内样式:clear:both;)优点:简单
缺陷:创建了不必要的空标签,造成html代码冗余
方式三:万能清除法(推荐)
.clear-fix::after {
content: "";
display: block;
width:0;
height: 0;
overflow: hidden;
visibility: hidden;
clear: both;
}
用法:哪个盒子塌陷了,就给哪个盒子上面写这个类名即可。
注意:这个类名是自己随意起的,你要想改是可以自行更改的。
使用from表单的属性method提交,一般为post和get
相同点:它们都是用来改变函数对象的this指向
不同点:apply,call第二个参数不同,apply为数组,call单独写出
一、v-if和v-show区分使用场景
二、computed和method区分使用场景
三、v-for遍历必须为item添加key值,且避免同时是用v-if.
四、长列表性能优化
五、图片资源懒加载
v-if和v-show
回调函数中嵌套回调函数的情况就叫做回调地狱。
如何解决回调地狱
1、Promise
1、async/await