前言
本圖書管理系統(tǒng)是基于Vue、Ajax、Node.js等技術(shù)的管理系統(tǒng),筆者給其命名為陽光圖書管理系統(tǒng),意味著我們這個年紀應(yīng)該活得灑脫像陽光一樣,應(yīng)充滿活力與信心。再此感謝老師朋友的悉心指導(dǎo),由于此系統(tǒng)是筆者初次完成的一個小型管理系統(tǒng),必定有許多紕漏,如有不足請指正。
陽光圖書館設(shè)計與實現(xiàn)
1、緒論
1.1 選題背景
1.2 研究的目的及意義
1.3 論文組織結(jié)構(gòu)
2、相關(guān)技術(shù)
2.1 Ajax異步加載
AJAX 是開發(fā)者的夢想,因為您能夠:
不刷新頁面更新網(wǎng)頁
在頁面加載后從服務(wù)器請求數(shù)據(jù)
在頁面加載后從服務(wù)器接收數(shù)據(jù)
在后臺向服務(wù)器發(fā)送數(shù)據(jù)
2.2 Axios
2.3 Vue
2.4 Node.js
jsonServer
3、系統(tǒng)需求分析
3.1 可行性設(shè)計
3.2 系統(tǒng)功能分析
3.3 系統(tǒng)非功能設(shè)計
4、系統(tǒng)設(shè)計
4.1 系統(tǒng)功能模塊詳細設(shè)計
下圖是該實驗的模塊設(shè)計圖
請求方式具體表現(xiàn):
4.2 系統(tǒng)功能流程分析
5、系統(tǒng)實現(xiàn)
系統(tǒng)的具體實現(xiàn)過程,在此不再贅述,可以評論區(qū)留言將項目發(fā)送到您的郵箱。
5.1 管理員驗證身份功能實現(xiàn)
(1)用戶登錄頁面以及可以伸縮頁面兼容性測試【響應(yīng)式布局】
(2)用戶登錄失敗與成功給出的不同提示
(3)用戶注冊頁面與功能的實現(xiàn)
(4)用戶找回密碼
(5)用戶注銷賬號
5.2 圖書增刪改查
(1)新增前、新增后
(2)刪除前、刪除后
(3)修改前、修改后
(4)查重機制
6、測試
系統(tǒng)開發(fā)完成之后,上線使用之前系統(tǒng)測試是必須的,因為只有對系統(tǒng)進行一個全面的測試,我們才可能發(fā)現(xiàn)系統(tǒng)中可能存在的問題,這些問題可能是技術(shù)缺陷,功能不全,業(yè)務(wù)需求達不到預(yù)先的效果等。新開發(fā)出來的系統(tǒng)沒有十全十美的,所以這些缺陷有可能在測試中發(fā)現(xiàn)并得到解決,系統(tǒng)測試方法有很多,并且各個所占時間都不同,功能測試在整個系統(tǒng)測試的過程中占據(jù)的比例較大,功能測試也叫黑盒測試,黑盒測試不需要測試軟件內(nèi)部結(jié)構(gòu),目的是測試系統(tǒng)的功能。只要測試人員搭建好系統(tǒng)測試環(huán)境 。對各個函數(shù)接口進行測試即可。
6.1 測試環(huán)境
硬件環(huán)境:筆記本或臺式電腦
操作系統(tǒng):Windows 10
軟件環(huán)境: 谷歌瀏覽器、Microsoft Edge瀏覽器
6.2 測試用例
只有嚴格按照完整的測試用例來對系統(tǒng)進行測試,才能使得系統(tǒng)不管是功能還是性能方面的質(zhì)量都有所保證,沒有十全十美的軟件系統(tǒng),但是我們可以通過測試減少很多不必要的錯誤,下面即是該系統(tǒng)的部分測試用例。
(1)圖書管理測試用例
(2)管理員登錄操作用例
結(jié)束語
本次實驗的設(shè)計與開發(fā),是對本學(xué)期學(xué)習(xí)的一種很好的總結(jié),在本學(xué)期的實驗中,本次實驗很具有挑戰(zhàn)性,因此我選擇了這個項目作為我的實驗項目,在完成了實驗的時候,我也遇到了許多困難與錯誤,在需求不明確的時候盲目的開發(fā)造成錯誤百出,某些知識點的掌握還不夠,也有一些地方與預(yù)期不相符,我不得不查詢各種資料,在一次次探討之中,我慢慢的掌握的許多知識,在這些知識的認識之下,完成了該實驗的設(shè)計與開發(fā),技術(shù)與業(yè)務(wù)能力也有所提高,這對以后的事業(yè)發(fā)展有一定的積極影響作用
參考文獻
致謝
本次實驗的開發(fā)與設(shè)計是在郭德先老師的指導(dǎo)下完成的,老師的建議和諄諄教誨使得實驗在一點點的完善,在這一學(xué)期的學(xué)習(xí)中,正是老師的責(zé)任心引導(dǎo)著我們完成一次又一次的實驗,每次遇到解決不了的問題時,都會向老師咨詢,老師總是能給出合理的建議并不斷鼓勵我完成實驗,再次由衷的感謝老師。
源碼
項目目錄結(jié)構(gòu)
大家根據(jù)這個項目的目錄結(jié)構(gòu)搭建即可,如有疑問評論區(qū)私聊博主。想要搭建好的項目評論區(qū)留言郵箱。
主頁【index.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<!-- 引入樣式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<!-- 引入組件庫 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="../css/index.css" />
<title>陽光圖書館</title>
</head>
<body>
<div id="logn" style="text-align: center">
<el-dialog
:visible.sync="dialogVisible"
style="width: 70%; text-align: center; position: absolute; left: 15%; top: 20%"
>
賬號:<input type="text" v-model="temp_node.id" /> <br /><br />
密碼:<input type="password" v-model="temp_node.name" /> <br /><br />
<!-- 年齡:<input type="text" v-model="temp_node.age" /> <br /><br /> -->
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false;dialogs();">確 定</el-button>
</el-dialog>
<el-dialog
:visible.sync="dialogVisible1"
style="width: 70%; text-align: center; position: absolute; left: 15%; top: 20%"
>
賬號:<input type="text" v-model="temp_node.id" /> <br /><br />
<!-- 密碼:<input type="password" v-model="temp_node.name" /> <br /><br /> -->
年齡:<input type="text" v-model="temp_node.age" /> <br /><br />
<el-button @click="dialogVisible1 = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible1 = false;losepasswd();">確 定</el-button>
</el-dialog>
</div>
<div class="back1" style="position: absolute">
<div class="namebgc">
<div class="head1"></div>
<div class="headfont">
<div>陽</div>
<div>光</div>
<div>圖</div>
<div>書</div>
<div>管</div>
<div></div>
</div>
</div>
<div class="headtext">
<a href="#" class="button" onclick="vmadd()"> 登錄 </a>
<a href="resiger.html" class="button"> 注冊 </a>
<a href="#" class="button" onclick="vmlook()"> 找回密碼 </a>
<a href="#" class="button" onclick="vmdel()"> 注銷賬號 </a>
</div>
</div>
<script>
function vmadd() {
vm.$data.dialogVisible = true
vm.$data.logordel = true
}
function vmdel() {
vm.$data.dialogVisible = true
vm.$data.logordel = false
}
function vmlook() {
vm.$data.dialogVisible1 = true
vm.$data.logordel = 3
}
let vm = new Vue({
el: '#logn',
data: {
userList: [],
dialogVisible: false,
dialogVisible1: false,
textvalue: '',
index: '',
temp_node: {
id: '',
age: '',
name: '',
},
logordel:0,
},
methods: {
//代碼還是有點復(fù)雜:我們程序員還要手動完成數(shù)據(jù)組裝
search() {
axios({
url: 'http://localhost:3000/users',
})
.then(function (response) {
vm.$data.userList = response.data
})
.catch(function (error) {
//失敗
console.log(error)
console.log('===請求失敗了===')
})
},
dialogs() {
if (this.$data.logordel) {
this.mlogin()
} else {
this.deluser()
}
this.resetTempNode();
},
// 登錄函數(shù)
mlogin() {
for (let i = 0; i < this.userList.length; i++) {
if (this.userList[i].id == this.temp_node.id && this.userList[i].name == this.temp_node.name) {
alert('登錄成功!')
// 前端小練習(xí)\陽光圖書館\html\opbook.html
// location.replace('D:/goStudy/前端大作業(yè)/前端小練習(xí)/opedata.html')
location.replace('opbook.html')
return
}
}
alert('未找到此用戶!')
},
// 刪除函數(shù)
deluser() {
for (let i = 0; i < this.userList.length; i++) {
if (this.userList[i].id == this.temp_node.id && this.userList[i].name == this.temp_node.name) {
axios({
method: 'DELETE', //刪除
url: 'http://localhost:3000/users/' + this.temp_node.id, //id為"hello"
}).then(function (response) {
console.log(response.data)
})
alert('注銷成功!')
this.search()
return
}
}
alert('未找到此用戶!')
},
losepasswd(){
for (let i = 0; i < this.userList.length; i++) {
if (this.userList[i].id == this.temp_node.id && this.userList[i].age == this.temp_node.age) {
// console.log(this.userList[i].name)
alert("您的密碼是:"+this.userList[i].name);
this.resetTempNode();
return
}
}
alert('您的信息有誤!')
this.resetTempNode();
},
resetTempNode(){
this.temp_node.id = ''
this.temp_node.name = ''
this.temp_node.age = ''
}
},
created: function () {
this.search()
},
})
</script>
</body>
</html>
圖書的增刪改查【opbook.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<!-- 引入樣式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<!-- 引入組件庫 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<title>操作圖書</title>
</head>
<!-- style="background-image: url(../imgs/image.png); background-repeat: no-repeat; background-size: cover;" -->
<body>
<div id="app">
<el-container>
<el-header>
<el-menu class="el-menu-demo" mode="horizontal">
<el-menu-item index="1">處理中心</el-menu-item>
<el-submenu index="2">
<temp_nodelate slot="title">我的工作臺</temp_nodelate>
<el-menu-item index="2-1">選項1</el-menu-item>
<el-menu-item index="2-2">選項2</el-menu-item>
<el-menu-item index="2-3">選項3</el-menu-item>
<el-submenu index="2-4">
<temp_nodelate slot="title">選項4</temp_nodelate>
<el-menu-item index="2-4-1">選項1</el-menu-item>
<el-menu-item index="2-4-2">選項2</el-menu-item>
<el-menu-item index="2-4-3">選項3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"><a href="https://www.ele.me" target="_blank">訂單管理</a></el-menu-item>
<el-menu-item index="4" style="position: absolute; right: 10%; background-color: aqua; color: black; border-radius: 40%">
<a href="index.html" style="text-decoration: none">退出登錄</a>
</el-menu-item>
</el-menu>
</el-header>
<el-main >
<!-- 信息錄入框 -->
<el-dialog
title="請輸入您的信息!"
:visible.sync="dialogVisible"
style="width: 70%; text-align: center; position: absolute; left: 15%"
>
id:<input type="text" v-model="temp_node.id" /> <br /><br />
書名:<input type="text" v-model="temp_node.name" /> <br /><br />
作者:<input type="text" v-model="temp_node.author" /> <br /><br />
價格:<input type="text" v-model="temp_node.price" /> <br /><br />
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false;add_or_amend();">確 定</el-button>
</el-dialog>
<div id="app" class="mylist">
<!-- 卡片的樣式進行展示 -->
<el-card class="box-card" >
<!-- 信息展示 -->
<el-table :data="bookList" style="width: 100%;">
<el-table-column prop="id" label="編號" width="%20"></el-table-column>
<el-table-column prop="name" label="書名" width="%20"></el-table-column>
<el-table-column prop="author" label="作者" width="%20"></el-table-column>
<el-table-column prop="price" label="價格(元)" width="%20"></el-table-column>
<el-table-column label="操作" width="%20">
<temp_nodelate slot-scope="scope">
<el-button
type="warning"
style="width: 30%"
v-on:click="addoramend=false;dialogVisible=true;index=scope.$index;"
>修改</el-button
>
<el-button type="danger" style="width: 30%" v-on:click="index=scope.$index;del();">刪除</el-button>
</temp_nodelate>
</el-table-column>
</el-table>
<!-- 新增按鈕 -->
<div style="text-align: center">
<el-button style="width: 15%; margin-top: 1%" v-on:click="addoramend=true;dialogVisible=true"
>+</el-button
>
</div>
</el-card>
</div>
</el-main>
<el-footer style="position: absolute; bottom: 20px; width: 100%">
<el-card>
<div style="text-align: center">
<el-link href="https://element.eleme.io" target="_blank">默認鏈接</el-link>
<el-link type="primary">主要鏈接</el-link>
<el-link type="success">成功鏈接</el-link>
<el-link type="warning">警告鏈接</el-link>
<el-link type="danger">危險鏈接</el-link>
<el-link type="info">信息鏈接</el-link>
</div>
</el-card>
</el-footer>
</el-container>
</div>
<script>
// 創(chuàng)建一個vue對象
let vm = new Vue({
// 將這個vue對象與id為app的標簽進行綁定
el: '#app',
// vue對象的數(shù)據(jù)庫
data: {
// 存儲所有書的列表
bookList: [],
dialogVisible: false,
textvalue: '',
sorttype: 0,
index: '',
temp_node: {
id: '',
name: '',
author: '',
price: '',
},
addoramend: true,
},
// vue對象的方法域
methods: {
//代碼還是有點復(fù)雜:我們程序員還要手動完成數(shù)據(jù)組裝
search() {
axios({
url: 'http://localhost:3000/book',
})
.then(function (response) {
vm.$data.bookList = response.data
})
.catch(function (error) {
//失敗
console.log(error)
console.log('===請求失敗了===')
})
},
// 刪除
del() {
let aaa = this.bookList[this.index]
var mindex = this.index
let bbb = this.bookList.indexOf(aaa)
this.bookList.splice(bbb, 1)
axios({
method: 'DELETE', //刪除
url: 'http://localhost:3000/book/' + aaa.id,
}).then(function (response) {
console.log(mindex)
})
},
// 修改
amend() {
let aaa = this.bookList[this.index]
let str = aaa.id
let bbb = this.bookList.indexOf(aaa)
for (let i = 0; i < this.bookList.length; i++) {
if (this.bookList[i].id == this.temp_node.id && i != bbb) {
alert('操作失敗')
return
}
}
// 將新的屬性給這個節(jié)點
this.bookList[bbb].id = this.temp_node.id
this.bookList[bbb].name = this.temp_node.name
this.bookList[bbb].author = this.temp_node.author
this.bookList[bbb].price = this.temp_node.price
// 先進行刪除
axios({
method: 'DELETE', //刪除
url: 'http://localhost:3000/book/' + str,
}).then(function (response) {
console.log(response.data)
})
// 再進行添加
axios({
method: 'POST', //增加
url: 'http://localhost:3000/book',
data: this.temp_node,
})
},
// 增加
add() {
// 判斷一下表單是否為空
if (this.temp_node.id != '' && this.temp_node.age != '') {
let ma = { id: '', name: '', author: '', price: '' }
ma.id = this.temp_node.id
ma.name = this.temp_node.name
ma.author = this.temp_node.author
ma.price = this.temp_node.price
for (let i = 0; i < this.bookList.length; i++) {
if (this.bookList[i].id == ma.id) {
alert('該id已經(jīng)存在!')
return
}
}
// 將新的節(jié)點加入頁面
this.bookList.push(ma)
// 將新的節(jié)點添加到數(shù)據(jù)庫
axios({
method: 'POST', //增加
url: 'http://localhost:3000/book',
data: ma,
})
.then(function (response) {})
.catch((err) => {
alert('操作失敗')
})
}
},
// 判斷是修改還是增加
add_or_amend() {
if (this.addoramend) {
this.add()
} else {
this.amend()
}
// 操作完后將表單數(shù)據(jù)置空
this.temp_node.id = ''
this.temp_node.author = ''
this.temp_node.name = ''
this.temp_node.price = ''
},
},
// 一個實例被創(chuàng)建之后執(zhí)行的代碼
created: function () {
this.search()
},
})
</script>
</body>
</html>
注冊頁面【resger.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<link rel="stylesheet" href="../css/resiger.css">
<title>注冊</title>
</head>
<body>
<div class="nav">
<form action="python">
<div style="color: steelblue;">
I    D: <input type="text" id="userid" class="texta"><br>
密    碼: <input type="password" id="userpasd" class="texta"><br>
年    齡: <input type="text" id="userage" class="texta"><br>
<a type="button" class="mbuttom" href="#" onclick="resetvalue()">清空</a>
<a type="button" class="mbuttom" href="#" onclick="submitvalue()">提交</a>
<a type="button" class="mbuttom" href="index.html" style="width: 110px;">返回主菜單</a>
</div>
</form>
</div>
<script>
// 將臨時節(jié)點的數(shù)據(jù)恢復(fù)初始值
function resetvalue(){
document.getElementById("userid").value="";
document.getElementById("userpasd").value="";
document.getElementById("userage").value=""
}
// 獲取各個文本框的數(shù)據(jù)
function submitvalue(){
vm.$data.temp_node.id=document.getElementById("userid").value
vm.$data.temp_node.name=document.getElementById("userpasd").value
vm.$data.temp_node.age=document.getElementById("userage").value
vm.add()
}
let vm = new Vue({
el: '#app',
data: {
userList: [],
temp_node: {
id: '',
age: '',
name: '',
},
},
methods: {
search() {
axios({
url: 'http://localhost:3000/users',
})
.then(function (response) {
vm.$data.userList = response.data
})
.catch(function (error) {
//失敗
console.log(error)
console.log('===請求失敗了===')
})
},
// 增加
add(){
if(this.temp_node.id!=''&&this.temp_node.age!=''){
let ma={id:'',age:'',name:''};
ma.id=this.temp_node.id;
ma.age=this.temp_node.age;
ma.name=this.temp_node.name;
// 遍歷用戶列表進行查重
for(let i=0;i<this.userList.length;i++){
if(this.userList[i].id==ma.id){
alert('該id已經(jīng)存在!請重新輸入');
resetvalue();
return;
}
}
// 沒有重復(fù)將數(shù)據(jù)插入列表內(nèi)
this.userList.push(ma);
alert("注冊成功!點擊確定去登錄")
resetvalue();
axios({
method:"POST",//增加
url:"http://localhost:3000/users",
data:ma,
}).then(function(response){
}).catch((err)=>{
alert('操作失敗');
})
location.replace('index.html')
}
},
},
// 一個實例被創(chuàng)建之后執(zhí)行的代碼
created: function () {
this.search()
},
})
</script>
</body>
</html>
主頁css樣式【index.css】
/* 第一頁背景 */
div {
display: inline-block;
}
a {
text-decoration: none;
}
/* body{
width: 100%;
} */
.back1 {
position: relative;
/* display: inline-block; */
width: 100%;
height: 1200px;
background: url('../imgs/image.png') no-repeat;
background-size: 100% 100%;
}
/* 網(wǎng)站簡介 */
.namebgc {
position: absolute;
top: -20%;
width: 44%;
height: 16%;
background-color: transparent;
transform: translate(70%, 180%);
}
.head1 {
position: absolute;
margin-top: 23px;
margin-left: 39px;
width: 15.3%;
height: 65%;
background: url('../imgs/head1.png') no-repeat;
background-size: 100% 100%;
background-color: transparent;
/* transform: translate(10%,10%); */
transition: all 1s;
}
.head1:hover {
transform: rotate(360deg);
}
.headfont {
background-color: transparent;
width: 70%;
text-align: center;
margin-top: 20px;
margin-left: 20px;
position: absolute;
left: 180px;
font-size: 80px;
font-weight: 700;
transition: all 0.6s;
/* font-family: '幼圓'; */
}
/* 當鼠標經(jīng)過圖標時,有一定的動畫效果 */
.headfont div:nth-child(1) {
transition: all 0.3s;
color: blueviolet;
}
.headfont div:nth-child(1):hover {
transform: translateY(-5px);
}
.headfont div:nth-child(2) {
transition: all 0.3s;
color: aqua;
}
.headfont div:nth-child(2):hover {
transform: translateY(-5px);
}
.headfont div:nth-child(3) {
transition: all 0.3s;
color: cornflowerblue;
}
.headfont div:nth-child(3):hover {
transform: translateY(-5px);
}
.headfont div:nth-child(4) {
transition: all 0.3s;
color: gold;
}
.headfont div:nth-child(4):hover {
transform: translateY(-5px);
}
.headfont div:nth-child(5) {
transition: all 0.3s;
color: tomato;
}
.headfont div:nth-child(5):hover {
transform: translateY(-5px);
}
/* 簡介 1388*232 */
/* 放置登錄、注冊幾個按鈕的盒子 */
.headtext {
background-color: transparent;
position: absolute;
width: 40%;
height: 40%;
transform: translate(80%, 60%);
text-align: center;
font-size: 26px;
}
.headtext .button {
margin-left: 30%;
margin-top: 1%;
width: 40%;
height: 100px;
display: block;
border-radius: 30%;
border: cornflowerblue 5px solid;
font-size: 40px;
line-height: 100px;
color: lightblue;
transition: all 0.4s;
}
.headtext .button:hover {
transform-origin: center;
border-color: chartreuse;
color: chartreuse;
transform: scale(110%, 110%);
}
注冊css樣式【resiger.css】
.nav{
display: inline-block;
width: 100%;
height: 780px;
text-align: center;
padding-top: 200px;
line-height: 30px;
background: url("../imgs/image.png") no-repeat;
background-size: 100% 100%;
font-size: 20px;
font-weight: 700;
}
.texta{
display: inline-block;
width: 400px;
height: 20px;
margin-top: 20px;
}
.mbuttom{
display: inline-block;
width: 60px;
height: 30px;
border-radius: 15px;
background-color: darkgray;
margin-left: 20px;
margin-right: 20px;
margin-top: 25px;
text-decoration: none;
color: rgb(85,39,140);
}
root CSS【root.css】
*{
margin: 0;
padding: 0;
}
圖片素材
本項目使用的是相對路徑建好項目目錄后直接將圖片放在相應(yīng)的目錄即可
環(huán)境安裝包
node.js
http://nodejs.cn/
element-ui文章來源:http://www.zghlxwxcb.cn/news/detail-491976.html
https://element.eleme.io/#/zh-CN
vue.js文章來源地址http://www.zghlxwxcb.cn/news/detail-491976.html
https://cn.vuejs.org/index.html
到了這里,關(guān)于基于Vue、Axios、Node.js的圖書管理系統(tǒng)【網(wǎng)頁前端高級編程】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!