app.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style lang="less">
</style>
index.vue
<template>
<div class="login-container">
<!--必须用el-form进行包裹-->
<div class="login-head"></div>
<!--配置表单验证
//必须为表单提供验证对象
2添加prop属性
3通过el-form组件库里面的rules-->
<el-form class="login-form" ref="login-form" :model="user" :rules="formRules">
<el-form-item prop="mobile">
<el-input v-model="user.mobile" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="user.code" placeholder="请输入验证码"></el-input>
</el-form-item>
<el-form-item prop="agree">
<el-checkbox v-model="checked">我已阅读并同意用户协议和隐私条款</el-checkbox>
</el-form-item>
<el-form-item>
<el-button class="login-btn" type="primary" :loading="loginLoading" @click="onLogin">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { login } from '@/api/user'
export default {
name: 'LoginIndex',
components: {
},
props: {},
data () {
return {
user: {
mobile: '', // 手机号
code: '', // 验证码
agree: false// 是否同意协议
},
loginLoading: false, // 登录的loding状态
/* checked: false, // 是否同意协议 */
formRules: {
mobile: [{
required: true,
message: '手机号不能为空',
trigger: 'change'
},
{ pattern: /^1[3|5|7|9]\d{9}$/, message: '请输入正确的号码格式', trigger: 'change' }
],
code: [{
required: true,
message: '验证码不能为空',
trigger: 'change'
},
{ pattern: /^\d{6}$/, message: '请输入正确的验证码格式', trigger: 'change' }
],
agree: [{
// 调用
validator: (rule, value, callback) => {
if (value) {
callback()
} else {
callback(new Error('请同意用户协议'))
}
},
trigger: 'change'
}]
}
}
},
methods: {
onLogin () {
// 获取表单数据
// const user = this.user
// 触发表单验证 validate是异步
this.$refs['login-form'].validate((valid, err) => {
console.log(valid)
console.log(err)
// 如果
if (!valid) {
return
}
this.login()
})
},
login () {
// 开启loading
this.loginLoading = true
// 验证通过
// 请求直接封装
login(this.user).then(res => {
console.log(res)
this.$message({
message: '登录成功',
type: 'success'
})
this.loginLoading = false
}).catch(err => {
console.log('登录失败', err)
this.$message.error({
message: '手机号或者验证码错误',
type: 'warning'
})
this.loginLoading = false
})
}
}
}
</script>
<style scoped lang="less">
.login-container{
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: url("./login_bg.jpg") no-repeat;
background-size: cover;
.login-head{
width: 300px;
height: 57px;
background:url("./logo_index.png") no-repeat;
margin-bottom: 30px;
}
.login-form{
background-color: #fff;
padding: 50px;
min-width: 300px;
.login-btn{
width: 100%;
}
}
}
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './styles/index.less'
// 加载组件库
import ElementUI from 'element-ui'
// 加载样式
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
// 注册组件库
Vue.use(ElementUI)
new Vue({
router,
render: h => h(App)
}).$mount('#app')
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '@/views/login/index'
Vue.use(VueRouter)
// 路由配置表
const routes = [{
path: '/login',
name: 'login',
component: Login
}]
const router = new VueRouter({
routes
})
export default router
user.js
// 用户登录的请求模块
import request from '@/utils/request'
export const login = data => {
return request({
method: 'POST',
url: '/mp/v1_0/authorizations',
data
})
}
// 获取用户信息
index.vue
<template>
<div class="home-container">首页</div>
</template>
<script>
export default {
name: 'HomeIndex',
data () {
return {
}
}
}
</script>
<style scoped lang="less">
</style>
index.vue
<template>
<el-container class="layout-container">
<el-aside class="aside">Aside</el-aside>
<el-container>
<el-header class="header">Header</el-header>
<el-main class="main">Main</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: 'LayoutIndex',
data () {
return {
}
}
}
</script>
<style scoped lang="less">
.layout-container{
position: fixed;
left:0;
right:0;
top:0;
bottom: 0;
}
.aside{
width: 100px;
background-color: #d3dce6;
}
.header{
background-color: #b3c0d1;
}
.main{
background-color: #e9eef3;
}
</style>
aside.vue
<template>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</template>
<script>
export default {
name: 'AppAside',
methods: {
handleOpen (key, keyPath) {
console.log(key, keyPath)
},
handleClose (key, keyPath) {
console.log(key, keyPath)
}
}
}
</script>
<style scoped lang="less">
</style>
运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通