返回

揭秘「Vue3+ElementUI」打造悬浮多行文本输入框的奥秘:Levitation in Text

前端

悬浮多行文本输入框:提升用户体验的利器

什么是悬浮多行文本输入框?

悬浮多行文本输入框顾名思义,就是文本输入框可以悬浮在其他元素之上,并且可以输入多行文本。这种输入框在许多场景下都非常有用,比如撰写评论、回复邮件、填写表单等。

基于 Vue3 和 ElementUI 实现悬浮多行文本输入框

基于 Vue3 和 ElementUI 实现悬浮多行文本输入框非常简单,只需要创建自定义组件即可:

<template>
  <div>
    <el-input
      v-model="value"
      :placeholder="placeholder"
      :rows="rows"
      :disabled="disabled"
      @focus="onFocus"
      @blur="onBlur"
    />
    <div
      v-if="showPopover"
      class="popover"
      :style="{
        top: popoverTop,
        left: popoverLeft
      }"
    >
      <el-input
        v-model="popoverValue"
        :placeholder="popoverPlaceholder"
        :rows="popoverRows"
        :disabled="popoverDisabled"
        @focus="onPopoverFocus"
        @blur="onPopoverBlur"
      />
    </div>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount } from 'vue'

export default {
  name: 'LevitationMultipleInput',
  props: {
    value: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: ''
    },
    rows: {
      type: Number,
      default: 1
    },
    disabled: {
      type: Boolean,
      default: false
    },
    popoverPlaceholder: {
      type: String,
      default: ''
    },
    popoverRows: {
      type: Number,
      default: 5
    },
    popoverDisabled: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:value', 'focus', 'blur', 'popover-focus', 'popover-blur'],
  setup(props, { emit }) {
    const value = ref(props.value)
    const popoverValue = ref('')
    const showPopover = ref(false)
    const popoverTop = ref('')
    const popoverLeft = ref('')

    const onFocus = () => {
      emit('focus')
      showPopover.value = true
      setTimeout(() => {
        const input = document.querySelector('.popover input')
        const rect = input.getBoundingClientRect()
        popoverTop.value = `${rect.top - 10}px`
        popoverLeft.value = `${rect.left}px`
      }, 100)
    }

    const onBlur = () => {
      emit('blur')
      showPopover.value = false
      value.value = popoverValue.value
    }

    const onPopoverFocus = () => {
      emit('popover-focus')
    }

    const onPopoverBlur = () => {
      emit('popover-blur')
      showPopover.value = false
      value.value = popoverValue.value
    }

    onMounted(() => {
      document.addEventListener('click', (e) => {
        if (!e.target.closest('.levitation-multiple-input')) {
          showPopover.value = false
        }
      })
    })

    onBeforeUnmount(() => {
      document.removeEventListener('click', (e) => {
        if (!e.target.closest('.levitation-multiple-input')) {
          showPopover.value = false
        }
      })
    })

    return {
      value,
      popoverValue,
      showPopover,
      popoverTop,
      popoverLeft,
      onFocus,
      onBlur,
      onPopoverFocus,
      onPopoverBlur
    }
  }
}
</script>

<style>
.popover {
  position: absolute;
  z-index: 10;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 10px;
  border-radius: 5px;
}
</style>

代码示例:

<LevitationMultipleInput />

优点:

悬浮多行文本输入框具有以下优点:

  • 不会遮挡底层元素,从而提高用户体验
  • 可以输入多行文本,适合撰写较长内容
  • 可以自定义悬浮框的位置和样式

常见问题解答:

1. 如何禁用悬浮框?

可以通过设置 popoverDisabled 属性为 true 来禁用悬浮框。

2. 如何更改悬浮框的位置?

可以通过设置 popoverToppopoverLeft 属性来更改悬浮框的位置。

3. 如何监听悬浮框的聚焦和失焦事件?

可以通过监听 popover-focuspopover-blur 事件来监听悬浮框的聚焦和失焦事件。

4. 如何自定义悬浮框的样式?

可以通过覆盖 .popover 样式来自定义悬浮框的样式。

5. 如何在 Vue3 中使用悬浮多行文本输入框?

在 Vue3 中使用悬浮多行文本输入框,需要先安装 ElementUI,然后在项目中注册 LevitationMultipleInput 组件,最后在模板中使用该组件。