vue3 element-plus-demo 登录认证多页面路由demo
一:效果演示
二:设计
a. 目录结构
src
├── App.vue
├── assets
│ ├── element-plus-logo.svg
│ └── logo.png
├── components
├── main.js
├── router
│ └── index.js
├── store
│ └── index.js
└── views
├── About.vue
├── Home.vue
├── Layout.vue # 模板基本布局,分Header,main 和 footer
├── Login.vue # 登录界面,
├── Page1.vue
└── Page2.vue
b. 页面
页面都继承自Layout.vue
Layout.vue
<template>
<el-container style="height: 100%;">
<el-header>
<el-menu :default-active="activeIndex" mode="horizontal" router>
<el-menu-item>
<img src="../assets/element-plus-logo.svg" style="width: 120px; height: 60px;" />
</el-menu-item>
<template v-if="username !== ''">
<template v-for="route in routes" :key="route.name" :route="route">
<el-menu-item :index="route.path">{{ route.meta.displayName }}</el-menu-item>
</template>
<el-sub-menu style="margin-left: auto;">
<template #title>
<i class="el-icon-setting"></i>
{{ username }}
</template>
<el-menu-item @click="logoff">
<i class="el-icon-right"></i>
注销登陆
</el-menu-item>
</el-sub-menu>
</template>
<template v-else>
<el-menu-item class="is-active">请登陆后访问!</el-menu-item>
</template>
</el-menu>
</el-header>
<el-main>
<slot name="main"></slot>
</el-main>
<el-footer height="40px" style="color: #909399; text-align: center;">?2021 Leo xxxxxx.com</el-footer>
</el-container>
</template>
<script>
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from 'element-plus'
export default {
name: 'Layout',
setup() {
const router = useRouter();
const route = useRoute();
return {
routes: router.getRoutes().filter(value => value.name != 'Login' && value.name != 'Logout'),
activeIndex: route.path,
}
},
computed: {
username() {
return this.$store.state.username || ''
}
},
methods: {
logoff() {
this.$store.commit('logoff')
ElMessage({
showClose: true,
message: `用户 ${this.$store.state.username} 注销成功!`,
type: 'success',
})
this.$router.replace({ name: 'Login' })
}
}
}
</script>
Home.vue
<template>
<Layout>
<template v-slot:main>
<h1>Main Content</h1>
</template>
</Layout>
</template>
<script>
import Layout from "../views/Layout.vue";
export default {
name: 'Home',
components: {
Layout
}
}
</script>
c. 路由
登录处理, Login.vue
<template>
<Layout>
<template v-slot:main>
<div style="display: flex; justify-content: center; align-items: center; height: 100%;">
<el-form
ref="loginForm"
:model="loginForm"
status-icon
:rules="rules"
label-width="120px"
style="width: 400px;"
>
<el-form-item label="用户" prop="username" required>
<el-input v-model="loginForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="userpwd" required>
<el-input
v-model="loginForm.userpwd"
type="password"
autocomplete="off"
show-password
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="submitForm('loginForm')"
style="width: 100%;"
>登陆</el-button>
</el-form-item>
</el-form>
</div>
</template>
</Layout>
</template>
<script>
import { ElMessage } from 'element-plus'
import Layout from '../views/Layout.vue';
export default {
data() {
return {
loginForm: {
username: '',
userpwd: ''
},
rules: {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
userpwd: [{ required: true, message: '请输入密码', trigger: 'blur' }]
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$store.commit('login', this.loginForm.username)
ElMessage({
showClose: true,
message: `用户 ${this.loginForm.username} 登陆成功!`,
type: 'success',
})
this.$router.replace({ name: 'Home' })
} else {
return false
}
})
}
},
components: {
Layout
}
}
</script>
三: 完整代码
https://github.com/LeoBest2/LearnLib/tree/main/element-plus/src
|