登录功能实现的基本步骤?亮点?难点?

  1. 首先对登陆页面进行绘制,除了登录页面其他页面都是需要权限的。基于 Vue 和 使用element-ui 提供的 el-form 表单快速实现项目各页面的搭建开发;利用display:flex控制水平垂直居中。
  2. 在使用form表单的时候会涉及到校验,校验规则是需要给form表单绑定四个属性,其中在el-form标签上要绑定:model属性和:rules属性,在el-form-item标签上绑定prop属性,在el-input标签上绑定v-model属性。然后在data中配置校验规则,要求是el-form-item标签上的prop字段要和el-input标签上的v-model的字段保持一致,这是基础的表单校验。
  3. 之后点击登录的时候要发送数据请求,用了一个第三方的包axios,因为是一个工具包,所以在src下面创建了一个utils目录,放到这下面。并且专门建立了一个request.js文件,在这里面进行一个二次包装,具体包装是导入后创建一个axios实例化对象instance = axios. create。在axios的实例里面把baseURL设置成公共的url。
instance var instance = axios. create ({
   // 基础路径 
    baseURL: 'https://lianghj.top:8888/api/private/v1/', 
   // 设置超时时间
   timeout: 3000 
});
  1. 【问题优化】为什么创建实例?而不是直接使用axios发送请求,因为我在项目后面要用到两个接口,管理信息分配权限是一个接口,聊天也是一个单独接口,这样的话我创建两个实例,我用哪个接口直接把这个实例暴露出去,就可以发送数据请求了。登陆的话用的第一个接口,所以在axios.create里面还配置了一个timeout进行超时处理。
  2. 因为大部分接口都是权限的接口,所以我又做了axios一个拦截器和响应器的封装 。拦截器的话做了一点,在拦截器携带了token,对token也做了一些处理,在项目中判断本地存储里面是否有token。因为在后期登录之后把这个token已经放到了vuex里面,我在request.js里面把这个token从vuex里面拿出来。如果有token说明登陆过了,就拿出来携带这个token进行发起请求。没有token的话就是没有登陆,需要重新登录。
  3. 在响应拦截器里面做了一层抽离,axios默认包装了一层data,我通过解构把它默认包装的这一层data解构出来,在后端接口中帮我们处理了统一的格式,只要数据请求成功就返回success:true,把为true返回的数据接口出来,我直接把data return出去。如果失败就返回success:false,就写一个提示信息,再抛出异常,后期都是promise,为了方便trycatch捕获,这里需要手动抛出一个promise.reject异常。
  4. 并且在这里导入element组件,在request.js里面使用this的时候,我发现this和当前vue组件的this没有啥关系,我打印之后发现是个undefined,但是在这里我还需要调用这个this.dilog弹出层组件,然后我导入了message这个组件$msg,可以使用alter或者error的一个提示。这是我封装axios的一些处理。最后为了方便后期对接口的复用管理,我又封装到了一个api目录下,并且在里面新建了一个login.js,主要就是分发请求。然后因为登录是一个post组件,我在这里需要携带一些参数,还需要使用data,然后还使用了es6的属性简写。
  5. 登录,接下来就是登录了,登陆成功后做了一个状态保持。涉及到用cookie、session还是token,前后端分离的项目为了方便用户的状态保持,使用了token。cookie和session也可以状态保持,但是有一点,不支持跨域。
  6. 登陆遇到的问题:所以用户状态保持和后端讨论后,最终决定使用token,一个亮点就是对token进行了持久化和存储,放到本地了。但发现不是响应式的,登陆过期之后还是不能处理,所以最后放到了vuex里面。登陆过期之后对token进行了一些处理:主动介入和被动介入,主动介入就是我在前端里面定义了一个时间戳,每次发送请求的时候判断时间戳是否小于规定的时间,过期的话就跳转到登录页。被动介入也是一个亮点就是在axios响应拦截器里面,根据后端返回的状态码,如果是401说明过期了,也是跳转到登录页。
  • 【问题优化】然而这个时候出现了一个问题,项目开发中后端提供的接口是一个IP地址,项目上线后又是另外一个地址。对于开发和上线需要经常切换baseURL,所以线上的就统一在.env.production里面声明了一个变量,而本地的放在了.env.development里面
  1. 点击button按钮进行登陆的时候,就可以发送数据请求了。但是在发送数据请求的时候,有的用户可能虽然看到的是验证失败,当他强行点击button按钮进行登录,也可以发送请求。所以这个时候,就做了一个二次校验,通过formvalidate方法来进行校验,调用this.$refs.引用名.方法名。如果要调用这个方法,必须要在el-form标签上绑定ref属性,引用名就是绑定的ref属性值。然后validate里面使用回调函数,回调函数里面又有一个形参isOK,如果为true,表示校验通过,就在为true里面来进行发送登录的请求,发送登录请求之后,请求成功,后端会返回一个token的字符串
  2. 拿到token之后,后续所有的接口都需要这个token。并且退出的时候,要把token删除掉,页面作出响应。包括token过期,页面也要做一些处理,所以把token存储到vuex里面。
  3. 由于使用的是vue-element-admin,他已经初始化好了一个store目录,在store目录下新建一个user.js。这个项目比较复杂,在设计的时候考虑到如果都把数据定义到state里面,可能会造成后期数据难以维护的问题,不方便查找和修改,所以用了一个vuex的分模块。在store下面的index.js里面的modules里面定义了一个user,与user相关的信息就在user.js里面处理了
  4. 接下来是存储vuex。我先在state里面存储了一个token,由于修改token只能通过mutations,在mutations里面定义了一个方法,setToken方法,他接收两个参数,第一个是指向state,第二个参数是载荷,就是当前用户传递过来的数据。在登录成功之后,就把token通过调用setToken这个方法,把token存到了vuex
  • 【问题优化】但是拿到token之后发现了一个问题,当刷新的时候,数据不存在了。后来发现是vuex数据是存到内存里面的,只要刷新,数据就会消失。为了数据持久化存储,就存到了localStorage里,每次刷新就能从本地存储里边读取。这样,token不但是响应式的,还是持久化的数据。
  1. 在vuex中定义好token数据之后,由于后续发送请求的时候,所有的接口都需要携带token,所以在axios请求拦截器里面携带上token,判断一下vuex里面是否有token,有的话就带上,没有就不携带。
  2. 此时,需要让utils下的request.js文件里取到这个token。因为request.jsvuex的实例没有关联上,没有办法直接使用this.$store方法。所以,这里要把store实例导入过来,再想调用vuex,就可以用store.模块名.token了。