SpringBoot + Vue 用户登入token 之租房管理系统后台 模板

阿里 阅读:716 2021-03-31 12:22:02 评论:0

SpringBoot 项目构建:SpringBoot + MySQL8 + MyBatis-Plus + Redis +定时任务框架(elastic-job) + Spring Security + JWT(前后端分离Token)

csdn 下载地址:https://download.csdn.net/download/zhouzhiwengang/16136915

Vue项目构建:Vue + Vue-Route +Vuex + Element-UI + Axios 项目管理后台模板

Vue项目创建:

#创建一个基于webpack模板的新项目 
vue init webpack C:\node_workspace\two 
# 切换至项目路径 
cd C:\node_workspace\two 
# 安装项目依赖文件 
cnpm install 
# 项目启动 
cnpm run dev 

Vue 项目集成Vuex + Element-UI + Axios框架依赖

C:\node_workspace\two>cnpm i element-ui -S 
√ Installed 1 packages 
√ Linked 8 latest versions 
√ Run 0 scripts 
√ All packages installed (6 packages installed from npm registry, used 4s(network 4s), speed 21.08kB/s, json 9(81.21kB), tarball 0B) 
 
C:\node_workspace\two>cnpm i vuex -S 
√ Installed 1 packages 
√ Linked 1 latest versions 
√ Run 0 scripts 
√ All packages installed (1 packages installed from npm registry, used 260ms(network 255ms), speed 156.22kB/s, json 2(39.84kB), tarball 0B) 
 
C:\node_workspace\two>cnpm i axios -S 
√ Installed 1 packages 
√ Linked 1 latest versions 
√ Run 0 scripts 
√ All packages installed (1 packages installed from npm registry, used 363ms(network 360ms), speed 26.39kB/s, json 2(9.5kB), tarball 0B)

Vue 之 移除初始化模板样式和数据

1、在App.vue 文件中移除原有Vue的logo 标签和样式文件。下面是修改后的App.Vue 文件

<template> 
  <div id="app"> 
    <router-view/> 
  </div> 
</template> 
 
<script> 
export default { 
  name: 'App' 
} 
</script> 
 
<style> 
* { 
  margin: 0; 
  padding: 0; 
  box-sizing: border-box; 
} 
html,body{ 
  width: 100%; 
  height: 100%; 
} 
#app { 
  height: 100%; 
} 
</style> 

Vue 之Vuex 功能封装

1、在src 文件夹下新增store 文件夹并新增index.js 。index.js 新增内容如下:

import Vue from 'vue' 
import Vuex from 'vuex' 
Vue.use(Vuex); 
  
const store = new Vuex.Store({ 
  
  state: { 
    // 存储token 
    token: localStorage.getItem('token') ? localStorage.getItem('token') : '' 
  }, 
  
  mutations: { 
    // 修改token,并将token存入localStorage 
    changeLogin (state, user) { 
      state.token = user.token; 
      localStorage.setItem('token', user.token); 
    }, 
    logout (state, user) { 
        state.token = '' 
        localStorage.removeItem('token') 
      } 
   
 
  } 
}); 
  
export default store;

Vue 之Element-ui、axios、store功能基础

1、在mian.js 集成element-ui、axios、store 。main.js 内容如下:

// The Vue build version to load with the `import` command 
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. 
import Vue from 'vue' 
import App from './App' 
import router from './router' 
// 集成element-ui 
import ElementUI from 'element-ui'; 
import 'element-ui/lib/theme-chalk/index.css'; 
// 集成vuex 
import store from'./store' 
// 集成axios 
import axios from '../node_modules/axios' 
 
// 设置跨域 
axios.defaults.withCredentials = true 
// 设置后端请求地址 
axios.defaults.baseURL='http://192.168.1.74:8198/house' 
Vue.prototype.$axios = axios 
 
Vue.use(ElementUI); 
Vue.config.productionTip = false 
 
// 添加请求拦截器,在请求头中加token 
axios.interceptors.request.use( 
  config => { 
    if (localStorage.getItem('token')) { 
      config.headers.token = localStorage.getItem('token'); 
    } 
    return config; 
  }, 
  error => { 
    return Promise.reject(error); 
  }); 
  
// 添加响应拦截器,移除token 
axios.interceptors.response.use( 
  response =>{ 
    return response; 
  }, 
  error=>{ 
    if(error.response){ 
      switch(error.response.status){ 
        case 401: 
          localStorage.removeItem('token'); 
          this.$router.push('/login'); 
      } 
    } 
  }) 
 
/* eslint-disable no-new */ 
new Vue({ 
  el: '#app', 
  router, 
  store, 
  components: { App }, 
  template: '<App/>' 
}) 

Vue 之路由配置

1、重点修改router文件夹下的index.js 文件,index.js 配置文件内容如下:

import Vue from 'vue' 
import Router from 'vue-router' 
import login from '@/components/login'; 
import home from '@/components/home'; 
// 新房管理 
import newHouse from '@/components/view/newHouse' 
// 二手房管理 
import secondHouse from '@/components/view/secondHouse' 
 
Vue.use(Router) 
 
const router = new Router({ 
  routes: [ 
    { 
      path: '/', 
      redirect: '/login' 
    }, 
    { 
      path: '/login', 
      name: 'login', 
      component: login 
    }, 
    { 
      path: '/home', 
      name: 'home', 
      component: home, 
      children: [{ 
        path: '/newHouse', 
        name: 'newHouse', 
        component: newHouse 
      }, 
      { 
        path: '/secondHouse', 
        name: 'secondHouse', 
        component: secondHouse 
      }] 
    } 
  ] 
}) 
 
// 导航守卫 
// 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆 
router.beforeEach((to, from, next) => { 
  if (to.path === '/login') { 
    next(); 
  } else { 
    let token = localStorage.getItem('token'); 
    if (token === null || token === '') { 
      next('/login'); 
    } else { 
      next(); 
    } 
  } 
}); 
 
export default router; 

Vue 组件之 login.vue(登入首页)

<template> 
   <div class="login-container"> 
    <el-form label-position="left" 
      label-width="0px" 
      status-icon> 
        <h3 class="login_title">系统登录</h3> 
        <el-form-item> 
          <el-input 
            type="text" 
            v-model="loginForm.username" 
            auto-coplete="off" 
            placeholder="账号"> 
          </el-input> 
        </el-form-item> 
        <el-form-item> 
          <el-input 
            type="password" 
            v-model="loginForm.password" 
            auto-coplete="off" 
            placeholder="密码"> 
          </el-input> 
        </el-form-item> 
        <el-form-item style="width: 100%"> 
          <el-button type="primary" @click.native.prevent="login" style="width: 100%">登录</el-button> 
          <!-- 
          <el-button type="primary" @click.native.prevent="register" style="width: 100%; margin-top: 30px">注册</el-button> 
          --> 
        </el-form-item> 
      </el-form> 
  </div> 
 
</template> 
  
<script> 
import { mapMutations } from 'vuex'; 
export default { 
  data () { 
    return { 
      loginForm: { 
        username: '', 
        password: '' 
      }, 
      userToken: '' 
    }; 
  }, 
  
  methods: { 
    // 调用store 存储 
    ...mapMutations(['changeLogin']), 
    login () { 
      let _this = this; 
      if (this.loginForm.username === '' || this.loginForm.password === '') { 
        alert('账号或密码不能为空'); 
      } else { 
        // 发起登入请求 
        this.$axios({ 
          method: 'post', 
          url: '/auth/login', 
          headers: { 
		     'Content-Type':'application/json;charset=utf-8'  
	      }, 
          data:{"username":_this.loginForm.username,"password":_this.loginForm.password}, 
        }).then(res => { 
          console.log('123456'); 
          console.log(res); 
          console.log(res.data.datas.token); 
          _this.userToken = res.data.datas.token; 
          // 将用户token保存到vuex中 
          _this.changeLogin({ token: _this.userToken }); 
          // 用户登入成功,自动跳转至系统首页 
          _this.$router.push('/home'); 
          alert('登陆成功'); 
        }).catch(error => { 
          alert('账号或密码错误'); 
          console.log(error); 
        }); 
      } 
    } 
  } 
}; 
</script> 
<style scoped> 
.login-container{ 
  border-radius: 15px; 
  background-clip: padding-box; 
  margin: 10% auto; 
  width: 350px; 
  padding: 35px 35px 15px 35px; 
  background: #fff; 
  border: 1px solid #eaeaea; 
  box-shadow: 0 0 25px #cac6c6; 
} 
.login_title{ 
  margin: 0px auto 40px auto; 
  text-align: center; 
  color: #505458; 
} 
</style>

Vue 组件之 home.vue(系统首页)

<style> 
.el-main { 
  background-color: #f5f7f9; 
} 
.el-header, 
.el-footer { 
  background-color: white; 
  box-sizing: border-box; 
  border-bottom: 1px solid #f5f1f1; 
} 
.el-container { 
  height: 100%; 
} 
</style> 
 
 <template> 
  <el-container> 
    <!-- header部分 --> 
    <el-header> 
      <navtop></navtop> 
    </el-header> 
    <el-container> 
       <!-- aside部分 --> 
      <leftNav></leftNav> 
      <el-main> 
         <!-- main部分 --> 
        <router-view /> 
      </el-main> 
    </el-container> 
  </el-container> 
</template> 
<script> 
import navtop from "@/components/part/nav-top.vue"; 
import leftNav from "@/components/part/nav.vue"; 
export default { 
  components: { 
    navtop, 
    leftNav 
  }, 
  data() { 
    return {}; 
  }, 
  methods: {} 
}; 
</script>

Vue 组件之 系统首页涉及公共页面(nav-top.vue 和nav.vue)

注意:在src/components/part 新增上述两个vue 文件

nav-top.vue

<style scoped> 
.el-aside { 
    display: flex; 
    justify-content: center; 
    align-items: center; 
} 
section{ 
  height: 100%; 
  display: flex; 
  justify-content: space-between; 
  align-items: center; 
  padding: 0 20px; 
} 
.logo { 
  width: 200px; 
} 
.headerLogo,.logo{ 
  cursor: pointer; 
} 
</style> 
 
<template> 
  <el-container> 
    <el-aside width="auto" class="header-logo tap" > 
      <img class="logo" src="@/assets/logo.png" alt="Logo" /> 
    </el-aside> 
    <el-aside width="auto" class="header-logo tap" > 
      <el-avatar icon="el-icon-user-solid" class="headerLogo"></el-avatar> 
    </el-aside> 
  </el-container> 
</template> 
 
<script> 
export default { 
  data() { 
    return { 
      activeIndex: "1", 
    }; 
  }, 
  methods: { 
    handleSelect(key, keyPath) { 
      console.log(key, keyPath); 
    } 
  } 
}; 
</script>

nav.vue

<style scoped> 
.el-row{ 
  height: 100%; 
} 
.el-menu{ 
  border-right:none; 
} 
.el-aside{ 
  border-right: 1px solid #f5f1f1; 
} 
</style> 
 
<template> 
  <el-aside width="200px"> 
    <el-row class="tac"> 
      <el-col> 
        <el-menu 
          default-active="1" 
          class="el-menu-vertical-demo" 
          @open="handleOpen" 
          @close="handleClose" 
        > 
          <el-menu-item index="1" @click="goPage('centre')"> 
            <i class="el-icon-menu"></i> 
            <span slot="title">首页</span> 
          </el-menu-item> 
 
          <el-submenu index="3"> 
            <template slot="title"> 
              <i class="el-icon-location"></i> 
              <span>房屋管理</span> 
            </template> 
            <el-menu-item-group> 
              <el-menu-item index="3-1" @click="goPage('newHouse')">新房管理</el-menu-item> 
            </el-menu-item-group> 
            <el-menu-item-group> 
              <el-menu-item index="3-2" @click="goPage('secondHouse')">二手房管理</el-menu-item> 
            </el-menu-item-group> 
          </el-submenu> 
        </el-menu> 
      </el-col> 
    </el-row> 
  </el-aside> 
</template> 
 
<script> 
var $this = {}; 
export default { 
  data() { 
    return {}; 
  }, 
  beforeCreate() { 
    $this = this; 
  }, 
  methods: { 
    handleOpen(key, keyPath) { 
      console.log(key, keyPath); 
    }, 
    handleClose(key, keyPath) { 
      console.log(key, keyPath); 
    }, 
    goPage(link) { 
    // 跳转至首页 
      if (link === "centre") { 
        $this.$router.push("/centre").catch(error => error); 
      } 
      // 跳转至会员管理  
      else if ((link === "newHouse")) { 
        $this.$router.push("/newHouse").catch(error => error); 
      }  
      // 跳转至收获地址 
      else if ((link === "secondHouse")) { 
        $this.$router.push("/secondHouse").catch(error => error); 
      }  
      
    } 
  } 
}; 
</script>

Vue 组件之业务组件

注意:在src/components/view 新增上述业务组件Vue

业务组件之newHouse.vue(新房管理)

<style> 
</style> 
<template> 
  <div id="new_house"> 
    <h1>新房管理</h1> 
  </div> 
</template> 
 
<script> 
export default{ 
    name: 'new_house' 
} 
</script>

业务组件之secondHouse.vue(二手房管理)

<style> 
</style> 
<template> 
  <div id="second_house"> 
    <h1>二手房管理</h1> 
  </div> 
</template> 
 
<script> 
export default{ 
    name: 'second_house' 
} 
</script>

Vue 后台租房管理系统功能演示:

 

 

标签:VUE
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号