Input 输入框
通过鼠标或键盘输入字符
ts
import { createApp } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const app = createApp()
app.use(ElInput)基础用法
<template>
<el-input v-model="input" style="width: 240px" placeholder="Please input" />
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('')
</script>禁用状态
<template>
<el-input
v-model="input"
style="width: 240px"
disabled
placeholder="Please input"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('')
</script>一键清空
<template>
<div class="input-group">
<el-input
v-model="input"
style="width: 240px"
placeholder="Please input"
clearable
/>
<el-input
v-model="textareaInput"
style="width: 240px"
placeholder="Please input"
type="textarea"
clearable
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('')
const textareaInput = ref('')
</script>
<style scoped>
.input-group {
display: flex;
align-items: center;
gap: 1em;
}
</style>自定义清除图标 (2.11.0)
<template>
<div class="input-group">
<el-input
v-model="input"
clearable
:clear-icon="CloseBold"
placeholder="Custom clear icon"
/>
<el-input
v-model="textareaInput"
clearable
:clear-icon="CloseBold"
placeholder="Custom clear icon"
type="textarea"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { CloseBold } from '@szhn/dh-design-pc/icons'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('Custom clear icon')
const textareaInput = ref('Custom clear icon')
</script>
<style scoped>
.input-group {
display: flex;
flex-direction: column;
gap: 1em;
}
</style>格式化
在 formatter的情况下显示值,我们通常同时使用 parser
<template>
<el-input
v-model="input"
style="width: 240px"
placeholder="Please input"
:formatter="format"
:parser="parse"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('')
const format = (value: string | number) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
const parse = (value: string) => value.replace(/\$\s?|(,*)/g, '')
</script>密码框
<template>
<div class="input-group">
<el-input
v-model="input"
style="width: 240px"
type="password"
placeholder="Please input password"
show-password
/>
<el-input
v-model="input"
style="width: 240px"
type="password"
placeholder="Please input password"
show-password
>
<template #password-icon="{ visible }">
<el-icon :size="16">
<Unlock v-if="visible" />
<Lock v-else />
</el-icon>
</template>
</el-input>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Lock, Unlock } from '@szhn/dh-design-pc/icons'
import { Icon as ElIcon, Input as ElInput } from '@szhn/dh-design-pc'
const input = ref('')
</script>
<style scoped>
.input-group {
display: flex;
align-items: center;
gap: 1em;
}
</style>带图标的输入框
带有图标标记输入类型
<template>
<div class="demo-input-with-icon">
<div class="input-group">
<span class="label">Using attributes</span>
<div class="input-container">
<el-input
v-model="input1"
class="responsive-input"
placeholder="Pick a date"
:suffix-icon="Calendar"
/>
<el-input
v-model="input2"
class="responsive-input"
placeholder="Type something"
:prefix-icon="Search"
/>
</div>
</div>
<div class="input-group">
<span class="label">Using slots</span>
<div class="input-container">
<el-input
v-model="input3"
class="responsive-input"
placeholder="Pick a date"
>
<template #suffix>
<el-icon class="el-input__icon"><calendar /></el-icon>
</template>
</el-input>
<el-input
v-model="input4"
class="responsive-input"
placeholder="Type something"
>
<template #prefix>
<el-icon class="el-input__icon"><search /></el-icon>
</template>
</el-input>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Calendar, Search } from '@szhn/dh-design-pc/icons'
import { Icon as ElIcon, Input as ElInput } from '@szhn/dh-design-pc'
const input1 = ref('')
const input2 = ref('')
const input3 = ref('')
const input4 = ref('')
</script>
<style scoped>
.demo-input-with-icon {
width: 100%;
}
.input-group {
margin-bottom: 1.5rem;
}
.label {
display: block;
margin-bottom: 1rem;
color: var(--el-text-color-regular);
}
.input-container {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.responsive-input {
width: 240px;
}
@media (max-width: 768px) {
.input-container {
flex-direction: column;
gap: 1rem;
}
.responsive-input {
width: 100%;
}
}
</style>文本域
用于输入多行文本信息可缩放的输入框。 添加 type="textarea" 属性来将 input 元素转换为原生的 textarea 元素。
<template>
<el-input
v-model="textarea"
style="width: 240px"
:rows="2"
type="textarea"
placeholder="Please input"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const textarea = ref('')
</script>自适应文本域
设置文字输入类型的 autosize 属性使得根据内容自动调整的高度。 你可以给 autosize 提供一个包含有最大和最小高度的对象,让输入框自动调整。
<template>
<el-input
v-model="textarea1"
style="width: 240px"
autosize
type="textarea"
placeholder="Please input"
/>
<div style="margin: 20px 0" />
<el-input
v-model="textarea2"
style="width: 240px"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
placeholder="Please input"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const textarea1 = ref('')
const textarea2 = ref('')
</script>复合型输入框
可以在输入框中前置或后置一个元素,通常是标签或按钮。
<template>
<div>
<el-input
v-model="input1"
style="max-width: 600px"
placeholder="Please input"
>
<template #prepend>Http://</template>
</el-input>
</div>
<div class="mt-4">
<el-input
v-model="input2"
style="max-width: 600px"
placeholder="Please input"
>
<template #append>.com</template>
</el-input>
</div>
<div class="mt-4">
<el-input
v-model="input3"
style="max-width: 600px"
placeholder="Please input"
class="input-with-select"
>
<template #prepend>
<el-select v-model="select" placeholder="Select" style="width: 115px">
<el-option label="Restaurant" value="1" />
<el-option label="Order No." value="2" />
<el-option label="Tel" value="3" />
</el-select>
</template>
<template #append>
<el-button :icon="Search" />
</template>
</el-input>
</div>
<div class="mt-4">
<el-input
v-model="input3"
style="max-width: 600px"
placeholder="Please input"
class="input-with-select"
>
<template #prepend>
<el-button :icon="Search" />
</template>
<template #append>
<el-select v-model="select" placeholder="Select" style="width: 115px">
<el-option label="Restaurant" value="1" />
<el-option label="Order No." value="2" />
<el-option label="Tel" value="3" />
</el-select>
</template>
</el-input>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Search } from '@szhn/dh-design-pc/icons'
import { Button as ElButton, Input as ElInput, Option as ElOption, Select as ElSelect } from '@szhn/dh-design-pc'
const input1 = ref('')
const input2 = ref('')
const input3 = ref('')
const select = ref('')
</script>
<style>
.input-with-select .el-input-group__prepend {
background-color: var(--el-fill-color-blank);
}
</style>尺寸
<template>
<div class="flex gap-4 mb-4 items-center">
<el-input
v-model="input1"
style="width: 240px"
size="large"
placeholder="Please Input"
/>
<el-input
v-model="input2"
style="width: 240px"
placeholder="Please Input"
/>
<el-input
v-model="input3"
style="width: 240px"
size="small"
placeholder="Please Input"
/>
</div>
<div class="flex gap-4 mb-4 items-center">
<el-input
v-model="input1"
style="width: 240px"
size="large"
placeholder="Please Input"
:suffix-icon="Search"
/>
<el-input
v-model="input2"
style="width: 240px"
placeholder="Please Input"
:suffix-icon="Search"
/>
<el-input
v-model="input3"
style="width: 240px"
size="small"
placeholder="Please Input"
:suffix-icon="Search"
/>
</div>
<div class="flex gap-4 items-center">
<el-input
v-model="input1"
style="width: 240px"
size="large"
placeholder="Please Input"
:prefix-icon="Search"
/>
<el-input
v-model="input2"
style="width: 240px"
placeholder="Please Input"
:prefix-icon="Search"
/>
<el-input
v-model="input3"
style="width: 240px"
size="small"
placeholder="Please Input"
:prefix-icon="Search"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Search } from '@szhn/dh-design-pc/icons'
import { Input as ElInput } from '@szhn/dh-design-pc'
const input1 = ref('')
const input2 = ref('')
const input3 = ref('')
</script>输入长度限制
<template>
<el-input
v-model="text"
style="width: 240px"
maxlength="10"
placeholder="Please input"
show-word-limit
type="text"
/>
<el-input
v-model="text"
class="ml-4"
style="width: 240px"
maxlength="10"
placeholder="Please input"
show-word-limit
word-limit-position="outside"
type="text"
/>
<div style="margin: 20px 0" />
<el-input
v-model="textarea"
maxlength="30"
style="width: 240px"
placeholder="Please input"
show-word-limit
type="textarea"
/>
<el-input
v-model="textarea"
class="ml-4"
maxlength="30"
style="width: 240px"
placeholder="Please input"
show-word-limit
word-limit-position="outside"
type="textarea"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const text = ref('')
const textarea = ref('')
</script>计数图形 (2.13.7)
:::小技巧
浏览器支持 & 回退策略
当使用 count-graphemes prop时,组件使用以下方法:
在实现自己的 count-graphemes 函数时,如果需要对复杂的 unicode 字符提供强大的支持,请考虑使用 Intl.Segmenter。
:::
<template>
<el-input
v-model="text"
maxlength="10"
placeholder="Please input"
show-word-limit
:count-graphemes="calc"
type="text"
/>
<div style="margin: 20px 0" />
<el-input
v-model="textarea"
maxlength="20"
placeholder="Please input"
show-word-limit
:count-graphemes="calc"
type="textarea"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { Input as ElInput } from '@szhn/dh-design-pc'
const text = ref('😀😁')
const textarea = ref('😀😁')
/**
* Count function for grapheme clustering.
* Counts the number of graphemes (visual characters) in a string.
*
* Note: This example uses Array.from() for simplicity.
* For production use, consider using Intl.Segmenter for better
* handling of complex emoji and unicode characters.
*/
const calc = (value: string) => {
// Simplified version: counts code points (not full grapheme clusters)
// For production, use Intl.Segmenter like the component does
return Array.from(value).length
}
</script>常见问题
典型问题: #7287
PS: 由于ElInput 组件没有默认宽度,当显示 clearable 图标时, 组件的宽度将被撑开,可以通过设置固定宽度属性来解决。
API
Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 输入类型,更多信息请参见 MDN | string | text |
| model-value / v-model | 绑定值 | string / number | — |
| model-modifiers 2.11.5 | v-model 修饰符,参考 Vue 修饰符 | object | — |
| maxlength | 同原生 maxlength 属性 | string / number | — |
| minlength | 原生属性,最小输入长度 | string / number | — |
| show-word-limit | 是否显示统计字数, 只在 type 为 'text' 或 'textarea' 的时候生效 | boolean | false |
| word-limit-position 2.11.5 | 字数统计的位置,仅当 show-word-limit 为 true 时生效。 | enum | "inside" |
| placeholder | 输入框占位文本 | string | — |
| clearable | 是否显示清除按钮,只有当 type 不是 textarea时生效 | boolean | false |
| clear-icon 2.11.0 | 自定义清除图标 | string / object | CircleClose |
| formatter | 指定输入值的格式。(只有当 type 是"text"时才能工作) | Function | — |
| parser | 指定从格式化器输入中提取的值。(仅当 type 是"text"时才起作用) | Function | — |
| show-password | 是否显示切换密码图标 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| size | 输入框尺寸,只在 type 不为 'textarea' 时有效 | enum | — |
| prefix-icon | 自定义前缀图标 | string / Component | — |
| suffix-icon | 自定义后缀图标 | string / Component | — |
| rows | 输入框行数,仅 type 为 'textarea' 时有效 | number | 2 |
| autosize | textarea 高度是否自适应,仅 type 为 'textarea' 时生效。 可以接受一个对象,比如: { minRows: 2, maxRows: 6 } | boolean / object | false |
| autocomplete | 原生 autocomplete 属性 | string | off |
| name | 等价于原生 input name 属性 | string | — |
| readonly | 原生 readonly 属性,是否只读 | boolean | false |
| max | 原生 max 属性,设置最大值 | — | ::: |
| min | 原生属性,设置最小值 | — | — |
| step | 原生属性,设置输入字段的合法数字间隔 | ::: | — |
| resize | 控制是否能被用户缩放 | enum | — |
| autofocus | 原生属性,自动获取焦点 | boolean | false |
| form | 原生属性 | string | — |
| aria-label a11y 2.7.2 | 等价于原生 input aria-label 属性 | string | — |
| tabindex | 输入框的 tabindex | string / number | — |
| validate-event | 输入时是否触发表单的校验 | boolean | true |
| input-style | input 元素或 textarea 元素的 style | string / object | {} |
| label a11y deprecated | 等价于原生 input aria-label 属性 | string | — |
| inputmode 2.10.3 | 等价于原生 input inputmode 属性 | string | — |
| count-graphemes 2.13.7 | 自定义函数用于计算字形;设置后,将绕过原生的 maxlength/minlength 约束。 组件使用 Intl.Segmenter(Chrome 87+、Firefox 125+、Safari 14.1+)进行正确的字素聚类;旧版浏览器回退到使用 Array.from() 进行代码点迭代。 | Function | ::: |
Events
| 事件名 | 说明 | 类型 |
|---|---|---|
| blur | 当选择器的输入框失去焦点时触发 | Function |
| focus | 当选择器的输入框获得焦点时触发 | Function |
| change | 仅当 modelValue 改变时,当输入框失去焦点或用户按Enter时触发 | Function |
| input | 在 Input 值改变时触发 | Function |
| clear | 在点击由 clearable 属性生成的清空按钮时触发 | Function |
| keydown | 按下键时触发 | Function |
| mouseleave | 当鼠标离开输入元素时触发 | Function |
| mouseenter | 当鼠标进入输入元素时触发 | Function |
| compositionstart | 输入法输入开始时触发 | Function |
| compositionupdate | 输入法输入改变时触发 | Function |
| compositionend | 输入法输入完成时触发 | Function |
Slots
| 插槽名 | 说明 |
|---|---|
| prefix | 输入框头部内容,只对非 type="textarea" 有效 |
| suffix | 输入框尾部内容,只对非 type="textarea" 有效 |
| prepend | 输入框前置内容,只对非 type="textarea" 有效 |
| append | 输入框后置内容,只对非 type="textarea" 有效 |
| password-icon 2.13.6 | 作为输入密码图标的内容,仅在 show-password 为 true 时生效。 作用域变量为 { visible: boolean } |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| blur | 使 input 失去焦点 | Function |
| clear | 清除 input 值 | Function |
| focus | 使 input 获取焦点 | Function |
| input | Input HTML 元素 | object |
| ref | HTML元素 input 或 textarea | object |
| resizeTextarea | 改变 textarea 大小 | Function |
| select | 选中 input 中的文字 | Function |
| textarea | HTML textarea 元素 | object |
| textareaStyle | textarea 的样式 | object |
| isComposing 2.8.0 | 是否是输入 composing 状态 | object |
| passwordVisible 2.13.7 | 密码是否可见 | object |
