目录
一、问题
二、解决方法
三、总结
tiips:如嫌繁琐,直接移步总结即可!
一、问题
1.使用原生input写了一个搜索框,在模拟器和pc上一切正常。但是打包放到手机上,样式就有问题:这个搜索框的布局是正常的,但是聚焦到input上,就可以看到input明显溢出了!
二、解决方法
1.真是奇怪,我也没有写什么奇怪的东西呀。pc端和移动端的模拟器都是没有问题的。
布局就是简单的flex布局。input 框 flex:1,其余图标自适应。怎么到移动端就有问题呢?
1)代码如下:
<template>
<!-- 搜索组件 -->
<div :class="['search-wrap', { round: round }]">
<template v-if="isCenterStart">
<span class="center" @click.stop="clickCenter">
<span class="icon left-icon" v-if="leftIcon">
<svg-icon :iconClass="leftIcon"></svg-icon>
</span>
<span>{{ placeholder }}</span>
</span>
</template>
<template v-else>
<span class="icon left-icon" v-if="leftIcon">
<svg-icon :iconClass="leftIcon"></svg-icon>
</span>
<input
v-model="currentValue"
class="input-area"
:placeholder="placeholder"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
/>
<span v-if="currentValue" class="icon right-icon clear-icon" @click.stop="handleClear">
<svg-icon :iconClass="'clearInput'"></svg-icon>
</span>
<span v-if="rightIcon" :class="['icon', { 'right-icon': rightIcon }]">
<svg-icon :iconClass="rightIcon"></svg-icon>
</span>
<slot></slot>
</template>
</div>
</template>
<script>
import { nextTick } from 'process';
import { defineComponent, onMounted, ref, watch, getCurrentInstance } from 'vue';
//使用的时候需要用v-model
export default defineComponent({
props: {
//搜索框的值
value: {
type: String,
default: ''
},
//提示
placeholder: {
type: String,
default: '请输入'
},
//左图标
leftIcon: {
type: String,
default: 'search'
},
//右图标
rightIcon: {
type: String,
default: ''
},
//是否圆角
round: {
type: Boolean,
default: false
},
//刚开始是否居中
isCenter: {
type: Boolean,
default: false
}
},
components: {},
setup(props, { emit, slots }) {
const { proxy } = getCurrentInstance();
//当前输入的值
const currentValue = ref('');
onMounted(() => {
currentValue.value = props.value;
});
//输入事件
const handleInput = () => {
//输入了字符再触发
// if (currentValue.value?.trim()) {
emit('input', currentValue.value);
// }
};
//清除
const handleClear = () => {
currentValue.value = '';
setCenter();
emit('input', currentValue.value);
emit('clear');
};
//聚焦
const handleFocus = () => {
emit('focus', currentValue.value);
};
//失焦
const handleBlur = () => {
setCenter();
emit('blur', currentValue.value);
};
//初始时是否显示在中间
const isCenterStart = ref(props.isCenter);
const clickCenter = () => {
isCenterStart.value = false;
nextTick(() => {
proxy.$el.querySelector('input')?.focus();
});
};
const setCenter = () => {
if (props.isCenter && !currentValue.value) {
isCenterStart.value = true;
}
};
watch(
() => props.value,
(newVal) => {
currentValue.value = newVal;
}
);
return {
currentValue,
handleInput,
handleClear,
handleFocus,
handleBlur,
clickCenter,
isCenterStart
};
}
});
</script>
<style lang="scss" scoped>
.search-wrap {
display: flex;
justify-content: space-between;
padding: 20px 40px;
background: #f1f3f7;
border-radius: 18px;
align-items: center;
.icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
}
.right-icon {
margin-left: 20px;
}
.clear-icon {
font-size: 60px;
}
.input-area {
flex: 1;
font-size: 51px;
line-height: 69px;
margin-left: 36px;
border: none;
background: none;
&::placeholder {
color: #acacac;
}
&:focus-visible {
outline: none;
}
}
}
.round {
background: rgba(255, 255, 255, 0.5);
border-radius: 54px;
}
.center {
width: 100%;
display: flex;
justify-content: center;
color: #acacac;
font-size: 51px;
line-height: 75px;
transition: ease-in-out;
span {
margin-left: 36px;
}
}
</style>
2.只能一个个试试到底哪个样式有问题。
3.发现注释了 最外层父盒子的 display:flex,竟然不溢出了。
4.但是吧,我确实需要用flex布局,让子元素一行显示,这样的修改显然不科学。。。
5.最后的最后发现,只需要在 input上 加上样式 width:100%;就好了。甚至flex:1`都不需要!!!!!
6.问题是解决了,但是原因真不知道。。。。。
三、总结
1.移动端怎么会有这么多奇怪的问题呢?
2.移动端确实需要在真机上测试才靠谱!
3.移动端input溢出:尝试设置input width:100%;
4.猜测可能是手机上有内置的样式,所以我们不设置的时候,使用了默认的样式,导致了最终的样式和预期不一致。(有大佬知道原因,欢迎评论区告知,非常感谢!)
/*
希望对你有帮助!
如有错误,欢迎指正,非常感谢!
*/