1.vue➡使用Element-ui
vue开发还有一个方便之处就是可以利用组件开发前端,因为组件都是一个类似的模板而已,所以需要什么的组件都可以到ELement组件拿到。
1. ELement组件使用初步教学
没有html、css的基础的,回去补一下,不需要太多时间的,就是要懂一下语法规则,以及一些常用的标签的用法。
Layout 布局
通过基础的24分栏,迅速简便地创建布局。
所谓的24分栏,就是把一个页面横向分成24分,通过标签里面的span确定布局所占的宽带。
例如:
可以通过修改
<el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
里面的span的值来修改占位的大小。
form表单
- rules规则:就是约束你输入框里面输入的格式。
- prop:相当于name,属性名。
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。 - ref: ref在Vue中是用来给元素或是子组件注册引用信息到父组件或是 Vue实例上,注册后的引用信息都会呈现在父组件/Vue实例的 (. r e f s ) 上 , 这 时 , 我 们 就 可 以 通 过 ( .refs) 上,这时,我们就可以通过(.refs)上,这时,我们就可以通过(.refs) 获取到引用的 DOM 对象或是子组件信息。
2.头像和下来菜单
2. Login页面-登录案例
分析后端传输验证码的方式:
1.首先是浏览器异步获取验证码的请求,后端生成验证码,这里使用mock.js模拟后端随机生成验证码,所以还没使用到redis。
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用校验,等等。
2.返回验证码的图片数据,由codeImg接收,并显示出来。
3.验证码生成逻辑
页面显示:
代码展示:
(注意:js和样式代码要放对地方)
<template>
<div>
<el-row type="flex" class="row-bg" justify="center">
<!-- 左边显示-->
<el-col :xl="6" :lg="7" style="min-width: 6px">
<h2>欢迎来到vue管理系统</h2>
<el-image :src="require('@/assets/login.jpg')" style="height: 180px;width: 180px"></el-image>
<p>we are the one</p>
<p>make them remember you!</p>
</el-col>
<!-- 分割线-->
<el-col :span="1">
<el-divider direction="vertical"></el-divider>
</el-col>
<!-- 右边显示-->
<el-col :xl="6":lg="7">
<el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="80px" >
<el-form-item label="用户名" prop="username"style="width: 380px;">
<el-input v-model="loginForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password"style="width: 380px;">
<el-input v-model="loginForm.password"></el-input>
</el-form-item>
<el-form-item label="验证码" prop="code" style="width: 380px;">
<el-input v-model="loginForm.code" style="width: 172px; float: left" ></el-input>
<!-- 验证码图片-->
<el-image :src="codeImg" class="codeImg"></el-image>
</el-form-item>
<el-form-item style="display: flex ;align-items: center">
<el-button type="primary" @click="submitForm('loginForm')">立即创建</el-button>
<el-button @click="resetForm('loginForm')">重置</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "Login",
//表单数据
data() {
return {
loginForm: {
username: '',
password: '',
code: '',
// 后端返回
token:''
},
//约束规则
rules: {
username: [
//require是true使用规则约束,trigger是触发器
{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ min: 5 ,max: 5, message: '长度为5', trigger: 'blur'}
],
},
//验证码
codeImg:null
};
},
//vue的生命周期函数
created() {
//调用方法生成验证码
this.getCodeImg();
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
//post请求,请求路径为https://localhost:8080/login
this.$axios.post('/login',this.loginForm).then(res=>{
const jwt = res.headers['authorization']
this.$store.commit('SET_TOKEN',jwt)
//提交到/index页面
this.$router.push('/index')
})
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
getCodeImg(){
//后端请求code图片的路径
this.$axios.get('/captcha').then(res=>{
console.log("res")
console.log(res)
//通过mockjs模拟返回数据
this.loginForm.token = res.data.data.token;
this.codeImg = res.data.data.codeImg;
})
}
},
}
</script>
<style scoped>
/* 整个页面的背景设置组件为 el-row*/
.el-row{
/*背景颜色*/
background-color: #fafafa;
/* 覆盖页面的全部*/
height: 100vh;
/*布局,选择flex布局方式*/
display: flex;
/*flex-center:居中*/
align-items: center;
}
/**/
.el-divider{
height: 200px;
}
/*验证码图片的样式*/
.codeImg{
float: left;
/* 边距*/
margin-left: 8px;
/* 圆角*/
border-radius: 4px;
}
</style>
3.在mock.js写随机生成验证码
mock官方网站:http://mockjs.com/examples.html#Image
//引用mockjs
const Mock = require('mockjs')
//随机变量
const Random = Mock.Random
let Result = {
code:200,
msg:'操作成功',
data:null
}
//请求路径为/captcha
Mock.mock('/captcha','get',()=>{
Result.data = {
//生成32位的token数据
token:Random.string(32),
//生成验证码图片
codeImg:Random.dataImage('120x40', 'p7n8')
};
//json数据
return Result
})
Mock.mock('/login','post',()=>{
//无法在header传入参数jwt
return Result
})
4.axios拦截器
登录逻辑需要用到axios来验证输入的信息是否正确,这里使用axios拦截器来实现这个功能。(axios官网:https://www.axios-http.cn
在main的同级目录下创建一个axios.js的文件,代码如下:
import axios from "axios";
import router from "./router";
import Element from "element-ui"
//不能和前端的端口冲突,前端端口8080
// axios.defaults.baseURL="http://localhost:8081"
//创建一个axios实例,由main.js引用
const request = axios.create({
//超时时间
timeout:5000,
//请求头
headers:{
//使用json数据格式
'Content-Type':"application/json"
}
})
//请求体的拦截器
request.interceptors.request.use(config=>{
config.headers["Authorization"] = localStorage.getItem("token")
return config
})
///响应体拦截器
request.interceptors.response.use(response=>{//响应体的逻辑处理
//获取响应的数据
let res =response.data
//登录逻辑
//注意一定要写===,而不是这个==,判断是否200,200表示登录成功
if (res.code===200){
return response
}else {//异常返回
//弹出窗口
Element.Message.error(!res.msg?'系统异常':res.msg)
return Promise.reject(response.data.msg)//异常拒绝跳转页面
}
}, error => {//业务逻辑出现异常的情况,比如权限异常
if (error.response.data){
error.message = error.response.data.msg
}
//未登录判断
if (error.response.state===401){
router.push('/login')
}
//element-ui的信息
Element.Message.error(error.message,{duration:3000})
return Promise.reject(error)
})
export default request
注意:这里同时要改main.js文件中的axios的引用,我这里的创建的axios.js文件和main.js在同级目录下面的,可以直接写成