快速搭建前端页面
1 Vue
前置:
需要先包含node环境
如果没有,可去node官网下载一个并配置
node官网地址:https://nodejs.org/zh-cn/
# 检测是否安装成功node -v
1.1 vue脚手架
- 检测是否有node环境,如果没有则去node官网下载配置【进入cmd执行以下命令】
node -v
- 安装vue脚手架
npminstall -g @vue/cli
# 检测是否安装成功
vue --version
- 创建项目
# 全局安装初始化命令npm i -g @vue/cli-init
# 创建项目
vue init webpack 文件夹名称
如果当前文件夹已经存在会提示Target directory exists. Continue? 是否在当前目录下创建,输入yes表示同意
# 项目名
Project name -- testpro
# 项目描述
Project description -- A Vue.js project
# 作者
Author -- ziyi
# build选项
Vue build ("通过上下箭头选择")
- Runtime+Compiler 运行加编译【建议】
- Runtime-only 仅运行
# 是否安装路由【输入y或者n即可】
Install vue-router(Y/n)# 是否使用ESLint(代码风格校验工具)
Use ESLint to lint your code?(Y/n)# 是否设置单元测试
Set up unit tests (Y/n)# 是否设置端到端测试
Setup e2e tests with Nightwatch (Y/n)# 使用什么管理包
Should we run `npminstall`for you after the project has been created?
- Yes, use NPM (使用npm包管理)
- Yes, use Yarn (使用yarn包管理)
- No, I will handle that myself (自己处理)
- 项目初始化并启动
切记一定要进入项目的文件夹,否则会报找不到
package.json
cd work(进入项目所在文件夹)
# 启动项目npm run dev
5. 连接链接,访问
项目结构:
1.2 vue+elementUi实现注册登录
首先已经通过1.1的vue脚手架搭建好了vue基本框架,通是编写对应js
# 安装element-uinpm i element-ui -S
vue项目结构介绍:
①新建vue文件
新建两个Vue文件,Login.vue和Register.vue
Login.vue:
<template><divclass="loginbody"><divclass="logindata"><divclass="logintext"><h2>Welcome</h2></div><divclass="formdata"><el-formref="form":model="form":rules="rules"><el-form-itemprop="username"><el-inputv-model="form.username"clearableplaceholder="请输入账号"></el-input></el-form-item><el-form-itemprop="password"><el-inputv-model="form.password"clearableplaceholder="请输入密码"show-password></el-input></el-form-item></el-form></div><divclass="tool"><div><el-checkboxv-model="checked"@change="remenber">记住密码</el-checkbox></div><div><spanclass="shou"@click="forgetpas">忘记密码?</span></div></div><divclass="butt"><el-buttontype="primary"@click.native.prevent="login('form')">登录</el-button><el-buttonclass="shou"@click="register">注册</el-button></div></div></div></template><script>import{ login }from"@/api/login";exportdefault{name:"Login",data(){return{form:{password:"",username:"",},checked:false,rules:{username:[{required:true,message:"请输入用户名",trigger:"blur"},{max:10,message:"不能大于10个字符",trigger:"blur"},],password:[{required:true,message:"请输入密码",trigger:"blur"},{max:10,message:"不能大于10个字符",trigger:"blur"},],},};},mounted(){if(localStorage.getItem("news")){this.form =JSON.parse(localStorage.getItem("news"));this.checked =true;}},methods:{login(form){this.$refs[form].validate((valid)=>{if(valid){login(this.form).then((res)=>{if(res.code ===200){setToken(res.data.token);
localStorage.setItem("USERNAME", res.data.username);this.$message({message:"登录成功啦",type:"success",showClose:true,});this.$router.replace("/");}else{this.$message({message:"账户名或密码错误",type:"error",showClose:true,});}}).catch((err)=>{this.$message({message:"账户名或密码错误",type:"error",showClose:true,});});}else{returnfalse;}});},remenber(data){this.checked = data;if(this.checked){
localStorage.setItem("news",JSON.stringify(this.form));}else{
localStorage.removeItem("news");}},forgetpas(){this.$message({type:"info",message:"功能尚未开发额😥",showClose:true,});},register(){//跳转到注册页面this.$router.push({path:`register`})},},};</script><stylescoped>.loginbody{width: 100%;height: 100%;min-width: 1000px;background-image:url("../assets/login.png");background-size: 100% 100%;background-position: center center;overflow: auto;background-repeat: no-repeat;position: fixed;line-height: 100%;padding-top: 150px;}.logintext{margin-bottom: 20px;line-height: 50px;text-align: center;font-size: 30px;font-weight: bolder;color: white;text-shadow: 2px 2px 4px #000000;}.logindata{width: 400px;height: 300px;transform:translate(-50%);margin-left: 50%;}.tool{display: flex;justify-content: space-between;color: #606266;}.butt{margin-top: 10px;text-align: center;}.shou{cursor: pointer;color: #606266;}</style>
Register.vue:
<template><divclass="login clearfix"><divclass="login-wrap"><el-rowtype="flex"justify="center"><el-formref="loginForm":model="user"status-iconlabel-width="80px"><h3>注册</h3><hr><el-form-itemprop="username"label="用户名"><el-inputv-model="user.username"placeholder="请输入用户名"></el-input></el-form-item><el-form-itemprop="email"label="邮箱"><el-inputv-model="user.email"placeholder="请输入邮箱"></el-input></el-form-item><el-form-itemprop="password"label="设置密码"><el-inputv-model="user.password"show-passwordplaceholder="请输入密码"></el-input></el-form-item><el-form-item><el-buttontype="primary"icon@click="doRegister()">注册账号</el-button></el-form-item></el-form></el-row></div></div></template><script>import axios from"axios";exportdefault{name:"login",data(){return{user:{username:"",email:"",password:""},};},created(){// console.log($);// console.log("1111");},methods:{doRegister(){if(!this.user.username){this.$message.error("请输入用户名!");return;}elseif(!this.user.email){this.$message.error("请输入邮箱!");return;}elseif(this.user.email !=null){var reg =/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;if(!reg.test(this.user.email)){this.$message.error("请输入有效的邮箱!");}elseif(!this.user.password){this.$message.error("请输入密码!");return;}else{// this.$router.push({ path: "/" }); //无需向后台提交数据,方便前台调试
axios
.post("/register/",{name:this.user.username,email:this.user.email,password:this.user.password
}).then(res=>{// console.log("输出response.data", res.data);// console.log("输出response.data.status", res.data.status);if(res.data.status ===200){this.$router.push({path:"/"});}else{alert("您输入的用户名已存在!");}});}}}}};</script><!-- Add "scoped" attribute to limit CSS to this component only --><stylescoped>.login{width: 100%;height: 740px;background-size: cover;overflow: hidden;}.login-wrap{background-size: cover;width: 400px;height: 300px;margin: 215px auto;overflow: hidden;padding-top: 10px;line-height: 20px;}h3{color: #0babeab8;font-size: 24px;}hr{background-color: #444;margin: 20px auto;}.el-button{width: 80%;margin-left: -50px;}</style>
②新建js文件
login.js:
登录请求是通过引入外部js实现,注册请求则是通过写入vue页面中的script实现,没有做复用【当然也可以封装到外部,写在login.js或register.js中】
import Axios from"axios";import{get, post}from"./http";// post 请求exportconstlogin=(params)=>post(`login`, params)
③添加路由配置
添加路由配置
router文件夹下的index.js
一定要加上
mode: "history"
,同时要import组件
index.js:
import Vue from'vue'import Router from'vue-router'import HelloWorld from'@/components/HelloWorld'import Register from'@/components/Register'import Login from'@/components/Login'
Vue.use(Router)exportdefaultnewRouter({routes:[// {// path: '/',// name: 'HelloWorld',// component: HelloWorld// },{path:'/',name:'Login',component: Login
},{path:'/register',name:'Register',component: Register
}],mode:"history"})
path:是指跳转路径,name是名称,component是组件名(对应.vue文件)
例如:/register表示如果路径是localhost:8080/register,就跳转到Register.vue文件夹下
④实例化vue对象,引入axios
实例化vue对象,引入需要使用的工具,如:axios、element-ui等
main.js:
import Vue from'vue'import App from'./App'import router from'./router'import axios from'axios'import ElementUI from'element-ui';import'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)//全局配置Vue.prototype.$axios = axios
Vue.config.productionTip =false/* eslint-disable no-new */newVue({el:'#app',
router,components:{ App },template:'<App/>'})
⑤效果
登录页面:
注册页面:
图片自取,页面图片,放在assets下,并命名为
login.png
:
拓展:操作js(与后端交互)
①封装http请求
src/api/http.js
http.js:
// 封装通用请求import axios from'axios'import router from'../router'
axios.defaults.timeout =5000// 超时时间:5s
axios.defaults.withCredentials =true// 允许跨域// Content-Type 响应头
axios.defaults.headers.post['Content-Type']='application/x-www.form-urlencoded;charset=UTF-8'// 访问基础url
axios.defaults.baseURL ='http://localhost:8090'// 响应拦截器
axios.interceptors.response.use(response=>{// 如果response里面的status是200,说明访问到接口了,否则失败if(response.status ===200){// Promise:异步框架return Promise.resolve(response)}else{return Promise.reject(response)}},error=>{if(error.response.status){// 根据访问失败返回的状态码,分别做不同的处理switch(error.response.status){case401:// 未登录
router.replace({path:'/',query:{redirect: router.currentRoute.fullPath // 存之前访问地址}})breakcase404:// not foundbreak}return Promise.reject(error.response)}})/**
* 封装get请求
*/exportfunctionget(url, params ={}){returnnewPromise((resolve, reject)=>{
axios.get(url,{params: params}).then(response=>{resolve(response.data)}).catch(err=>{reject(err)})})}/**
* 封装post请求
*/exportfunctionpost(url, data ={}){returnnewPromise((resolve, reject)=>{
axios.post(url, data).then(response=>{resolve(response.data)}).catch(err=>{reject(err)})})}
②定义请求的js
例如文件为:index.js【文件放在src/api/index.js】
//查询所有歌手【普通的get请求,不带参数】exportconstgetAllSinger=()=>get(`singer/selectAll`)//根据歌手性别查询【带参数的get请求】exportconstgetSingerOfSex=(sex)=>get(`singer/selectSingerOfSex?sex=${sex}`)//返回当前的评论列表【根据传参发送不同请求】exportconstgetAllComment=(type, id)=>{if(type ==0){//type: 0 歌曲returnget(`comment/commentOfSongId?songId=${id}`);}else{//歌单returnget(`comment/commentOfSongListId?songListId=${id}`);}}//新增收藏【post请求】exportconstsetCollect=(params)=>post(`collect/add`, params);//下载音乐【异步请求】exportconstdownload=(url)=>Axios({method:'get',url: url,responseType:'blob'})
③在页面中引入并使用
在xxx.vue的<script>标签中引入对应的js
import {getAllSinger} from '../api/index';
在Singer.vue中的script标签中引入对应的js方法,一般我们都会多封装一层【getAllSinger被封装为getSingerList】
// export const getAllSinger = () => get(`singer/selectAll`)<script>import ContentList from"../components/ContentList";import{getAllSinger}from'../api/index';import{mixin}from"../mixins";import{singerStyle}from'../assets/data/singer';exportdefault{name:'singer',components:{
ContentList
},data(){return{albumDatas:[],//歌手数据pageSize:10,//页面大小currentPage:1,singerStyle:[],//歌手类型activeName:'全部歌手',//当前风格【类型】}},computed:{//计算当前表格中的数据data(){returnthis.albumDatas.slice((this.currentPage -1)*this.pageSize,this.currentPage*this.pageSize)}},mounted(){this.singerStyle = singerStyle;this.getSingerList();},methods:{//获取歌手列表getSingerList(){getAllSinger().then(res=>{this.currentPage =1;this.albumDatas = res;})}}}</script>
2 Element-UI
2.1 提交表单
SongListPage.vue:
//html部分
<el-dialogtitle="添加歌单":visible.sync="centerDialogVisible"width="400px"center><el-form:model="registerForm"ref="registerForm"label-width="80px"><el-form-itemprop="title"label="标题"size="mini"><el-inputv-model="registerForm.title"placeholder="标题"></el-input></el-form-item><el-form-itemlabel="歌单风格"prop="style"><el-selectv-model="registerForm.style"placeholder="请选择歌曲风格"><el-optionlabel="流行":value="'流行'"></el-option><el-optionlabel="摇滚":value="'摇滚'"></el-option><el-optionlabel="古典":value="'古典'"></el-option></el-select></el-form-item></el-form><spanslot="footer"><el-buttonsize="mini"@click="centerDialogVisible = false">取消</el-button><el-buttonsize="mini"@click="addSongList">确定</el-button></span></el-dialog>
其中,el-select的registerForm.style对应的是script中data的registerForm的style,el-form-item对应传给后端的属性名
//js 部分<script>import{ getAllSongList, setSongList, updateSongList, delSongList}from'../api/index';import{mixin}from'../mixins/index';exportdefault{mixins:[mixin],data:function(){return{registerForm:{//添加框title:'',introduction:'',style:''},};},methods:{//添加歌单addSongList(){let params =newURLSearchParams();
params.append('title',this.registerForm.title);
params.append('pic','/img/songListPic/songList1.png');
params.append('introduction',this.registerForm.introduction);
params.append('style',this.registerForm.style);setSongList(params).then(res=>{if(res.code ==1){this.getData();this.notify("添加成功","success");}else{this.notify("添加失败","error");}}).catch(err=>{
console.log(err);});//添加成功之后清除添加框this.registerForm ={}},}}</script>
版权归原作者 NPE~ 所有, 如有侵权,请联系我们删除。