參賽進入最尾聲了,剩下最後一個實戰任務!將會用我之前透過.net MVC開發的訂房網站為基礎進行;今天來完成房間資訊頁,並比較看看和原先jQuery差別在哪!
昨天我們透過Vue處理網站前端的靜態資料,進入房間資訊頁發現介面上有許多區塊需要動態渲染:
因此,想藉由.NET Core進行SSR之前先讓Vue處理好這兩區畫面就能透過Axios來實現!
◎小提示:Axios是以Promise為基礎(promise-based)的HTTP請求工具,提供Get和Post方法
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
▲我嘗試透過npm下載,但一直無法順利引用node_modules之下的套件
const url= './RoomService?No=' + '@ViewData["No"]';
axios.get(url)
.then((res) => {
console.log(res.data)
})
我們透過單一url夾帶參數的方式呼叫api,並取得res.data
,也可以一次請求多個url:
const url1 = './RoomService?No=' + '@ViewData["No"]';
const url2 = './RoomInfo?No=' + '@ViewData["No"]';
const request1 = axios.get(url1);
const request2 = axios.get(url2);
axios.all([request1, request2])
.then(axios.spread((response1, response2) => {
// 在這裡處理 response1 和 response2
...
}))
.catch((error) => {
// 處理錯誤
});
import { ref, createApp } from '../../vue/dist/vue.esm-browser.prod.js';
const url1 = './RoomService?No=' + '@ViewData["No"]';
const url2 = './RoomInfo?No=' + '@ViewData["No"]';
createApp({
setup() {
const nowImg = ref(1);
const roomItem = ref();
const roomInfo = ref();
const roomImg = ref([]);
const request1 = axios.get(url1);
const request2 = axios.get(url2);
axios.all([request1, request2])
.then(axios.spread((response1, response2) => {
// 在這裡處理 response1 和 response2
roomItem.value = response1.data;
roomInfo.value = response2.data;
let array = response2.data[0].bS01_07.split(",");
for (var y = 0; y < array.length; y++) {
roomImg.value.push({
id:y+1,
src: array[y]
});
};
}))
.catch((error) => {
// 處理錯誤
});
return { roomItem, roomInfo, roomImg, nowImg };
},
}).mount("#roomDetail");
Controller
處理資料No
取得詳細資料 //進入房間資訊頁
public IActionResult RoomDetail(int No) {
ViewData["No"] = No;
return View();
}
RoomInfo
:透過get
發送請求1領取該房相關資料,BS01_07-BS01_09
為房間照片,將三個欄位合併一起回傳 //取得房間相關資料
public IEnumerable RoomInfo(int No)
{
var result = from room in ud_RoomContext.ut_BS001
where room.BS01_02.Equals(No)
select new ut_BS001
{
BS01_01 = room.BS01_01,
BS01_02 = room.BS01_02,
BS01_03 = room.BS01_03,
BS01_04 = room.BS01_04,
BS01_05 = room.BS01_05,
BS01_07 = room.BS01_07 == null ? "roomsetting.png" :
room.BS01_07 + (room.BS01_08 != null ? "," + room.BS01_08 + (room.BS01_09 != null ? "," + room.BS01_09 : "") : "")
};
return result;
}
RoomService
:透過get
發送請求2領取該房提供的相關服務設施,服務設施記錄在BS01_06
欄位,進入ut_BS001_A
表比對之後回傳相符的資料 //取得房間相關設施
public IEnumerable RoomService(int No) {
var result = from room in ud_RoomContext.ut_BS001_A
let trimmedValue = (room.BS01A_01).ToString().Trim()
where ud_RoomContext.ut_BS001
.Where(b => b.BS01_02.Equals(No))
.Select(b => b.BS01_06)
.Any(bs01_06 => bs01_06.Contains(trimmedValue))
select new ut_BS001_A
{
BS01A_01 = room.BS01A_01,
BS01A_02 = room.BS01A_02,
BS01A_03 = room.BS01A_03
};
return result;
}
View
渲染資料我們在Vue裡面宣告了多個響應式資料去接Axios
的回傳結果:
const nowImg = ref(1); //紀錄當前輪播圖片
const roomItem = ref(); //房間提供的服務設施
const roomInfo = ref(); //房間資訊,價格等
const roomImg = ref([]); //房間照片
...
roomItem.value = response1.data;
roomInfo.value = response2.data;
let array = response2.data[0].bS01_07.split(",");
for (var y = 0; y < array.length; y++) {
roomImg.value.push({
id:y+1,
src: array[y]
});
};
}))
▲房間照片的內容包在response2.data
裡面,因此還要再做一個拆解的動作
接下來的v-for
渲染,就跟昨天首頁的渲染方式很像,不過這次的資料我們是從DB拿過來的:
<div class="carousel-indicators">
<button v-for="img in roomImg" v-bind:key="img.id" type='button' data-bs-target='#carouselExampleIndicators' v-bind:data-bs-slide-to="img.id-1" v-bind:class="{'active' : nowImg === img.id}" aria-current="true">
<img v-bind:src="'../../img/'+img.src" class='d-block w-100'>
</button>
</div>
<div class="carousel-inner">
<div class="carousel-item" v-bind:class="{'active' : nowImg === img.id}" v-for="img in roomImg" v-bind:key="img.id">
<img v-bind:src="'../../img/'+img.src" class="d-block w-100">
</div>
</div>
順帶一提,這個環節我之前透過js寫,是透過ajax的方式拿資料,寫出來長這樣:
//放房間相關圖片
$.ajax({
url: './GetRoomDetail',
type: 'POST',
async: false,
data: { BS01_02: No },
success: function (data) {
var result = JSON.parse(data);
var num = 1;
for (var i = 7; i < 12; i++) {
var str = "0";
if (i < 10) {
str += i;
} else {
str = i;
}
if (result["BS01_" + str] != "" && result["BS01_" + str] != undefined) {
if (i == 7) {
$(".carousel-indicators").append("<button type='button' data-bs-target='#carouselExampleIndicators' style='width:120px;height:60px' data-bs-slide-to='" + (num - 1) + "' class='active' aria-current='true' aria-label='Slide " + num + "'><img src='../../Image/" + result["BS01_" + str] + "' class='d-block w-100'></button>");
$(".carousel-inner").append(" <div class='carousel-item active'><img src='../../Image/" + result["BS01_" + str] + "' class='d-block w-100'></div>");
} else {
$(".carousel-indicators").append("<button type='button' data-bs-target='#carouselExampleIndicators' style='width:120px;height:60px' data-bs-slide-to='" + (num - 1) + "' aria-label='Slide " + num + "'><img src='../../Image/" + result["BS01_" + str] + "' class='d-block w-100'></button>");
$(".carousel-inner").append("<div class='carousel-item'><img src='../../Image/" + result["BS01_" + str] + "' class='d-block w-100'></div>");
}
num += 1;
} else {
if (i == 7) {
$(".carousel-indicators").append("<button type='button' data-bs-target='#carouselExampleIndicators' style='width:120px;height:60px' data-bs-slide-to='" + (num - 1) + "' class='active' aria-current='true' aria-label='Slide " + num + "'><img src='../../Image/roomsetting_big.png' class='d-block w-100'></button>");
$(".carousel-inner").append("<div class='carousel-item active'><img src='../../Image/roomsetting_big.png' class='d-block w-100'></div>");
break;
} else {
break;
}
}
}
◎說明:一樣從後端拿到一包房間資料,用迴圈判斷到圖片欄位的時候,append
Html到介面上,看起來超級阿雜的…
<div id="ItemList">
<span v-for="item in roomItem" v-bind:key="item.bS01A_01">
<img v-bind:src="'../../img/'+item.bS01A_03" />
<text>{{item.bS01A_02}}</text>
</span>
</div>
我們一樣跟js寫法比較看看,也是透過js去塞html,非常不好維護:
//取得目前所有設施
$.ajax({
url: './GetAllItem',
type: 'POST',
async: false,
data: {},
success: function (data) {
var result = JSON.parse(data);
var num = 0;
for (var i = 0; i < result.length; i++) {
if (i == 0 || i % 2 == 0) {
num += 1;
$("#ItemList").append("<div id='ItemRow" + num + "' style='display:flex;flex-direction:column;margin-left:2%;margin-top:2%;'></div>");
}
$("#ItemRow" + num).append("<span id='item" + result[i].BS01A_01 + "' style='color:#b3b3b3'><img style='filter:opacity(0.3);' src='../../Image/" + result[i].BS01A_03 + "'> " + result[i].BS01A_02 + " </span></br>");
}
},
error: function (err) {
console.log("無法取得當前所有設施列表!");
},
});
改版訂房網站壓在三天內最終還是太硬了啦!TT,又要透過我沒接觸過的.net Core還有LinQ語法真的是很難徹底改版,內容的重點稍微調整了一下,看看Vue引入到專案後是如何改善我的前端程式碼,這樣一比較下來真的覺得之前用ajax也寫得太恐怖了吧…
參考資料
在Vue.js中使用Axios取得資料
Axios 并发请求怎么实现?这里有三种方法帮助你