1. 移動端適配,頁面高度沒有寫死,使用 input 標(biāo)簽時,喚起的虛擬鍵盤導(dǎo)致頁面頂起和壓縮
-
原因:使用的 flex 布局,頁面的高度是所有的元素的高度都是自適應(yīng)的,高度未寫死,當(dāng)出現(xiàn)虛擬鍵盤時,會造成頁面布局混亂,底部元素被頂起及 input 的上一個元素被壓縮
before.jpeg
after.jpeg 解決思路,既然是高度沒有寫死的造成的,那么將高度寫死不就好了么?
但是高度寫死了,還怎么適配不同的手機?不能將高度寫死
那么,它只在鍵盤喚起的那一刻需要高度,那么,我們在喚起鍵盤的那一刻將下面的元素隱藏掉,當(dāng)鍵盤消失時再將元素顯示出來
方案一: 使用 v-show 來控制元素的顯示與隱藏
- click 時 isShow = false, 失去焦點時 isShow = true
// 帶有 input 元素的 FormItem.vue
<input type="text"
class="input-notes"
:value="value"
@input="onValueChange($event.target.value)"
:placeholder="placeholder"
@click="$emit('update:isShow',false)"
@blur="$emit('update:isShow',true)"
>
// 調(diào)用 FormItem.vue 的組件 Money.vue
<Layout class-prefix="xxx" ref="layout" :is-show="isShow"> <--! 因為把底部組件放 Layout組件里,要給其傳一個值-->
<NumberPad v-show="isShow"/> <--! 2. 控制要隱藏的變量 -->
<FormItem @update:isShow="(value) => {isShow=value}"/> <--! 3. 當(dāng)觸發(fā)input的click事件時,改變isShow的值 -->
<Tags :data-source.sync="tagsList" @update:selectedTag="selectedTag"/>
</Layout>
isShow = true // 1. 先定義一個變量 isShow,用來控制顯示和隱藏
// Layout.vue 組件
<div class="layout-wrapper">
....
<Nav v-show="isShow"/>
</div>
props:['isShow']
效果:是解決了頂起和壓縮問題,
引發(fā)問題:
- 但是要點擊其它地方使 input 失去焦點,不然就會變成右邊的圖
- 且點擊其它地方時頁面會出現(xiàn)閃爍問題
- 在這里,會影響其它頁面,為了實現(xiàn)這個,我必須在所有用到 Layout.vue 這個組件的地方,給其傳一個屬性
v-show="true",不然的話,被isShow控制的那個組件就會不顯示。
總結(jié):這個方案既麻煩又不好用,特別是對于由好多組件組成的頁面

1.jpeg

2.jpeg
方案二: window.onresize 時結(jié)合 v-show 來隱藏元素
- 那不通過判斷input的狀態(tài),而是通過監(jiān)聽resize事件,當(dāng)屏幕高度發(fā)生變化時,控制元素的隱藏展示
- 其它的和方案一一樣
// Money.vue
height = document.body.clientHeight;
isShow = true
mounted(){
window.addEventListener('resize', ()=>{
if(document.body.clientHeight < height){
this.isShow = false
}else{
this.isShow = true
}
})
}
效果:解決了頁面被頂起和壓縮的問題
問題:
- 當(dāng)虛擬鍵盤消失時,頁面會有閃爍的情況出現(xiàn)
- 還是和方案一的問題三一樣,維護比較麻煩
方案三:一進入頁面,就將頁面的高度固定下來
- 一進入頁面就獲取瀏覽器可視區(qū)的高度,然后把高度賦給根元素
// Money.vue
<Layout class-prefix="xxx" ref="layout" :style="{height:h+'px'}">
<NumberPad @update:value="onUpdateAmount" @submit="saveRecord" :x="record.tags"/>
<FormItem :value.sync="record.notes" name="備注" placeholder="請在這里輸入備注"/>
<Tags :data-source.sync="tagsList" @update:selectedTag="selectedTag"/>
<template #head>
<Tabs :value.sync="record.type"/>
</template>
</Layout>
h = document.body.clientHeight;
效果: 所有問題完美解決,頁面也不會有閃爍問題,特別簡單.........
最后附上項目預(yù)覽地址:項目 simpleBilling