本地服务端口在vue.config.js中进行设置
vue.config.js 是vue项目相关的编译,配置,打包,启动服务相关的配置文件,它的核心在于webpack,但是又不同于webpack,相当于改良版的webpack
打开vue.config.js文件,我们发现如下代码:
const port = process.env.port || process.env.npm_config_port || 9528 // dev port
其中process.env.port实际上是一个nodejs服务下的环境变量
该变量在项目根目录中的.env.development和.env.production两个文件中设置
当我们运行npm run dev进行开发调试的时候,此时会加载执行.env.development文件内容
当我们运行npm run build:prod进行生产环境打包的时候,会加载执行.env.production文件内容
所以,如果想要设置开发环境的接口,直接在.env.development中写入对于port变量的赋值即可,代码如下:
# 设置端口号
port = 8888
通过阅读模板代码,我们发现网站名称是src目录下的settings.js文件中配置:
module.exports = {
title: '人力资源管理平台',
/**
* @type {boolean} true | false
* @description Whether fix the header
*/
fixedHeader: false,
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: true
}
我们在基础模板的登录页面的基础上添加样式,在src-views-login-index.vue中添加样式代码:
<div class="title-container">
<h3 class="title">
<img src="@/assets/common/login-logo.png" alt="">
</h3>
</div>
注意:@是我们在vue.config.js中设置的一个路径别名,指定src根目录,这样可以很方便的寻找文件
在style中配置:
.login-container {
background-image: url('~@/assets/common/login.jpg'); // 设置背景图片
background-position: center; // 将图片位置设置为充满整个屏幕
}
注意:如需要在样式表中使用@别名的时候,需要在@前面加上一个~符号,否则不识别
$light_gray: #68b0fe; // 将输入框颜色改成蓝色
input {
color: $light_gray;
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.7); // 输入登录表单的背景色
border-radius: 5px;
color: #454545;
}
.el-form-item__error {
color: #fff
}
.loginBtn {
background: #407ffe;
height: 64px;
line-height: 32px;
font-size: 24px;
}
首先在utils/validate.js方法中添加校验手机号的方法:
export function validMobile(str) {
return /^1[3-9]\d{9}$/.test(str) // 校验手机号
}
然后在src/views/login/index.vue中导入该方法并使用:
import { validMobile } from '@/utils/validate'
data() {
// 自定义校验函数
const validateMobile = function(rule, value, callback) {
// 校验value,如果通过,直接执行callback
// 不通过返回错误提示信息
validMobile(value) ? callback() : callback(new Error('手机号格式不正确'))
}
return {
loginForm: {
mobile: '13800000002',
password: '123456'
},
loginRules: {
mobile: [{ required: true, trigger: 'blur', message: '手机号不能为空' }, {
validator: validateMobile, trigger: 'blur'
}],
password: [{ required: true, trigger: 'blur', message: '密码不能为空' }, {
min: 6, max: 16, message: '密码的长度在6-16位之间 ', trigger: 'blur'
}]
},
loading: false,
passwordType: 'password',
redirect: undefined
}
},
在基础模板中,我们发现密码输入框绑定了一个事件修饰@keyup.enter.native
@keyup.enter.native 表示当用户按回车键的时候触发绑定函数,这里的native表示keyup是一个原生事件
当下,最流行的就是前后端分离项目,也就是前端项目和后端接口并不在一个域名之下,那么前端项目访问后端接口必然存在跨域的行为,这时候就要通过配置跨域代理来解决这个问题。需要注意的是,我们目前所配置的跨域代理是位于开发环境的,如果项目需要部署上线时,还要配置生产环境的跨域代理。
需要在项目根目录下的vue.config.js中配置跨域代理:
module.exports = {
devServer: {
// 代理跨域的配置
proxy: {
// 当我们的本地的请求 有/api的时候,就会代理我们的请求地址向另外一个服务器发出请求
'/api': {
target: 'http://ihrm-java.xxxx.net/', // 跨域请求的地址
changeOrigin: true // 只有这个值为true的情况下 才表示开启跨域
}
}
}
}
在src/api/user.js中封装登录请求接口:
//导入axios
import request from '@/utils/request'
export function login(data) {
// 返回一个promise对象
return request({
url: '/sys/login',
method: 'post',
data
})
}
在src/store/modules/user.js中删掉基础模板的代码,保留如下初始配置代码:
// 状态
const state = {}
// 修改状态
const mutations = {}
// 执行异步
const actions = {}
export default {
namespaced: true,
state,
mutations,
actions
}
在utils/auth.js中,基础模板已经为我们提供了获取token,设置token,删除token的方法,可以直接使用,只要把存储的key设置成特定值即可:
import Cookies from 'js-cookie'
const TokenKey = 'hrsaas-ihrm-token' // 设定一个独一无二的key
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
import { getToken, setToken, removeToken } from '@/utils/auth'
// 初始化的时候从缓存中读取状态 并赋值到初始化的状态上
// Vuex的持久化通过Vuex和前端缓存相结合实现
const state = {
token: getToken() // 设置token初始状态
}
// 修改状态
const mutations = {
// 设置token
setToken(state, token) {
state.token = token // 设置token
setToken(token) // vuex和缓存数据的同步
},
// 删除缓存
removeToken(state) {
state.token = null // 删除vuex的token
removeToken() //vuex和缓存数据的同步
}
}
// 调用登录接口,成功后设置token到vuex,失败则返回失败
const actions = {
// 定义login
async login(context, data) {
// 经过响应拦截器的处理之后 这里的result实际上就是 token
const result = await login(data)
// actions 修改state 必须通过mutations
context.commit('setToken', result)
}
}
为了更好的让其他模块和组件更好的获取token数据,我们可以store/getters.js中将token值作为公共的访问属性:
const getters = {
token: state => state.user.token
}
export default getters
我们可以在.env.development和.env.production文件中定义环境变量
我们需要在.env.development文件中修改开发环境的代理:
# 开发环境的基础地址和代理对应
VUE_APP_BASE_API = '/api'
在src/utils/request.vue中添加:
import axios from 'axios'
// 创建一个axios的实例
const service = axios.create({
// 如果执行 npm run dev 值为 /api
baseURL: process.env.VUE_APP_BASE_API, // 设置axios请求的基础的基础地址
timeout: 5000 // 定义5秒超时
})
处理逻辑代码如下:
// 响应拦截器
service.interceptors.response.use(response => {
// axios默认加了一层data
const { success, message, data } = response.data
// 要根据success的成功与否决定下面的操作
if (success) {
return data
} else {
// 业务已经错误了 还能进then ? 不能 ! 应该进catch
Message.error(message) // 提示错误消息
return Promise.reject(new Error(message))
}
}, error => {
Message.error(error.message) // 提示错误信息
return Promise.reject(error) // 返回执行错误 让当前的执行链跳出成功 直接进入 catch
})
import { mapActions } from 'vuex' // 引入vuex的辅助函数
methods: {
...mapActions(['user/login'])
handleLogin() {
// 表单的手动校验
// ref可以获取该组件的实例
this.$refs.loginForm.validate(async isOK => {
if (isOK) {
try {
this.loading = true
// 只有校验通过了 我们才去调用action
await this['user/login'](this.loginForm)
// await下面的代码 都是成功执行的代码
this.$router.push('/')
} catch (error) {
console.log(error)
} finally {
// 不论执行try 还是catch 都去关闭转圈动画
this.loading = false
}
}
})
}
}
今天的主要工作是封装了登录组件,用Vuex来设计登录流程,组件间共享用户数据。