title: 使用 createError 創建錯誤對象的詳細指南 date: 2024/8/8 updated: 2024/8/8 author: cmdragon excerpt: 摘要:本文介紹了createError函數在Nuxt應用開發中的使用方法,用於創建帶有附加元數據的錯誤對象,以提升 ...
vue前端自適應佈局,一步到位所有自適應
頁面展示
實現內容
1,左右佈局
- 左側固定寬頻,右側自適應剩餘的寬度。
- 中間一條分割線,可以拖拉,自適應調整左右側的寬度。
- 左側的高度超長自動出現橫向滾動條,左側寬度超長,自動出現豎向滾動條。
2,上中下佈局
- 最上面的 搜索條件 div 固定占用 100 px 高度,下麵的 查詢條件 div 固定占用 30 px 高度,最下麵的分頁固定占用高度,頁面剩下的高度自動分配給中間的表格內容。
- 表格內容高度超過後自動出現豎向滾動條,寬度超出後自動出現橫向滾動條。
- 點擊按鈕,可以 隱藏/顯示 搜索條件 div 裡面的內容。
- 當隱藏 搜索條件 div 裡面的內容時,中間表格的高度為:整個頁面的高度—操作按鈕div的高度—分頁div的高度。
- 當搜索條件 div 裡面的內容時,中間表格的高度為:整個頁面的高度—搜索條件div的高度—操作按鈕div的高度—分頁div的高度。
3,解析度自適應
- 載入即動態實時計算高度,寬度
實現代碼
vue2 版本代碼
<template>
<div class="app-container">
<div class="left" :style="{ width: leftWidth + 'px' }">
<div class="right-center-left">
左邊的內容,可以很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
</div>
</div>
<div class="divider" @mousedown="startDragging"></div>
<div class="right">
<div v-if="showDiv1" class="div1">查詢條件</div>
<div class="div2">
<button @click="toggleDiv1">操作按鈕 div1</button>
</div>
<div class="div3" :style="{ height: div3Height + 'px' }">
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
</div>
<div class="div4">分頁</div>
</div>
</div>
</template>
<script>
export default {
name: "AppContainer",
data() {
return {
isDragging: false,
leftWidth: 200,
showDiv1: true
};
},
computed: {
div3Height() {
const totalHeight = window.innerHeight;
const div2Height = 30;
const div4Height = 30;
const div1Height = this.showDiv1 ? 100 : 0;
// 計算 div3 的高度
return totalHeight - div2Height - div4Height - div1Height;
}
},
methods: {
startDragging(e) {
this.isDragging = true;
document.addEventListener("mousemove", this.onDrag);
document.addEventListener("mouseup", this.stopDragging);
},
onDrag(e) {
if (this.isDragging) {
const minWidth = 50;
const maxWidth = window.innerWidth - 50;
const newLeftWidth = e.clientX;
if (newLeftWidth > minWidth && newLeftWidth < maxWidth) {
this.leftWidth = newLeftWidth;
}
}
},
stopDragging() {
this.isDragging = false;
document.removeEventListener("mousemove", this.onDrag);
document.removeEventListener("mouseup", this.stopDragging);
},
toggleDiv1() {
this.showDiv1 = !this.showDiv1;
}
}
};
</script>
<style scoped>
.app-container {
display: flex;
height: 100vh;
overflow: hidden;
}
.left {
overflow-x: auto;
overflow-y: auto;
white-space: nowrap;
min-width: 90px;
}
.divider {
width: 5px;
cursor: ew-resize;
background-color: #ccc;
}
.right {
display: flex;
flex-direction: column;
height: 100%;
flex: 1; /* 自動填滿剩餘寬度 */
}
.div1 {
height: 100px;
background-color: #f0f0f0;
}
.div2 {
height: 30px;
background-color: #ddd;
}
.div3 {
overflow-x: auto; /* 添加橫向滾動條 */
overflow-y: auto; /* 添加縱向滾動條 */
background-color: #f5f5f5;
}
.div4 {
height: 200px;
background-color: #ccc;
}
</style>
vue3 版本代碼
<template>
<div class="app-container">
<div class="left" :style="{ width: leftWidth + 'px' }">
左邊的內容,可以很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
</div>
<div class="divider" @mousedown="startDragging"></div>
<div class="right">
<div v-if="showQueryDiv" class="right-query">搜索條件</div>
<div class="right-button">
<div class="right-button-left">操作按鈕</div>
<div class="right-button-right">
<button @click="toggleQueryDiv">隱藏/展示 搜索條件</button>
</div>
</div>
<div class="right-table" :style="{ height: tableHeight + 'px' }">
表格內容<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
</div>
<div class="right-page">分頁內容</div>
</div>
</div>
</template>
<script>
import { ref, computed, onMounted, onUnmounted } from 'vue';
export default {
name: "AppContainer",
setup() {
const isDragging = ref(false);
const leftWidth = ref(200);
const showQueryDiv = ref(true);
const tableHeight = computed(() => {
const totalHeight = window.innerHeight;
const buttonHeight = 30;
const pageHeight = 30;
const queryHeight = showQueryDiv.value ? 100 : 0;
return totalHeight - buttonHeight - pageHeight - queryHeight;
});
const startDragging = (e) => {
isDragging.value = true;
document.addEventListener("mousemove", onDrag);
document.addEventListener("mouseup", stopDragging);
};
const onDrag = (e) => {
if (isDragging.value) {
const minWidth = 50;
const maxWidth = window.innerWidth - 50;
const newLeftWidth = e.clientX;
if (newLeftWidth > minWidth && newLeftWidth < maxWidth) {
leftWidth.value = newLeftWidth;
}
}
};
const stopDragging = () => {
isDragging.value = false;
document.removeEventListener("mousemove", onDrag);
document.removeEventListener("mouseup", stopDragging);
};
const toggleQueryDiv = () => {
showQueryDiv.value = !showQueryDiv.value;
};
onMounted(() => {
window.addEventListener("resize", onDrag);
});
onUnmounted(() => {
window.removeEventListener("resize", onDrag);
});
return {
leftWidth,
showQueryDiv,
tableHeight,
startDragging,
toggleQueryDiv
};
}
};
</script>
<style scoped>
.app-container {
display: flex;
height: 100vh;
overflow: hidden;
}
.left {
overflow-x: auto;
overflow-y: auto;
white-space: nowrap;
min-width: 90px;
}
.divider {
width: 5px;
cursor: ew-resize;
background-color: #ccc;
}
.right {
display: flex;
flex-direction: column;
height: 100%;
flex: 1; /* 自動填滿剩餘寬度 */
}
.right-query {
height: 100px;
background-color: #f0f0f0;
}
.right-button {
height: 30px;
display: flex;
justify-content: space-between; /* 左右對齊內容 */
align-items: center; /* 垂直居中對齊 */
background-color: #ddd;
}
.right-button-left {
margin-left: 5px;
text-align: left;
}
.right-button-right {
margin-right: 5px;
text-align: right;
}
.right-table {
overflow-x: auto; /* 添加橫向滾動條 */
overflow-y: auto; /* 添加縱向滾動條 */
background-color: #f5f5f5;
}
.right-page {
height: 200px;
background-color: #ccc;
}
</style>
實現感想
這個功能,從畢業就開始思索,直到八年後的今天成熟完善,真是艱辛也是很不容易。目前市面上沒有見過有人實現,很多人都是隻言片語的,基本複製下來,無法達到效果。我這個一鍵複製到自己的項目,就能實現了,中間的坎坷不平,到了完全實現的這一刻,才覺得激動不已。
無任何坑,也沒有任何額外的引入,一個普普通通,最簡單的vue頁面,佈局建好,裡面的內容就可以自己隨意發揮了。
未覺池塘春草夢,階前梧葉已秋聲。記錄激動時刻,也造福後來人。