本文首发于个人博客 Cyy’s Blog
转载请注明出处 https://cyyjs.top/blog/5c651b21ee82320b23674355

小程序开发过程中,当我们在一个有表单页面上,写了一个弹出层时,会发现input的输入框,会浮在弹出框之上;并且设置z-index值也不起作用,这是因为input是原生组件,层级比view要高。

那么如何解决呢?

# 思路

既然弹框的时候,input会浮动,那我们在弹框显示时,隐藏掉input不就好了。

# 有什么问题呢

这样虽然可以几觉浮动的问题,但是由于input被隐藏,会导致页面布局发生改变,产生抖动。

# 解决方法

input隐藏的时候,使用view标签替换,并显示当前的值。

# 更好的解决办法

既然每次显示弹框都需要隐藏显示input,太过麻烦,我们何不直接用view替换掉input呢?
即用view替代默认的input,并使view拥有input的样式,当点击view时,隐藏view并显示input

使用vue重新编写input组件代码如下:

<template>
    <div>
        <input
            :focus="focus"
            @input="input"
            @blur="blur"
            v-if="showInput"
            :value="v"
            :type="type"
            :class="className"
            :placeholder="placeholder"
        >
        <div :class="[className, 'input']" @tap="focusEvent" v-if="!showInput">{{v || placeholder}}</div>
    </div>
</template>
<script>
export default {
    name: 'MInput',
    props: {
        align: {
            type: String,
            default: 'left'
        },
        placeholder: String,
        type: String,
        value: String
    },
    data() {
        return {
            showInput: false,
            v: this.value || '',
            focus: false
        }
    },
    computed: {
        className() {
            if (this.align) {
                return 'input_' + this.align
            }
            return ''
        }
    },
    methods: {
        blur(e) {
            this.$emit('input', this.v)
            this.showInput = false
        },
        input(e) {
            this.v = e.target.value
        },
        focusEvent() {
            this.focus = true
            this.showInput = true
        }
    }
}
</script>
<style lang="scss" scoped>
.input {
    padding: 0 10px;
    color: #666;
    display: block;
    text-overflow: clip;
    overflow: hidden;
    white-space: nowrap;
    font-family: UICTFontTextStyleBody;
    height: 28px;
    font-size: 16px;
    line-height: 28px;
}
.input_right {
    text-align: right;
    padding-right: 20px;
}
</style>

使用的时候引入上面的组件:

<m-input v-model="name" type="text" placeholder="请输入名称"></m-input>

这样就解决了弹窗表单元素浮动的问题。