目录结构
router.js
- import Vue from 'vue'
- import Router from 'vue-router'
- import Login from './components/Login.vue'
- import Home from './components/Home.vue'
- import Welcome from './components/Welcome.vue'
- import Users from './components/user/Users.vue'
- import Right from './components/power/Right.vue'
- import Roles from './components/power/Roles.vue'
- import Cate from './components/goods/Cate.vue'
- import Params from './components/goods/Params.vue'
- import List from './components/goods/List.vue'
- Vue.use(Router)
-
- const router = new Router({
- routes: [{
- path: '/',
- redirect: '/login'
- },
- {
- path: '/login',
- component: Login
- },
- {
- path: '/home',
- component: Home,
- redirect: '/welcome',
- children: [{
- path: '/welcome',
- component: Welcome
- }, {
- path: '/users',
- component: Users
- },
- {
- path: '/rights',
- component: Right
- },
- {
- path: '/roles',
- component: Roles
- },
- {
- path: '/categories',
- component: Cate
- }, {
- path: '/params',
- component: Params
- }, {
- path: '/goods',
- component: List
- }
- ]
- }
- ]
- });
- //挂载路由导航守卫
- router.beforeEach((to, from, next) => {
- if (to.path === '/login') return next();
- //获取token
- const tokenStr = window.sessionStorage.getItem('token')
- if (!tokenStr) return next('/login')
- next();
- })
-
- export default router
login.vue
-
- <div class="login_container">
- <div class="login_box">
- <div class="avatar_box">
- <img src="../assets/logo.png">
- div>
-
- <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
-
- <el-form-item prop="username">
- <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user">el-input>
- el-form-item>
- <el-form-item prop="password">
- <el-input type="password" v-model="loginForm.password" prefix-icon="iconfont icon-3702mima">el-input>
- el-form-item>
- <el-form-item class="btns">
- <el-button type="primary" @click="login">登录el-button>
- <el-button type="info" @click="resetLoginForm">重置el-button>
- el-form-item>
- el-form>
- div>
- div>
-
- template>
-
- <script>
- export default{
- data(){
- return{
- //这是登录表单的数据
- loginForm:{
- username:'geyao',
- password:'12345678'
- },
- // 表单验证
- loginFormRules: {
- username: [
- { required: true, message: '请输入用户名', trigger: 'blur' },
- { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
- ],
- password: [
- { required: true, message: '请输入用户密码', trigger: 'blur' },
- { min: 6, max: 18, message: '长度在 6 到 18 个字符', trigger: 'blur' }
- ]
- }
- }
- },
- methods:{
- resetLoginForm(){
- // console.log(this)
- this.$refs.loginFormRef.resetFields();
- },
- login(){
- this.$refs.loginFormRef.validate(async valid =>{
- if(!valid) return;
- const {data:res}=await this.$http.post('login',this.loginForm);
- if(res.meta.status!==200) return this.$message.error('登录失败');
- this.$message.success('登录成功');
- // 1、将登陆成功之后的token, 保存到客户端的sessionStorage中;
- // 1.1 项目中出现了登录之外的其他API接口,必须在登陆之后才能访问
- // 1.2 token 只应在当前网站打开期间生效,所以将token保存在
- window.sessionStorage.setItem('token', res.data.token)
- // 2、通过编程式导航跳转到后台主页, 路由地址为:/home
- this.$router.push('/home')
- });
- }
- }
- }
- script>
-
- <style lang="less" scoped>
- .login_container {
- background-color: #2b4b6b;
- height: 100%;
- }
- .login_box {
- width: 450px;
- height: 360px;
- background-color: #fff;
- border-radius: 3px;
- position: absolute;
- left: 50%;
- top: 50%;
- -webkit-transform: translate(-50%, -50%);
- background-color: #fff;
- }
- .avatar_box {
- width: 130px;
- height: 130px;
- border: 1px solid #eee;
- border-radius: 50%;
- padding: 10px;
- box-shadow: 0 0 10px #ddd;
- position: absolute;
- left: 50%;
- transform: translate(-50%, -50%);
- background-color: #fff;
- img {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- background-color: #eee;
- }
- }
- .login_form {
- position: absolute;
- bottom: 60px;
- width: 100%;
- padding: 0 20px;
- box-sizing: border-box;
- }
- .btns {
- display: flex;
- justify-content: center;
- }
- style>
main.js
- import Vue from 'vue'
- import App from './App.vue'
- import router from './router'
- import './plugins/element.js'
- //导入字体图标
- import './assets/fonts/iconfont.css'
- Vue.config.productionTip = false
- //导入全局样式
- import './assets/css/global.css'
- import TreeTable from "vue-table-with-tree-grid"
- import axios from 'axios'
-
-
- Vue.prototype.$http=axios
- axios.defaults.baseURL="http://127.0.0.1:8888/api/private/v1/"
- // 请求在到达服务器之前,先会调用use中的这个回调函数来添加请求头信息
- axios.interceptors.request.use(config => {
-
- // console.log(config)
- // 为请求头对象,添加token验证的Authorization字段
- config.headers.Authorization = window.sessionStorage.getItem('token')
- // 在最后必须 return config
- return config
- })
- Vue.config.productionTip=false;
- Vue.component('tree-table',TreeTable)
-
- Vue.filter('dataFormat', function (originVal) {
- const dt = new Date(originVal)
-
- const y = dt.getFullYear()
- const m = (dt.getMonth() + 1 + '').padStart(2, '0')
- const d = (dt.getDate() + '').padStart(2, '0')
-
- const hh = (dt.getHours() + '').padStart(2, '0')
- const mm = (dt.getMinutes() + '').padStart(2, '0')
- const ss = (dt.getSeconds() + '').padStart(2, '0')
- // yyyy-mm-dd hh:mm:ss
- return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
- })
- new Vue({
- router,
- render: h => h(App)
- }).$mount('#app')
-
-
global.css
- /* 全
原文:https://blog.csdn.net/weixin_43392489/article/details/107825183