前端:後臺模板vue-admin-template
尚硅谷Spring筆記-05
後臺模板
非常經典的模板,被用的很廣泛
- 倉庫 https://github.com/PanJiaChen/vue-admin-template
- 解壓縮下載來的
vue-admin-template-master
,取個好名字放到自己的專案路徑下 - 進到資料夾,執行
npm install
安裝依賴
依賴除錯
課件給的老板本用起來很多錯誤,需要手動排查
// 載都沒載直接報錯停止,可能是npm版本太高,降版本:
npm install npm@6.14.10 -g
/* node-sass問題,報錯為
node-sass@4.14.1 postinstall: `node scripts/build.js`
node-sass跟Node.js版本有很大關係,不相容的時候可以這樣
*/
npm install gulp-sass --save-dev
npm install node-sass@latest
// 清除緩存
npm cache clean --force
- 都沒問題使用
npm run dev
就能啟動了- 後來我是去它倉庫抓4.4版本的,依賴都沒報錯,也不用修改登入接口那些
開始搭建
新增側邊欄
- 左邊那些表在vue中對應叫router,修改
/src/router/index.js
綁定要顯示的項目 @/
是設定好的別名,表示/src
路徑之下- 然後在view中添加要顯示的內容,新增檔案後輸入veu+table就能產生模板
串接api
- 到@/api下編輯接口,複製一個預設的來改,點進去發現第一行
import request from '@/utils/request'
是已經引用好axios了- 但是他這邊
request.js
裡面成功代號預設是20000,如果與後端用的不同要自己修改- 改這個最好用全局取代,因為還有其他比如登入也用到這個代碼,要統一改
- 但是他這邊
- 修改下面的請求方法,與後端api的URL對接
import request from '@/utils/request'
export default {
findPageHospitalSet(current, limit, searchObj) {
return request({
// ES6特性,反引號包裹強化字串
url: `http://localhost:8201/admin/hosp/hospitalSet/findPageHospitalSet/${current}/${limit}`,
// url: `/admin/hosp/hospitalSet/findPageHospitalSet/${current}/${limit}`,
method: 'post',
// data表示使用json傳遞給後端的@RequestBody
data: searchObj
})
}
}
- 暫時先用完整的url跳過需要關閉mock與跨域問題
修改請求端口號
留坑,暫時先用完整的url跳過需要關閉mock與跨域問題
- 到
main.js
先斬斷mock
vue.config.js
中也有
- 到
.env.development
設定BASE_API
編寫ajax請求
<script>
// 引入接口的js
import hospitalSet from "@/api/hospital-set";
export default {
// 定義接收用的變量與初始值
data() {
return {
current: 1, // 當前頁
limit: 5, // 每頁幾筆
searchObj: {}, // 搜索條件
list: [], // 每頁中的數據集合
total: 0, // 總頁數
multipleSelection: [], // 批量選擇中的記錄列表
};
},
created() {
// 在頁面渲染之前,通常用來調用methods裡的方法取得數據
this.getList();
},
methods: {
getList(page = 1) {
// 當前頁數預設是1
// 發送axaj請求
this.current = page;
// 對應後端條件查詢帶分頁
hospitalSet
.findPageHospitalSet(this.current, this.limit, this.searchObj)
.then((response) => {
// 請求成功,取出回應資料
this.list = response.data.records;
this.total = response.data.total;
})
// 請求失敗
.catch((error) => {
console.log(error);
});
},
顯示資料
- 到elementUI拿表格模板
- https://element.eleme.cn/#/zh-CN/component/table
<el-table
:data="list"
stripe
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column type="index" width="50" label="序號" />
<el-table-column prop="hosname" label="醫院名稱" />
<el-table-column prop="hoscode" label="醫院編號" />
<el-table-column prop="apiUrl" label="api基礎路徑" width="200" />
<el-table-column prop="contactsName" label="聯繫人姓名" />
<el-table-column prop="contactsPhone" label="聯繫人手機" />
<el-table-column label="狀態" width="80">
<template slot-scope="scope">
{{ scope.row.status === 1 ? "可用" : "不可用" }}
</template>
</el-table-column>
跨域問題
-
以下三種情況都會引起:
-
協議不同:http與https
-
端口不同:9528與8201
-
ip不同
-
-
解法:
- 後端Controller註解
@CrossOrigin
- 使用nginx反向代理
- 後端Controller註解
完成其他功能
list.vue
<template>
<div class="app-container">
醫院設置列表
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-input v-model="searchObj.hosname" placeholder="醫院名稱" />
</el-form-item>
<el-form-item>
<el-input v-model="searchObj.hoscode" placeholder="醫院編號" />
</el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getList()"
>查詢</el-button
>
</el-form>
<!-- 工具條 -->
<div>
<el-button type="danger" size="mini" @click="removeRows()"
>批量刪除</el-button
>
</div>
<el-table
:data="list"
stripe
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column type="index" width="50" label="序列" />
<el-table-column prop="hosname" label="醫院名稱" />
<el-table-column prop="hoscode" label="醫院編號" />
<el-table-column prop="apiUrl" label="api基礎路徑" width="200" />
<el-table-column prop="contactsName" label="聯繫人姓名" />
<el-table-column prop="contactsPhone" label="聯繫人手機" />
<el-table-column label="狀態" width="80">
<template slot-scope="scope">
{{ scope.row.status === 1 ? "可用" : "禁用" }}
</template>
</el-table-column>
<el-table-column label="操作" width="280" align="center">
<template slot-scope="scope">
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click="removeDataById(scope.row.id)"
>刪除</el-button
>
<el-button
v-if="scope.row.status == 1"
type="primary"
size="mini"
icon="el-icon-delete"
@click="lockHospitalSet(scope.row.id, 0)"
>鎖定</el-button
>
<el-button
v-if="scope.row.status == 0"
type="danger"
size="mini"
icon="el-icon-delete"
@click="lockHospitalSet(scope.row.id, 1)"
>解鎖</el-button
>
<router-link :to="'/hospitalSet/edit/' + scope.row.id">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
></el-button>
</router-link>
</template>
</el-table-column>
</el-table>
<!-- 分頁 -->
<el-pagination
:current-page="current"
:page-size="limit"
:total="total"
style="padding: 30px 0; text-align: center"
layout="total, prev, pager, next, jumper"
@current-change="getList"
/>
</div>
</template>
<script>
// 引入接口的js
import hospitalSet from "@/api/hospital-set";
export default {
// 定義接收用的變量與初始值
data() {
return {
current: 1, // 當前頁
limit: 5, // 每頁幾筆
searchObj: {}, // 搜索條件
list: [], // 每頁中的數據集合
total: 0, // 總頁數
multipleSelection: [], // 批量選擇中的記錄列表
};
},
created() {
// 在頁面渲染之前,通常用來調用methods裡的方法取得數據
this.getList();
},
methods: {
getList(page = 1) {
// 當前頁數預設是1
// 發送axaj請求
this.current = page;
// 對應後端條件查詢帶分頁
hospitalSet
.findPageHospitalSet(this.current, this.limit, this.searchObj)
.then((response) => {
// 請求成功,取出回應資料
this.list = response.data.records;
this.total = response.data.total;
})
// 請求失敗
.catch((error) => {
console.log(error);
});
},
// 鎖定和取消鎖定
lockHospitalSet(id, status) {
hospitalSet.lockHospitalSet(id, status).then((response) => {
// 刷新
this.getList(this.current);
});
},
// 獲取選擇複選框的id值
handleSelectionChange(selection) {
this.multipleSelection = selection;
},
// 批量刪除
removeRows() {
this.$confirm("此操作將永久刪除醫院的設置信息, 是否繼續?", "提示", {
confirmButtonText: "確定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 確定執行then方法
var idList = [];
// 遍歷數組得到每個id值,塞到idList裏面
for (var i = 0; i < this.multipleSelection.length; i++) {
var obj = this.multipleSelection[i];
var id = obj.id;
idList.push(id);
}
// 調用接口
hospitalSet.batchRemove(idList).then((response) => {
//提示
this.$message({
type: "success",
message: "刪除成功!",
});
// 刷新頁面
this.getList(this.current);
});
})
.catch(() => {
this.$message({
type: "warning",
message: "取消操作",
});
});
}, // 刪除醫院設置的方法
removeDataById(id) {
this.$confirm("此操作將永久刪除醫院的設置信息, 是否繼續?", "提示", {
confirmButtonText: "確定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 確定執行then方法
// 調用接口
hospitalSet.removeHospitalSet(id).then((response) => {
// 提示
this.$message({
type: "success",
message: "刪除成功!",
});
// 刷新頁面
this.getList(this.current);
});
})
.catch(() => {
this.$message({
type: "warning",
message: "取消操作",
});
});
},
},
};
</script>
<style>
</style>
- 到
hospital-set.js
綁定接口
import request from '@/utils/request'
export default {
findPageHospitalSet(current, limit, searchObj) {
return request({
// ES6特性,反引號包裹強化字串
url: `http://localhost:8201/admin/hosp/hospitalSet/findPageHospitalSet/${current}/${limit}`,
// url: `/admin/hosp/hospitalSet/findPageHospitalSet/${current}/${limit}`,
method: 'post',
// data表示使用json傳遞給後端的@RequestBody
data: searchObj
})
},
// 刪除醫院設置
removeHospitalSet(id) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/removeHospitalSet/${id}`,
method: 'delete'
})
},
// 批量刪除
batchRemove(idList) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/batchRemove`,
method: 'delete',
data: idList
})
},
// 鎖定和取消鎖定
lockHospitalSet(id, status) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/lockHospitalSet/${id}/${status}`,
method: 'put'
})
},
// 添加醫院設置
saveHospitalSet(hospitalSet) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/saveHospitalSet`,
method: 'post',
data: hospitalSet
})
},
// 院設置id查詢
getHospitalSet(id) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/getHospitalSet/${id}`,
method: 'get'
})
},
// 修改醫院設置
updateHospitalset(hospitalSet) {
return request({
url: `http://localhost:8201/admin/hosp/hospitalSet/updateHospitalSet`,
method: 'post',
data: hospitalSet
})
}
}
知識點
獲取多選框
批量XX功能
// 先定義一個批量選擇中的記錄列表
multipleSelection: [],
// 上面選框綁定@selection-change動作
<el-table-column type="selection" width="55" />
@selection-change="handleSelectionChange"
// 獲取選擇複選框的id值
handleSelectionChange(selection) {
this.multipleSelection = selection;
// 遍歷數組得到每個id值,塞到idList裏面
for (var i = 0; i < this.multipleSelection.length; i++) {
var obj = this.multipleSelection[i];
var id = obj.id;
idList.push(id);
}
// 調用接口,拿idList當參數發請求
確認彈窗
// 上面綁一個按鈕
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click="removeDataById(scope.row.id)"
>刪除</el-button>
// 下面寫方法
removeDataById(id) {
this.$confirm("此操作將永久刪除醫院的設置信息, 是否繼續?", "提示", {
confirmButtonText: "確定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 確定執行then方法
// 調用接口
hospitalset.removeHospitalSet(id).then((response) => {
// 提示
this.$message({
type: "success",
message: "刪除成功!",
});
// 刷新頁面
this.getList(this.current);
});
})
.catch(() => {
this.$message({
type: "warning",
message: "取消操作",
});
});
},
- 注意刷新可以回到當前頁
this.getList(this.current)
,教學中它統一回到第1頁,感覺會很不爽 .catch(() => {
是應對選取消的,如果不寫會拋出一個錯誤沒人接,怪怪的
大小寫風格
為了防坑看了好多風格說明,但也沒個結論,先暫時定一下,插個眼
- 前端的節點、頁面名,參考預設的項目全小寫且用
-
相連,文件名全小寫可以防止linux系統的麻煩,例如hospital-set.js
- 這樣記住原則,前端的頁面
@/
開頭或/
轉址都是全小寫-
連 - 其他方法、變量都用小駝峰,這樣最符合直覺,不然一個
lockHospitalset
後面的Set
忘記駝峰害我找半天 - 前後端調用的函數名最好一樣
- 可以善用VS code的搜尋功能,這裡可以切換大小寫是否要完全相符,如果發現搜到的結果有變動,那就是有坑
- 自訂的事件名、HTML標籤名用
-
相連,例如<blog-post>
、selection-change
新增&修改頁面
- 先去
/router/index.js
綁定網址:id
表示動態,類似SQL中?佔位符hidden: true
,不會顯示在側邊欄
{
path: 'edit/:id',
name: '醫院設定編輯',
component: () => import('@/views/hospital-set/add'),
meta: { title: '醫院設定編輯', icon: 'table' },
hidden: true
}
- 接著回到
list.vue
,綁定修改按鈕,<router-link :to="
跳轉至
<router-link :to="'/hospital-set/edit/' + scope.row.id">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
></el-button>
</router-link>
- 回到
add.vue
<template>
<div class="app-container">
添加醫院設置
<el-form label-width="120px">
<el-form-item label="醫院名稱">
<el-input v-model="hospitalSet.hosname" />
</el-form-item>
<el-form-item label="醫院編號">
<el-input v-model="hospitalSet.hoscode" />
</el-form-item>
<el-form-item label="api基礎路徑">
<el-input v-model="hospitalSet.apiUrl" />
</el-form-item>
<el-form-item label="聯繫人姓名">
<el-input v-model="hospitalSet.contactsName" />
</el-form-item>
<el-form-item label="聯繫人手機">
<el-input v-model="hospitalSet.contactsPhone" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveOrUpdate">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import hospitalSet from "@/api/hospital-set";
export default {
data() {
return {
hospitalSet: {},
};
},
created() {
// 頁面渲染之前執行
// 獲取路由id值,如果有表示修改來的,需要先查詢回顯
// 調用接口得到醫院設置信息
if (this.$route.params && this.$route.params.id) {
const id = this.$route.params.id;
this.getHospitalSet(id);
} else {
// 表單清空,為了防有人點進修改又去按新增
this.hospitalSet = {};
}
},
methods: {
// 根據id查詢
getHospitalSet(id) {
hospitalSet.getHospitalSet(id).then((response) => {
this.hospitalSet = response.data;
});
},
// 添加
save() {
hospitalSet.saveHospitalSet(this.hospitalSet).then((response) => {
// 提示
this.$message({
type: "success",
message: "添加成功!",
});
// 跳轉列表頁面,使用路由跳轉方式實現
this.$router.push({ path: "/hospital-set/list" });
});
},
// 修改
update() {
hospitalSet.updateHospitalSet(this.hospitalSet).then((response) => {
// 提示
this.$message({
type: "success",
message: "修改成功!",
});
// 跳轉列表頁面,使用路由跳轉方式實現
this.$router.push({ path: "/hospital-set/list" });
});
},
saveOrUpdate() {
// 先防空
if (!this.hospitalSet.hoscode || !this.hospitalSet.hosname) {
// 提示
this.$message({
type: "error",
message: "醫院名與編號為必填!",
});
return;
}
// 判斷添加還是修改
if (!this.hospitalSet.id) {
// 沒有id,做添加
this.save();
} else {
// 修改
this.update();
}
},
},
};
</script>
- 用
this.$route.params && this.$route.params.id
從網址參數判斷是要新增還是修改 this.$router.push({ path: "/hospital-set/list" });
跳轉頁面- 注意請求是
route
,跳轉是router
- 注意請求是
上次修改於 2022-01-15