Spring Boot + Vue +Three.js综合案例(上)--前端开发

前端开发----vue

首先附上Vue生命周期图
在这里插入图片描述


一、项目的搭建

使用 vue-cli 脚手架搭建工程步骤步骤:
默认已经安装好npm,我的版本
在这里插入图片描述

  1. 以管理员身份运行cmd,全局安装vue-cli
npm install -g @vue/cli  //安装vue cli
vue --version 			 //查看版本

在这里插入图片描述

  1. 选择一个文件目录,存放项目,进入该目录的cmd命令提示符,输入下列命令,等待配置
vue create 工程名(只能使用英文、数字、短横线,不支持中文,特殊字符)

在这里插入图片描述
选择预设配置:1.默认;2.手动;(可以使用键盘的上下选择,回车确定配置)
我选择了手动配置…

  1. 进入下列选项,选择你需要的配置,键盘上下选择,空格确定,回车进入下一个配置
    在这里插入图片描述
    在这里插入图片描述
    常用配置:
    Babel:配置兼容性,可以让ES6+编译为ES5
    Router:配置路由
    Vuex:状态管理
    我只选择了Babel…

  2. 选择完成后,在选择配置放置位置,选择第二个in package.json
    在这里插入图片描述

  3. 是否保留预设配置,否N,回车,等待项目搭建完成。
    在这里插入图片描述
    至此一个vue项目搭建完成,就可以关掉命令窗口了
    在这里插入图片描述


二、项目工程结构

使用HBuilderX从存放目录导入该项目,(–部分为自己创建的,其他是自动生成。

---node-modules                                          	...外部库依赖
---public
	---favicon.ico											...vue的图标
	---index.html											...静态页面,首页
---src
	---main.js												...入口函数
	---App.vue												...根组件
	---components											...子组件文件夹
	---assets												...静态文件夹,如图片等
	(--router												...路由配置文件夹
	(--service												...请求服务配置文件夹
	(--store												...状态管理配置文件夹
	(--views												...视图文件夹
---.gitignore												...代码管理仓库地址
---babel.config.js											...配置兼容性
---package.json												...工程信息,如外部依赖,项目版本等
---package-lock.json										...依赖版本
---README.md												...说明文档

点击HX功能栏(运行–>运行到终端–>1.npm run build–构建打包项目;2.npm run server–构建完成直接运行 )
也可以在该目录的cmd中,输入这些命令,最后获得项目的服务器地址
在这里插入图片描述
初始项目效果如图
在这里插入图片描述

三、开始编码工作

  1. 安装可能需要的依赖,进入工程目录的cmd,安装vue-router,vuex,axios
npm i vue-router		//路由
npm i vuex				//状态管理
npm i axios				//http库

在这里插入图片描述

  1. 项目文件内容
  • 在src目录下,新建文件夹views–视图层,之下新建Login.vue(登录页面)、Personal.vue(个人中心页面,登录成功后方可进入)、Auth.vue(登录验证页面,受保护的页面如Personal.vue必须进过该页面验证才能进入)、NotFound.vue(404页面)、Example1…2…3.vue(three.js小案例)
  • 在src目录下,新建文件夹router–路由配置,之下新建index.js(路由基本配置),新建文件夹store–状态管理,之下新建index.js(状态管理基本配置)、loginUser.vue(登录用户状态管理),新建文件夹service(http请求服务),之下新建userService.js(用户登录请求服务)。
  • 在components子组件下,Center.vue实现任意内容居中,FormError.vue实现表单错误提示
    在这里插入图片描述
  1. 代码部分

①配置路由

src/router/index.js,路由配置文件

import Vue from "vue";					//引入Vue
import VueRouter from "vue-router";		//引入vue-router

import store from "../store";

//1.安装
Vue.use(VueRouter);

//2.创建路由对象
let router=new VueRouter({//相关配置
	mode:"history",//路由模式
	routes:[
		{
			name:"Example1",
			path:"/",				
			component:()=>import('@/views/Example1.vue'),
		},
		{
			name:"Example2",
			path:"/example2",				
			component:()=>import('@/views/Example2.vue'),
		},
		{
			name:"Example3",
			path:"/example3",				
			component:()=>import('@/views/Example3.vue'),
		},
		{
			name:"Login",								//页面自定义名称
			path:"/login",									//页面路径
			component:()=>import('@/views/Login.vue')	//导入页面
		},
		{
			name:"Auth",//登录验证页面
			path:"/auth",
			component:()=>import ('@/views/Auth.vue'),
		},
		{
			name:"Personal",
			path:"/personal",				
			component:()=>import('@/views/Personal.vue'),
			meta:{//需要验证登录的页面
				auth:true
			}
		},
		{
			name:"404",
			path:"*",//匹配所有路径
			component:()=>import ('@/views/NotFound.vue')
		}
	]
});

router.beforeEach(function(to,from,next){//导航守卫,验证登录
	if(to.meta.auth){
		if(store.state.loginUser.isLogin){
			next({
				name:'Auth',
				query:{
					nextUrl:to.fullPath
				}
			});
		}else if(store.state.loginUser.data){
			next();
		}else{
			next({name:'Login'});
		}
	}else{
		next();
	}
});

//3.导出配置,在main.js配置路由到vue实例中
export default router;

路由模式:
1.Hash:路径来自于地址栏中#后面的值,这种兼容性比较好;
2.History:路径来自于真实的地址路劲,旧浏览器不兼容
3.Abstract:路径来自于内存

src/main.js,程序入口设置

import Vue from 'vue';
import App from './App.vue';

import './assets/css/global.css';

import router from "./router/index.js";		//引入路由
import store from "./store/index.js";		//引入状态管理

Vue.config.productionTip = false;

//获取登录数据
store.dispatch("loginUser/getUserInfo");

new Vue({
  render: h => h(App),
  router,		
  store 		
}).$mount('#app');

src/APP.vue,配置路由出入口

<template>
  <div id="app">
	  <header>
		  <div class="container">
			  <div class="title">
				  SpingBoot+Vue+Three.js
			  </div>
			  <ul class="nav">
				  <li v-for="item of nav" :key="item.id">
					  <!-- 命名导航-->
					<router-link :to="{name:item.url}">{{item.name}}</router-link>				  
				  </li>
			  </ul>
			  <div class="user">
				  <template v-if="userInfo">
					  <router-link :to="{name:'Personal'}" class="a-link">用户:{{userInfo.username}}</router-link>
					  <a href="" @click.prevent="logout()" class="a-link">注销</a>
				  </template>
				  <template v-else>
					  <router-link :to="{name:'Login'}" class="a-link">登录</router-link>
				  </template>			  
			  </div>			  
		  </div>
	  </header>

	  <!-- 路由的出入口,该标签会根据不同的访问路径,渲染不同的组件-->
		<router-view></router-view>
  </div>
</template>

<script>
import {mapState} from 	'vuex';
	
export default {
  name: 'App',
  components: {

  },
  data(){
	  return{
		  nav:[
			  {
				  id:"001",
				  name:"three.js案例一",
				  url:"Example1"
			  },
			  {
				  id:"002",
				  name:"three.js案例二",
				  url:"Example2"
				  
			  },
			  {
				  id:"003",
				  name:"three.js案例三",
				  url:"Example3"
			  },
		  ]
	  }
  },
  computed:mapState("loginUser",{
	  userInfo:'data'
  }),
  methods:{
	  logout(){
		  this.$store.dispatch("loginUser/logout");
		  this.$router.push({name:'Login'});
	  }
  }
}
</script>

<style scoped="scoped">
	#app{
		height: 100%;
		width: 100%;
	}
	header{
		height: 60px;
		background: #000;
		color:#fff;
		position: fixed;
		z-index: 100;
		width: 100%;
		border-bottom: 1px solid #fff;
		display: flex;
		justify-content: center;
	}
	.container{
		display: flex;
		width: 80%;
	}
	.title{
		display: flex;
		height: 100%;
		align-items: center;
		font-size: 25px;
	}
	.nav{
		display: flex;
		align-items: center;
		margin: 0 60px;
		width: 700px;
		list-style: none;
	}
	.nav li{
		padding: 0 30px;
	}
	.router-link-exact-active{
		color: #fcb85f;
	}
	.a-link{
		margin-left: 10px;
		color:#fff;
		font-size: 13px;
	}
	.user{
		display: flex;
		align-items: center;
	}

</style>

②设置请求服务

src/service/userService.js,用户登录请求服务

import axios from 'axios';

//登录
async function login(userInfo){
	//post方法获取登录信息
	let resp=await axios.post('http://127.0.0.1:8089/springboot_vue/loginCheck',userInfo);
	//获取服务器授权码
	let token=resp.headers.authorization;
	if(token){
		localStorage.setItem("token",token);
	}
	return resp.data;
}

//注销
function logout(){
	localStorage.removeItem("token");
}

//使用保存的令牌从服务器获取登录信息
async function getUserInfo(){
	let token=localStorage.getItem("token");
	if(token){
		let resp=await axios.get("http://127.0.0.1:8089/springboot_vue/getUserInfo",{
			headers:{
				authorization:`${token}`
			}
		});
		return resp.data.data;
	}else{
		return null;
	}
}

export {
	login,
	logout,
	getUserInfo
}

③配置状态管理

src/store/index.js,状态管理基本配置

import Vue from 'vue';
import vuex from 'vuex';

import loginUser from './loginUser.js';//引入用户登录信息配置

//1.安装
Vue.use(vuex);

//2.创建vuex的状态管理对象
let store=new vuex.Store({//配置
	modules:{
		loginUser,
	}
});

//3.导出配置,在main.js注入到vue实例中
export default store;

src/store/loginUser.js,登录用户状态管理

import {login,logout,getUserInfo} from '../service/userService.js';

export default{
	namespaced:true,//开启命名空间
	state:{
		isLogin:false,//是否正在登录
		data:null//登录用户信息		
	},
	mutations:{
		setData(state,payload){
			state.data=payload;
		},
		setIsLogin(state,payload){
			state.isLogin=payload;
		}
	},
	actions:{
		async login(context,payload){
			context.commit('setIsLogin',true);
			let resp=await login(payload);
			let result=false;
			if(resp.code===0){//登录成功
				context.commit('setData',resp.data);
				result=true;
			}
			context.commit('setIsLogin',false);
			return result;
		},
		logout(context){
			logout();
			context.commit('setData',null);
		},
		async getUserInfo(context){
			context.commit('setIsLogin',true);
			let resp=await getUserInfo();
			context.commit('setData',resp);
			context.commit('setIsLogin',false);
		}
	}
}

④基本页面

src/view/Auth.vue,登录验证页面

<template>
	<Center>
		<h1>登录验证中...</h1>
	</Center>
</template>

<script>
	import Center from "../components/Center.vue";
	import {mapState} from "vuex";
	
	export default{
			components:{
				Center
			},
			computed:mapState("loginUser",["data","isLogin"]),
			methods:{
				handleLogin(){
					if(this.isLogin){
						return;
					}
					if(this.data){
						if(this.$route.query.nextUrl){
							this.$router.push(this.$route.query.nextUrl);
						}else{
							this.$router.push({name:"Personal"});
						}
					}else{
						this.$router.push({name:"Login"});
					}
				}
			},
			watch:{
				isLogin:{
					immediate:true,
					handler(){
						this.handleLogin();
					}
				},
			}
		}
</script>

<style>
</style>

使用watch的注意事项:1.当监听的数据不是一个简单的基本类型,比如一个对象,一个数组,此时应该使用深度监听:deep:true;2.当想让监听器一启动就触发一次watch,应该使用: immediate: true。

src/view/Login.vue,登录页面

<template>
	<Center>
		<h2>登录页面Login.vue</h2>
		<form class="login-container" @submit.prevent="handleSubmit()">
			<div class="form-item">
				<div class="input">
					<label>账号:</label>
					<input type="text" v-model="userInfo.username" @input="validateEmpty('username','请输入用户名')"/>
				</div>
				<FormError :msg="errorInfo.username"></FormError>
			</div>
			<div class="form-item">
				<div class="input">
					<label>密码:</label>
					<input type="password" v-model="userInfo.password" @input="validateEmpty('password','请输入密码')"/>
				</div>
				<FormError :msg="errorInfo.password"></FormError>
			</div>
			<div class="form-item">
				<div class="input">
					<label></label>
					<button>{{$store.state.loginUser.isLogin ? '登陆中...' : '登录'}}</button>
				</div>
				<FormError :msg="errorInfo.server" :isCenter="true"></FormError>
			</div>
		</form>
	</Center>
</template>

<script>
	import Center from '../components/Center.vue';
	import FormError from '../components/FormError.vue';
	
	import axios from 'axios';
	
	export default{
		name:'Login',
		components:{
			Center,
			FormError
		},
		data(){
			return{
				userInfo:{
					username:"",
					password:""
				},
				errorInfo:{
					username:"",
					password:"",
					server:""
				}
			}
		},
		methods:{
			validateEmpty(field,msg){//输入非空验证,field元素名,msg错误信息
				if(this.userInfo[field]){
					this.errorInfo[field]="";
					return true;
				}else{
					this.errorInfo[field]=msg;
					return false;
				}
			},
			async handleSubmit(){
				if(
					this.validateEmpty('username','请输入用户名')
				&&	this.validateEmpty('password','请输入密码')
				){
					let result=await this.$store.dispatch('loginUser/login',this.userInfo);
					if(result){
						alert("登录成功!");
						this.$router.push({name:"Personal"})
					}else{
						this.errorInfo.server="用户名或密码错误";
					}								
				}				
			}
		}
	}
</script>

<style scoped="scoped">
	.login-container{
		margin-top: 50px;
		width: 400px;
	}
	.input{
		display: flex;
	}
	label{
		width: 56px;
		display: inline-block;
		font-size: 18px;
		line-height: 40px;
	}
	input,button{
		border: 1px solid #ccc;
		flex-grow: 1;
		border-radius: 5px;
	}
	button{
		font-size:16px;
		background-color: #409EFF;
		color:#FFFFFF;
		line-height: 40px;		
	}
</style>

登录页面
登录页面


Spring Boot + Vue +Three.js综合案例(中)–后端开发

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值