简单介绍一下做个的项目(项目介绍,自己做了哪些功能)
民族影城这个项目是民族影城官方提供的订票App.用户可以查看影城的排片信息,以及电影的详细信息等等。
本人负责App 首页,影片查询,详细页面开发。
登录拦截这块是怎么处理的?
判断localstorage里的有没有token ,没有token 跳转到登录页面。退出登录的时候会把localstorage 里的token 数据清空。
oa项目
它包括员工的日常考勤打卡,签报发文与审批,员工请假销假,员工管理等功能模块,满足员工日常办公需求。我负责员工管理,签报模块的页面开发。员工的增删改查,新增一个员工的同时给分配一个系统登录账号。工作人员通过系统生成一个签报,提交给科室领导审批,科室领导审批完再提交给下一级审批
菜单权限如何实现的?
登录后会得到用户的token 信息,根据用户的token 信息,获取所有该角色下的所有权限数据。循环遍历这个权限数据,通过递归的方式得到一个树形菜单,然后渲染页面就好了。
项目中的axios进行封装了码?
有,封装了一个http 模块,通过axios.create()方法进行封装的,http 模块里设置了请求超时,还添加了一些请求拦截器。
// 对于数据请求的封装
import axios from 'axios'
import { Toast } from 'vant'
// import router from '../router'
const http = axios.create({
baseURL: 'https://m.maizuo.com',
timeout: 10000, // 请求超时
headers: {
'X-Client-Info':
'{"a":"3000","ch":"1002","v":"5.0.4","e":"1606697250632532718583809","bc":"440100"}'
}
})
// 添加请求拦截器(aiax发起请求之前拦截)
http.interceptors.request.use(function (config) {
// 显示loading
Toast.loading({
message: '加载中...',
forbidClick: true,
duration: 0
})
return config
}, function (error) {
return Promise.reject(error)
})
// 添加响应拦截器
http.interceptors.response.use(function (response) {
// 任何处于2xx范围内的状态代码都会触发此函数
// 隐藏loading
Toast.clear()
return response
}, function (error) {
// 任何超出2xx范围的状态码都会触发此函数
// 隐藏loading
Toast.clear()
return Promise.reject(error)
})
export default http
axios 和ajax 有什么区别
axios 是基于promise API 对ajax 的一种封装,返回一个promise 对象 。
jsop 和 Ajax 的区别
ajax的核心是通过构建xhr对象来实现前后端数据交互;
jsonp的核心是动态添加script标签调用服务器提供的js脚本
谈谈你在项目中都采用什么方式进行性能优化
将css 文件放在页面最上面
移除空的css规则
css 避免层级过深
提取公告样式,减少代码量(网站的配色、字体提取处理使用公告的前缀)
属性值为0时,不加单位
属性值小于1时,省略小数点前面的0
css 雪碧图
redux 工作流
用户通过界面触发 ActionCreators, 调用store.dispatch , 并携带action 数据。然后store 自动调用reducer函数,store 传递两个参数给reducer函数(当前的state,action)。其中reducer函数必须是一个纯函数,该函数会返回一个新的state。根reducer会把多个子reducer的返回结果合并成最终的应用状态,在这一过程中,可以使用redux 提供的combineReducer方法。使用combineReducers 方法时,action 会传递给每个子的reduce 进行处理,在子reducer 处理后会将结果返回给根reducer合并成最终的应用状态。store调用store.subscribe 监听 state的变化,state一旦发生改变就会触发store的更新,最终view 会根据store数据的更新刷新界面。
tabale 组件常用有哪几个属性,分别是用来干什么的
dataSource : 表格的数据源。
columns: 表格列的配置描述
pagination : 分页器
rowKey : 表格行 key 的取值,可以是字符串或一个函数
size : 表格大小
谈一谈react 和 vue 的区别
vue 是双向数据绑定,采用的是mvvm 模式,react 是单向数据流,只有view层
vue 封装了很多方法,提供指令,react没有,需要什么都要自己写,
vue 是通过get/set 进行状态拦截,react 是一套订阅发布模式,需要自己监听,自己发布
react 里的hooks函数了解多少
react 分为类组件和函数组件,函数组件不支持状态和生命周期,所以在react 16.8之后,推出了hook写法,hooks 写法封装了一些方法,例如useState() 保存组件的状态,
useEffect() 处理副作用,用来做一些异步操作,请求数据这些。还有事件监听。
useEffect() 第一个参数是一个回调函数,第二个参数是个数组。
第二个参数如果是一个空数组的话就类似componentDidmount,不依赖任何状态,只会执行一次。
useMemo(),
useCallback() 记忆函数
useEffect() 如果只是在里面进行log 操作,数组里面可以不写依赖吗?
不可以,如果不写的话,如果log的这个n 在其他地方变了的话,那么是读取不到这个最新的值,它就一直是旧的,不会刷新。如果useEffect(fn,[n]) , 加上这个n 的话,在其他地方set ,这个useEffect 就会拿到最新的值
useCallback() 在什么时候会用到?
进入到不必要的遍历的时候怎么去权衡?
axios 有什么区别 ; 可以通过cancel token 来取消请求
cancel token怎么做到取消的?
首先每次去发送请求的时候 都会带上token,cancle token 进行标记一下每一个请求,
https://www.jianshu.com/p/1662e2524c64
fetch 的问题?基于promise ,promise 支持取消请求,
vue路由配置你讲一下,如何配置动态路由,嵌套路由
首先导入官方提供的路由插件“vue-router”,然后注册使用路由插件,然后配置路由信息表,路由信息表是一个数组,数组里存放的是每个对象,对象中配置每个路由path 路径,component 对应的组件。选择路由模式,最后要导出路由。
import VueRouter from 'vue-router' // 1.引用官方提供的路由插件
Vue.use(VueRouter)
const routes = [ // 2.配置信息写在这个数组里
{
path: '/film',
component: Film
},
{
path: '*',
redirect: '/film'
}
]
const router = new VueRouter({
mode: 'hash', // history
routes
})
动态路由配置:
动态路由要在路由跳转的过程中传递参数,在配置路由信息的时候通过冒号配置动态路由,例如path:”/detail/:id”。 然后页面中点击跳转到指定的动态路由通过编程式跳转实现的,this. r o u t e r . p u s h ( ‘ / d e t a i l / router.push(`/detail/ router.push(‘/detail/(id)`),跳转的时候要携带参数。然后获取路由参数通过this.$route.params。
嵌套路由:在路由配置时,加一个children字段,在children 中配置嵌套路由。
const routes = [ // 配置信息写在这个数组里
{
path: '/film',
component: Film,
children: [
{
path: '/film/nowplaying',
component: Nowplaying
}
]
}
]
你是如何用vuex 管理用户登录token
首先在store里的index.js里定义一个全局状态token,
第一次登录的时候,前端调后端的登录接口,发送用户和用户名
后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token
前端拿到token ,将token 存储到localstorage 和vuex中,并跳转路由页面
前端每次跳转路由判断有没有token ,没有就跳转到登录页面,有则跳转到对应的路由页面
每次调后端接口,都要在请求头中加token
后端判断请求头中有没有token , 有token就拿到token并验证token,验证成功就返回数据,验证失败,如token 过期,就返回401 ,请求头中没有token 也返回401
如果前端拿到状态码为401 ,就清除token 信息并跳转到登录页面。
Vue.use(Vuex)
export default new Vuex.Store({
// state 公共的状态
state: {
token: {}
},
// 统一管理,被devtools 记录状态的修改, 唯一改变状态的地方,只支持同步
mutations: {
setUserToken (state, token) {
state.token = token
}
},
// vuex 管理保存公共状态(分散在各个组件内的状态,统一管理)
// 注意:
// vuex 默认是管理在内存,一刷新页面,公共状态就丢失了。
// vuex 持久化
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
onSubmit (values) {
axios.post('/gateway/login', values).then(res => {
console.log(res.data)
const { errorCode } = res.data
if (errorCode === 0) {
localStorage.setItem('token', true) // localStorage 不允许存对象,只能存基本数据类型
this.store.commit('setUserToken', res.data) // 调用commit 方法,将token数据交给store 统一管理。
this.$router.push(this.$route.query.redirect ? this.$route.query.redirect : '/center')
} else {
Toast(res.data.message)
}
})
}
}
}
mvvm 框架怎么理解
采用双向绑定:View的变动,自动反映在 ViewModel,反之亦然。
懒加载如何实现,路由里有懒加载么
懒加载的数据接口的形式是怎么样的?
数据不是一次性加载,当页面需要的时候再请求后端加载相应的数据
我每次会通过get 方式给后端传两个字段,一个是page 要第几页,一个是limit 要几条数据。后端给我返回数组,我每次把这个数组合并到原来的数组中,这样长度就不断的增加。后端还会给我返回一个总长度,到底之后就判断,是继续请求还是return;通过数组的总长度去判断。
路由里也有懒加载,路由的懒加载是在配置路由的时候component字段配一个回调函数,
vant 组件库用到的组件(List,Cell)
List ,Cell 实现电影列表懒加载,当列表即将滚动到底部时,会触发事件并加载更多列表项。
List 组件通过loading 和 finished 两个变量控制加载状态,当组件滚动到底部时,会触发load 事件并将 loading 设置成 true。这个时候就可以发起异步操作并更新数据,数据更新完毕后,将loading 设置成false 即可。如果数据已经全部加载完毕,就直接将finished 设置成true 。
懒加载中遇到了两个问题,页面加载完了全部的数据,已经没有数据了,还是会不断的请求数据,取回来的每次都是空数组,每次更新状态都合并了一个空数组进去,等于没有合并。数据的长度没有把列表撑开,列表还是在底部,出现无限的朝后端发强求。解决办法:判断列表数组的长度是不是等于后端数据的总长度,是的话表示数据已经取完了,返回return ,让它不再执行就可以了。
es6新特性
let const
展开运算符…
解构赋值
模板字符串
class 类
箭头函数
加了个 Symbol数据类型
Set() : 特点可以对数据进行自动去重
Map()特点:对象的属性可以为任意类型的值
css3新特性
- 新增各种CSS选择器 first-child ; last-child; nth-child ; first-of-type (^ $)
- 圆角 (border-radius:8px)
- 阴影 (Shadow)
- 文字特效 (text-shadow、)
- 线性渐变 (gradient)
- 旋转 (transform)
- 增加了旋转,缩放,定位,倾斜,动画,多背景
transform:\scale(0.85,0.90)\ translate(0px,-30px)\ skew(-9deg,0deg)\Animation:
h5新特性
用于媒体播放的 video 和 audio
元素本地离线存储 localStorage 长期存储数据,
浏览器关闭后数据不丢失==sessionStorage 的数据在浏览器关闭后自动删除==
语意化更好的内容元素,比如 article、footer、header、nav、section
表单控件,calendar、date、time、email、url、search
vue数据绑定原理
vue 的数据双向绑定是通过数据劫持和发布-订阅者功能来实现的
实现步骤:
-
实现一个监听者Oberver来劫持并监听所有的属性,一旦有属性发生变化就通知订阅者
-
实现一个订阅者watcher 来接受属性变化的通知并执行相应的方法,从而更新视图
-
实现一个解析器compoile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相对应的订阅者
vue是通过object.defineProperty()来实现数据劫持的。
实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据。
view 更新data其实可以通过事件监听即可,比如input 标签监听”input”事件就可以实现了。
数据更新视图的重点是如何知道数据变了,只要知道数据变了,那么接下去的事都好处理。如何知道数据变了,就是通过object.defineProperty()对属性设置一个set 函数,当数据改变了就会触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了。
react 的diff 算法
tcp三次握手
tcp 三次握手是为了准确无误地将数据送达目的地
1.首先客户端发一个数据包
2.服务端接收数据包之后回传一个带标志的数据包来传递确认信息,表示我收到了
3.客户端接收服务端传递回来的数据,发送一个数据包,代表我知道了,表示’握手‘结束。