本文讲解如何使用vue制作一个比较好看的vue前端项目。
打开vue ui开始创建项目
手动创建项目
目前大概这样选择
选择vue2的版本
选择less
点击新建项目,不保存预设
等待即可
创建完成之后的样子
先编译一下看一下这个有没有问题,是否可以正常打开
可以正常打开,好耶
在根目录下创建一个vue.config.js文件
输入以下内容
module.exports = {
devServer: {
host: "localhost", //指定要使用的 host
port: 80, //指定端口号以侦听
hotOnly: false, //启用热模块替换,而无需页面刷新作为构建失败时的回退。
},
};
首先是先把需要导入的js文件,这里是main.js, 这里面引入的axios,element-ui等依赖都可以通过vue ui里面进行下载。
完整代码
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Element from 'element-ui'
import axios from 'axios'
//引用全局
Vue.prototype.$axios = axios
import "element-ui/lib/theme-chalk/index.css"
import "./axios"
Vue.use(Element)
Vue.config.productionTip = false
Vue.prototype.$axios = axios
new Vue({
router,
axios,//注册axios
store,
render: h => h(App)
}).$mount('#app')
这里登录页面的vue文件,在这个文件中,当用户点击登录了之后,就会出发登录事件,触发之后,会把他的账号的信息发送到后端,然后进行处理。
<template>
<div id="background">
<div id="logo"> <i>极客李华的项目</i></div>
<div id="login">
<el-card class="box-card">
<div id="form">
<el-input
v-model="user.username"
placeholder="请输入账号"
></el-input>
<el-input
v-model="user.password"
placeholder="请输入密码"
show-password
></el-input>
<el-button
type="primary"
v-on:click="login"
>登录</el-button>
<el-button
type="primary"
v-on:click="toregister"
>注册</el-button>
</div>
</el-card>
</div>
</div>
</template>
<style scoped>
#background {
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-image: linear-gradient(90deg, rgb(0, 162, 255), rgb(128, 0, 107));
background-size: 400%;
animation: myanimation 10s infinite;
}
@keyframes myanimation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
#logo {
color: aliceblue;
font-size: 88px;
font-weight: 800;
position: absolute;
top: 8%;
left: 12%;
}
#login {
position: absolute;
top: 30%;
left: 35%;
}
.el-card {
width: 473px;
height: 280px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 15px;
}
#form {
line-height: 82px;
padding-left: 15px;
padding-right: 15px;
}
#clock {
color: aliceblue;
position: absolute;
top: 80%;
left: 15%;
}
#time {
font-size: 20px;
}
#date {
font-size: 20px;
}
#copyright {
color: aliceblue;
position: absolute;
top: 95%;
left: 37%;
}
</style>
<script>
import axios from "axios";
export default {
data() {
return {
user: {
id:"",
username: "lihua",
password: "123456",
avatar:""
},
};
},
mounted() {
this.$nextTick(() => {
setInterval(this.update_clock, 1000);
});
},
methods: {
login() {
this.$axios.post("/user/login", this.user).then(
(response) => {
if (response.data.code == 200) {
this.user = response.data.data
// console.log(response.data.data)
console.log("id:" + this.user.id)
// 把用户的信息存储到浏览器中 记得需要存储JSON形式
window.sessionStorage.setItem("user", JSON.stringify(this.user))
const users = JSON.stringify(this.user);
console.log("Login")
console.log(users)
console.log(response.data)
this.$router.push({path:"/Notes"});
} else {
this.$alert("账号或密码错误,请重新输入!");
}
},
(error) => {
console.log(error.message);
}
);
},
toregister() {
this.$router.push("/register");
},
},
};
</script>
登录页面效果如下,简直完美,我们这里默认设置的有一个账号,这样便于每次的测试功能
这里是注册页面,首先注册页面会把账号发送给后端,检查账号是否存在,注册成功了之后就返回登录页面。
<template>
<div id="background">
<div id="logo"><i>极客李华的课设</i></div>
<div id="register">
<el-card class="box-card">
<div id="form">
<el-input v-model="user.username" placeholder="请输入账号"></el-input>
<el-input placeholder="请输入密码" v-model="user.password" show-password></el-input>
<el-input placeholder="请再次输入密码" v-model="repassword" show-password></el-input>
<el-button type="primary" v-on:click="register">注册</el-button>
</div>
</el-card>
</div>
</div>
</template>
<style scoped>
#background{
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-image: linear-gradient(
90deg,
cyan,
purple
);
background-size: 400%;
animation: myanimation 10s infinite;
}
@keyframes myanimation{
0%{
background-position: 0% 50%;
}
50%{
background-position: 100% 50%;
}
100%{
background-position: 0% 50%;
}
}
#logo{
color: aliceblue;
font-size: 88px;
font-weight: 800;
position: absolute;
top: 8%;
left: 12%;
}
#register{
position: absolute;
top: 20%;
left: 35%;
}
.el-card{
width: 473px;
height: 600px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 15px;
}
#form{
line-height: 82px;
padding-left: 15px;
padding-right: 15px;
}
</style>
<script>
import axios from 'axios';
export default {
data(){
return{
user: {
username:"",
password:"",
},
repassword:"",
}
},
mounted(){
},
methods:{
register(){
if(this.user.username === null || this.user.username.trim() === ""){
this.$alert('账号不能为空')
} else if(this.user.password === null || this.user.password.trim() === ""){
this.$alert('密码不能为空')
} else if(this.user.password != this.repassword){
this.$alert('两次密码不一致')
}else{
axios.post('/user/register', this.user).then(
response => {
if (response.data.code == 200) {
this.$router.push("/")
location.href = "http://localhost:8080/"
} else {
this.$alert('昵称或者账号已存在')
}
},
)
}
},
},
}
</script>
运行效果,可以看出,我还设置了确认密码的功能,简直完美。
系统架构,通过components组件库,我们可以编写很多的组件,然后更加便于我的解耦合,然后更加便于我们的后面的网页的简洁快速的开发。
这个是公共的头的组件,这个组件为后面的NoteView.vue,NoteViewFinish.vue,NoteViewNotFinish.vue提供公共的头。
完整代码如下
<template>
<div class="m-content">
<h3>欢迎来到{{ user.username }}的备忘录</h3>
<div class="block">
<el-avatar :size="50" :src="user.avatar"></el-avatar>
</div>
<div class="maction">
<span><el-link href="/Notes">主页</el-link></span>
<el-divider direction="vertical"></el-divider>
<span><el-link type="success" href="/NoteAddView">发布备忘录</el-link></span>
<el-divider direction="vertical"></el-divider>
<span v-show="!hasLogin"><el-link type="primary" href="/NoteViewFinish">已完成</el-link></span>
<el-divider direction="vertical"></el-divider>
<span v-show="!hasLogin"><el-link type="danger" href="/NoteViewNotFinish">未完成</el-link></span>
<el-divider direction="vertical"></el-divider>
<span v-show="!hasLogin"><el-link type="primary" href="/NoteTypeView">根据类型查询</el-link></span>
<el-divider direction="vertical"></el-divider>
<span v-show="!hasLogin"><el-link type="danger" @click="logout">退出</el-link></span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user: {
id:"",
username: "lisi",
password: "",
avatar:""
},
hasLogin: false
}
},
methods: {
logout() {
location.href = "http://localhost:8080/"
window.sessionStorage.removeItem("user")
}
},
created() {
const users = window.sessionStorage.getItem("user")
this.user = JSON.parse(users)
}
}
</script>
<style scoped>
.m-content {
max-width: 960px;
margin: 0 auto;
text-align: center;
}
.maction {
margin: 10px 0;
}
</style>
运行结果,这个功能的头部就是这个页面红色框框中的部分,很美观简洁
表单信息的公共组件,这个组件在添加与更新中是公共的存在,然后在这个组件中,我还给输入的类型没有写死,是根据后端传送的情况定制的。
<template>
<el-card>
截止日期:
<input type="date" v-model="notes.time">
<p></p>
备忘录内容:<el-input v-model="notes.detail" placeholder="请输入内容"></el-input>
<p></p>
输入类型:
<p></p>
<el-radio-group v-model="notes.type" v-for="i in typesid">
<el-radio :label="i">{{types[i]}}</el-radio>
<!-- <el-radio :label="2">学习</el-radio>-->
<!-- <el-radio :label="3">健身</el-radio>-->
</el-radio-group>
<p></p>
是否完成:
<el-switch
v-model="notes.finish"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
<p></p>
<el-button type="primary" round @click="add()">提交</el-button>
</el-card>
</template>
<script>
export default {
name: "Table.vue",
data() {
return {
user:{},
notes:{},
typesid:[],
types:[]
}
},
methods:{
getTypes(){
this.$axios.get("/getMapping").then(res =>{
console.log(res.data)
let map = res.data
for (const mapKey in map) {
// console.log(mapKey)
// console.log(map[mapKey])
this.typesid.push(mapKey)
this.types.push(map[mapKey])
}
console.log(this.typesid)
})
}
},
created() {
const users = window.sessionStorage.getItem("user")
this.user = JSON.parse(users)
this.getTypes()
}
}
</script>
<style scoped>
.m-content {
text-align: center;
}
</style>
运行结果 这个表单就是这个红色框线中的内容,做的还是比较简洁美观的,用了很多elementui的组件。
这个组件是用于显示,博客的具体内容的,在这个组件中目前我分了两个不同的请求,进行查询,一个是第一个if后面的查询全部类型的文章,另外两个是,根据finish这个变量的属性,来判断查询完成还是未完成的这个变量有,已完成与未完成的网页发送过来,1表示完成了,0表示未完成,这里面还有删除按钮,更新按钮,已经对应的事件,和页面我是如何处理刷新过程的,我是采取重新回到,首页的方式实现页面的刷新。
<template>
<div class="block">
<el-timeline>
<el-timeline-item :timestamp="notes.created" placement="top" v-for="note in notes">
<el-card>
<h4>
<!-- <router-link :to="{name: 'NoteDetail', params: {noteId: notes.id}}">-->
<!-- {{note.title}}-->
<!-- </router-link>-->
</h4>
<p>截止日期:{{note.time}}</p>
<p>内容:{{note.detail}}</p>
<p>任务类型:{{typeMap[""+note.type]}}</p>
<p>是否完成:{{note.finish == 1 ? "完成" : "未完成"}}</p>
<el-row>
<el-button type="primary" @click="updatebyId(note.id)">更新</el-button>
<el-button type="danger" @click="deletebyId(note.id)">删除</el-button>
</el-row>
</el-card>
</el-timeline-item>
</el-timeline>
<el-pagination class="mpage"
background
layout="prev, pager, next"
:current-page="currentPage"
:page-size="pageSize"
:total="total"
@current-change=page>
</el-pagination>
</div>
</template>
<script>
export default {
name: "Detail.vue",
props:['isfinish'],
data() {
return {
userid:0,
user:{},
notes: {},
currentPage: 0,
total: 0,
pageSize: 0,
typeMap:{},
finish:this.isfinish
}
},
mounted() {
const users = JSON.stringify(this.user);
this.user = users
},
methods: {
page(currentPage) {
const _this = this
const users = window.sessionStorage.getItem("user")
this.user = JSON.parse(users)
console.log("----------------------------------")
console.log(this.isfinish)
if (this.isfinish == null){
_this.$axios.get("/selectAllByUserID/" + this.user.id + "?currentPage=" + currentPage).then(res => {
console.log(res)
_this.notes = res.data.data.records
_this.currentPage = res.data.data.current
_this.total = res.data.data.total
_this.pageSize = res.data.data.size
})
} else {
_this.$axios.get("/selectIsFinish/" + this.user.id + "/"+ this.isfinish + "/" + "?currentPage=" + currentPage).then(res => {
console.log(res)
_this.notes = res.data.data.records
_this.currentPage = res.data.data.current
_this.total = res.data.data.total
_this.pageSize = res.data.data.size
})
}
_this.$axios.get("/getMapping").then(res =>{
console.log(res.data)
_this.typeMap = res.data
})
// console.log(this.typeMap)
},
deletebyId(id){
console.log(id)
this.$axios.get("/delete/" + id).then(res=>{
if (res.data){
// this.$router.push({path:"/"});
location.href = "http://localhost:8080/Notes"
} else {
alert("删除失败")
}
})
},
updatebyId(id){
location.href = "http://localhost:8080/NodeUpdateView"
console.log("id" + id)
console.log(this.user.id)
window.sessionStorage.setItem("id", id)
window.sessionStorage.setItem("rid", this.user.id)
}
},
created() {
// 防止没有显示内容的情况
this.page(1)
}
}
</script>
<style scoped>
.mpage {
margin: 0 auto;
text-align: center;
}
</style>
运行结果 这个红色框框里面就是每篇文字的详细内容
查询所有的备忘录的页面,这个页面可以查询用户自己的所有的备忘录,可以看出,这个写的很简洁呀,这就是组件开发的好处,写的异常的简介,这个代码,低耦合。
完整代码
<template>
<div class="mcontaner">
<Header></Header>
<Detail></Detail>
</div>
</template>
<script>
import Header from "../components/Header";
import Detail from "../components/Detail.vue";
export default {
name: "NoteView.vue",
components: {Header, Detail},
}
</script>
<style scoped>
</style>
运行结果
可以看出这个代码,除了这个方法多了一个自己的,因为这个发送的请求不一样,当然这个还可以优化,这个添加的更新的,根据那个是否完成和查询所有的,写一个if判断在Table.vue组件就可以实现这个功能。
完整代码
<template>
<div>
<Header></Header>
<Table></Table>
</div>
</template>
<script>
import Header from "../components/Header";
import Table from "../components/Table.vue";
export default {
name: "NoteAddView.vue",
components: {Header,Table},
methods: {
add(){
this.notes.rid=this.user.id
if (this.notes.finish){
this.notes.finish = 1
} else {
this.notes.finish = 0
}
this.$axios.post("/save", this.notes).then(res=>{
if (res.data){
// this.$router.push({path:"/"});
location.href = "http://localhost:8080/Notes"
} else {
alert("添加失败")
}
})
}
}
}
</script>
<style scoped>
</style>
运行结果
这里的这个请求发送的代码和添加的那个不同这个就是这两个文件的区别。 完整代码
<template>
<div>
<Header></Header>
<Table></Table>
</div>
</template>
<script>
import Header from "../components/Header";
import Table from "../components/Table.vue";
export default {
name: "NoteUpdateView.vue",
components: {Header, Table},
methods: {
add(){
const users = window.sessionStorage.getItem("user")
this.user = JSON.parse(users)
this.notes.rid=this.user.id;
this.notes.id=window.sessionStorage.getItem("id")
console.log(this.notes.rid + " " + this.notes.id)
window.sessionStorage.removeItem("rid")
window.sessionStorage.removeItem("id")
// 给finish赋值
if (this.notes.finish){
this.notes.finish = 1
} else {
this.notes.finish = 0
}
console.log(this.notes)
this.$axios.post("/update", this.notes).then(res=>{
if (res.data){
// 返回主页
// this.$router.push({path:"/"});
location.href = "http://localhost:8080/Notes"
} else {
alert("更新失败")
}
})
}
}
}
</script>
<style scoped>
</style>
运行结果
这个代码很简洁,就传递了一个参数 完整代码
<template>
<div class="mcontaner">
<Header></Header>
<detail :isfinish="isfinish"></detail>
</div>
</template>
<script>
import Header from "../components/Header";
import Detail from "../components/Detail.vue";
export default {
name: "NoteViewNotFinish.vue",
components: {Header, Detail},
data(){
return{
isfinish:1
}
},
methods: {
}
}
</script>
<style scoped>
</style>
运行结果 查询出来了所有已经完成的备忘录
这个代码很简洁,就传递了一个参数 完整代码
<template>
<div class="mcontaner">
<Header></Header>
<detail :isfinish="isfinish"></detail>
</div>
</template>
<script>
import Header from "../components/Header";
import Detail from "../components/Detail.vue";
export default {
name: "NoteViewNotFinish.vue",
components: {Header, Detail},
data(){
return{
isfinish:0
}
},
methods: {
}
}
</script>
<style scoped>
</style>
运行结果 查询出来了所有没有完成的备忘录,当然目前没有。