实现textarea自动撑开

需求设想

实现一个具有默认高度,且随着输入内容的增加自动撑开高度的输入框

技术支持
  • visibility: hidden; 隐藏DOM但是仍然占位
  • contenteditable="true"div添加属性可以模拟输入
方法
div模拟textarea实现
HTML:
<div class="full-test" contenteditable="true">
    {{divInputValue}}
</div>

CSS:
.full-test{
    width: 100%;
    min-height: 40px;
    height: auto;
    overflow: auto;

    border: 1px solid black;
    outline: none;
}

JS:
export default {
    data () {
        return {
            divInputValue: ''
        }
    }
}

这种方式能实现,但是有一个问题,在我的vue项目中,只要一刷新就会失效,必须重新跑服务

用隐藏的p标签撑开高度
HTML:
<div class="full-box">
    <p>
        {{textareaValue}}
    </p>
    <textarea placeholder="输入文字" v-model="textareaValue"></textarea>
</div>

CSS:
.full-box
        width: 100%;
        height: auto;
        background-color: #fff;
        position: relative;

        p
            margin: 0;
            padding: 0;
            visibility: hidden;
            word-wrap: break-word;
            line-height: 1.16rem;
            min-height: 30px;

        textarea
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            text-align: left;
            line-height: 1.15rem;
            margin: 0;
            padding: 0;
            
JS:
export default {
    data () {
        return {
            textareaValue: ''
        }
    }
}

这种方式的实现思路是textarea跟随父元素高度,同时用兄弟原色撑开父元素即可

值得注意的点是p标签与textarea的文字设置需要一致

组件封装
/**
 * 实现随着输入内容增多,自动增高的输入框
 * 父组件调用示例:
 * <taTextarea 
 *  :textareaValue="divInputValue" 
 *  v-model="divInputValue"></taTextarea>
 * @time: 2018.9.20
 * @Author: Nick_yangxiaotong
 */

<template>
    <div class="ta-textarea">
        <p>
            {{textValue}}
        </p>
        <textarea 
            :class="{ 'align-right': alignRight }"
            :placeholder="placeholder" 
            v-model="textValue"></textarea>
    </div>
</template>

<script>

export default {
    data () {
        return {
            textValue: ''
        }
    },
    props: {
        textareaValue: {    // 默认文案
            type: String,
            default: ''
        },
        placeholder: {  // 文本提示文案
            type: String,
            default: '请输入'
        },
        alignRight: {   // 文本是否需要右对齐
            type: Boolean,
            default: false
        }
    },
    created () {
        if (this.textareaValue) this.textValue = this.textareaValue
    },
    watch: {
        // 监听数据变化,改变父组件值
        textValue () {
            this.$emit('input', this.textValue)
        }
    }
}
</script>

<style lang="stylus" scoped>
    .ta-textarea
        width: 100%;
        height: auto;
        background-color: #fff;
        position: relative;

        p
            margin: 0;
            padding: 0;
            visibility: hidden;
            word-wrap: break-word;
            line-height: 1.16rem;
            min-height: 30px;

        textarea
            position: absolute;
            top: 0;
            left: 0;
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            line-height: 1.15rem;
            text-align left;
        .align-right
            text-align: right;
</style>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值