#### tag关闭功能实现
1.逻辑:点击关闭,后面的页面会往前进一位
2.在menu.js中定义删除函数
const mutations = {
collapseMenu (state){
state.isCollapse = !state.isCollapse
},
addMenu (state,payload){
//对数据进行去重
if(state.selectMenu.findIndex(item => item.path === payload.path) === -1){
state.selectMenu.push(payload)
}
},
closeMenu(state,payload){
//找到点击数据的索引
const index = state.selectMenu.findIndex(val => val.name === payload.name)
//通过索引删除数组指定元素,1是删除的个数
state.selectMenu.splice(index,1)
}
}
3.在navheader里定义关闭函数
<el-icon class="close" size="12" @click="closeTab(item,index)" ><Close /></el-icon>
import { useRoute,useRouter } from 'vue-router'
//拿到store实例
const store = useStore()
//当前的路由对象
const route = useRoute()
const router = useRouter()
const selectMenu = computed(() => store.state.menu.selectMenu)
//点击关闭tag
const closeTab = (item,index) => {
store.commit('closeMenu',item)
//删除判断
//删除的非当前页tag
if(route.path !== item.path){
return
}
//删除当前页面
const selectMenuData = selectMenu.value
//删除最后一项
if(index === selectMenuData.length){
//如果tag只有一个元素
if(!selectMenuData.length){
router.push('/')
} else {
router.push({
path: selectMenuData[index-1].path
})
}
} else { //如果删除的是中间位置tag
router.push({
path: selectMenuData[index].path
})
}
}
#### 接口文档介绍和登录页面编写
1.补充login页面,将图片放置public文件夹
2.静态资源的处理:
将资源引入为url;
new URL(url, import.meta.url)方式
3.表单数据
接口文档:https://apifox.com/apidoc/shared-205c93aa-6b50-4a1a-85be-b93dc5304443
4.验证码倒计时
<template>
<el-row class="login-container" >
<el-card style="max-width: 480px">
<template #header>
<div class="card-header">
<img :src="imgUrl" alt="">
</div>
</template>
<div class="jump-link">
<el-link type="primary" @click="handleChange">{{ formType ? '返回登录':'注册账号'}}</el-link>
</div>
<el-form
:model="loginForm"
style="max-width: 600px"
class="demo-ruleForm">
<el-form-item prop="userName">
<el-input v-model="loginForm.userName" placeholder="手机号" :prefix-icon="UserFilled"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.passWord" type="password" placeholder="密码" :prefix-icon="Lock "></el-input>
</el-form-item>
<el-form-item v-if="formType" prop="validCode">
<el-input v-model="loginForm.validCode" placeholder="验证码" :prefix-icon="Lock ">
<template #append>
<span @click="countdownChange">{{ countdown.validText }}</span>
</template>
</el-input>
</el-form-item>
</el-form>
</el-card>
</el-row>
</template>
<script setup>
import { ref,reactive } from 'vue'
const imgUrl = new URL('../../../public/login-head.png', import.meta.url).href
//表单的初始数据
const loginForm = reactive({
userName: '',
passWord: '',
validCode: ''
})
//切换表单(0登录)(1注册)
const formType = ref(0)
//点击切换登录和注册
const handleChange = () => {
formType.value = formType.value ? 0 : 1
}
//发送短信
const countdown = reactive({
validText: '获取验证码',
time: 60
})
let flag = false
const countdownChange = () => {
//如果已发送就不处理
if(flag) return
//判断手机号是否正确
const phoneReg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/
if (!loginForm.userName || !phoneReg.test(loginForm.userName) ) {
return ElMessage({
message: '请检查手机号是否正确',
type: 'warning'
})
}
//倒计时
setInterval(() => {
if(countdown.time <= 0){
countdown.time = 60
countdown.validText = `获取验证码`
flag = false
} else {
countdown.time -= 1
countdown.validText = `剩余${countdown.time}s`
}
},1000)
flag = true
}
</script>
<style lang="less" scoped>
:deep(.el-card__header) {
padding: 0
}
.login-container {
height: 100%;
align-items: center;
justify-content: center;
.card-header{
background-color: #899fe1;
img {
width: 430px;
}
}
.jump-link {
text-align: right;
margin-bottom: 10px;
}
}
</style>
#### form表单的校验
<el-form
:model="loginForm"
style="max-width: 600px"
class="demo-ruleForm"
:rules="rules">
<el-form-item prop="userName">
<el-input v-model="loginForm.userName" placeholder="手机号" :prefix-icon="UserFilled"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.passWord" type="password" placeholder="密码" :prefix-icon="Lock "></el-input>
</el-form-item>
<el-form-item v-if="formType" prop="validCode">
<el-input v-model="loginForm.validCode" placeholder="验证码" :prefix-icon="Lock ">
<template #append>
<span @click="countdownChange">{{ countdown.validText }}</span>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" :style="{width: '100%'}" @click="submitForm">
{{ formType ? '注册账号':'登录'}}
</el-button>
</el-form-item>
</el-form>
const validateUser = (rule,value,callback) => {
//不能为空
if (value === "") {
callback(new Error('请输入账号'))
} else {
const phoneReg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/
phoneReg.test(value) ? callback() : callback(new Error('手机号格式不正确,请输入正确手机号'))
}
}
//密码校验规则
const validatePass = (rule,value,callback) => {
//不能为空
if (value === "") {
callback(new Error('请输入密码'))
} else {
const reg = /^[a-zA-Z0-9_-]{4,16}$/
reg.test(value) ? callback() : callback(new Error('密码格式不对,需要4到16位字符,请确认格式'))
}
}
//表单校验
const rules = reactive({
userName: [{ validator: validateUser,trigger: 'blur'}],
passWord: [{ validator: validatePass,trigger: 'blur'}]
})