Skip to content

Input 输入框

增强型输入框组件,支持文本输入、密码输入、前缀图标、后缀图标、清除按钮等功能。

基础用法

最简单的输入框用法。

html
<div class="sa-input" data-placeholder="请输入内容" data-autocomplete="off" style="width: 300px;"></div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

带图标的输入框

前缀图标

html
<div class="sa-input" 
     data-placeholder="请输入用户名" 
     data-prefix-icon="search"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

后缀图标

html
<div class="sa-input" 
     data-placeholder="请输入内容" 
     data-suffix-icon="close"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

清除按钮

通过 data-clearable="true" 启用清除按钮,点击可以清空输入内容。

html
<div class="sa-input" 
     data-placeholder="带清除按钮" 
     data-clearable="true"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

密码输入框

设置 data-type="password" 可以创建密码输入框,通过 data-show-password="true" 可以显示密码显示/隐藏切换按钮。

html
<div class="sa-input" 
     data-placeholder="请输入密码" 
     data-type="password"
     data-show-password="true"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

其他输入类型

Input 组件支持多种 HTML5 输入类型,包括 emailnumbertelurl 等。

邮箱输入框

html
<div class="sa-input" 
     data-placeholder="请输入邮箱地址" 
     data-type="email"
     data-clearable="true"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

数字输入框

html
<div class="sa-input" 
     data-placeholder="请输入数字" 
     data-type="number"
     data-clearable="true"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

URL 输入框

html
<div class="sa-input" 
     data-placeholder="请输入网址" 
     data-type="url"
     data-clearable="true"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

文本域

用于输入多行文本信息可缩放的输入框。添加 data-type="textarea" 属性来将 input 元素转换为原生的 textarea 元素。

基础文本域

html
<div class="sa-input" 
     data-type="textarea"
     data-placeholder="Please input"
     data-rows="4"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

文本域高度控制

文本域高度可通过 data-rows 属性控制。

html
<div class="sa-input" 
     data-type="textarea"
     data-placeholder="请输入内容"
     data-rows="6"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

自适应文本域

设置 data-autosize="true" 属性使得根据内容自动调整的高度。

html
<div class="sa-input" 
     data-type="textarea"
     data-placeholder="请输入内容"
     data-autosize="true"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

自适应文本域(限制范围)

你可以给 data-autosize 提供一个包含有最大和最小高度的对象,让输入框自动调整。

html
<div class="sa-input" 
     data-type="textarea"
     data-placeholder="请输入内容"
     data-autosize='{"minRows": 2, "maxRows": 6}'
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

禁用状态

通过 data-disabled="true" 禁用输入框。

html
<div class="sa-input" 
     data-placeholder="禁用状态" 
     data-disabled="true"
     data-value="已禁用"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

只读状态

通过 data-readonly="true" 设置输入框为只读状态,只读状态下用户无法编辑内容。

html
<div class="sa-input" 
     data-placeholder="只读状态" 
     data-readonly="true"
     data-value="只读内容,无法编辑"
     data-autocomplete="off"
     style="width: 300px;">
</div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

不同尺寸

通过 data-size 属性设置输入框大小。

html
<!-- 大尺寸 -->
<div class="sa-input" data-size="large" data-placeholder="大尺寸" data-autocomplete="off" style="width: 300px;"></div>

<!-- 默认尺寸 -->
<div class="sa-input" data-placeholder="默认尺寸" data-autocomplete="off" style="width: 300px;"></div>

<!-- 小尺寸 -->
<div class="sa-input" data-size="small" data-placeholder="小尺寸" data-autocomplete="off" style="width: 300px;"></div>

<script>
  SA.init('body');
</script>
加载 SanoUI 组件中...
            
          

统一自动初始化

使用 SA.init() 可以自动初始化容器内的所有支持自动初始化的组件(包括 input、form、button 等)。

html
<div style="display: flex; flex-direction: column; gap: 16px; max-width: 600px;">
  <div class="sa-input" 
       id="username-input"
       data-placeholder="用户名"
       data-value="admin"
       data-prefix-icon="search"
       data-clearable="true"
       data-autocomplete="off"
       style="width: 100%;"></div>
  <div class="sa-input" 
       id="password-input"
       data-placeholder="密码"
       data-value="123456"
       data-type="password"
       data-show-password="true"
       data-clearable="false"
       data-autocomplete="off"
       style="width: 100%;"></div>
  <div class="sa-input" 
       id="email-input"
       data-placeholder="邮箱"
       data-type="email"
       data-clearable="true"
       data-autocomplete="off"
       style="width: 100%;"></div>
</div>

<script>
// 使用 SA.init() 统一初始化所有组件
const page = SA.init('body');

// 按钮组件已自动初始化,所有带有 class="sa-input" 的元素都会被处理
// 图标按钮的图标也会自动添加

// 输入框组件通常不需要手动初始化,直接使用 HTML 类名即可
</script>
加载 SanoUI 组件中...
            
          

API

构造函数

javascript
new SaInput(container, config)

参数

参数说明类型默认值
container容器选择器或元素string | HTMLElement-
config配置选项SaInputOptions{}

配置选项

参数说明类型默认值
value输入框的值string''
placeholder占位符文本string''
type输入框类型'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'textarea''text'
rows文本域行数(当 type="textarea" 时)number2
autosize文本域自适应高度(当 type="textarea" 时),可以是布尔值或对象 { minRows, maxRows }boolean | Objectfalse
clearable是否显示清除按钮booleantrue
showPassword是否显示密码切换按钮(仅 type="password" 时有效)booleanfalse
prefixIcon前缀图标名称string | nullnull
suffixIcon后缀图标名称string | nullnull
disabled是否禁用booleanfalse
readonly是否只读booleanfalse
autocomplete浏览器自动填充控制string-
size输入框尺寸'large' | 'default' | 'small''default'
onInput输入事件回调function(value: string)null
onEnter回车键事件回调function(value: string)null
onClear清除事件回调function()null
onChange值变化事件回调function(value: string)null

Data 属性

Input 组件支持通过 data-* 属性进行配置:

属性说明类型默认值示例
data-value输入框的值string''data-value="初始值"
data-placeholder占位符文本string''data-placeholder="请输入"
data-type输入框类型,支持 'textarea'string'text'data-type="password"
data-type="textarea"
data-rows文本域行数(当 type="textarea" 时)string'2'data-rows="4"
data-autosize文本域自适应高度,可以是 'true' 或 JSON 对象字符串string'false'data-autosize="true"
data-autosize='{"minRows": 2, "maxRows": 6}'
data-clearable是否显示清除按钮booleantruedata-clearable="true"
data-show-password是否显示密码切换按钮booleanfalsedata-show-password="true"
data-prefix-icon前缀图标名称string-data-prefix-icon="search"
data-suffix-icon后缀图标名称string-data-suffix-icon="close"
data-disabled是否禁用booleanfalsedata-disabled="true"
data-readonly是否只读booleanfalsedata-readonly="true"
data-autocomplete浏览器自动填充控制string-data-autocomplete="off"
data-autocomplete="new-password"
data-size输入框尺寸string'default'data-size="large"

方法

方法名说明参数返回值
getValue()获取输入框的值-string
setValue(value)设置输入框的值value: stringSaInput
setDisabled(disabled)设置禁用状态disabled: booleanSaInput
setReadonly(readonly)设置只读状态readonly: booleanSaInput
focus()聚焦输入框-void
blur()失焦输入框-void
togglePasswordVisibility()切换密码显示/隐藏(仅 type="password" 时有效)-void
destroy()销毁实例-void

事件回调

事件名说明回调参数
onInput输入时触发value: string - 当前输入值
onEnter按下回车键时触发value: string - 当前输入值
onClear点击清除按钮时触发-
onChange值变化时触发(失焦时)value: string - 当前输入值

实际使用场景

场景 1:登录表单

完整的登录表单,包含用户名和密码输入框,带验证和提交功能。

html
<form id="login-form" style="max-width: 400px;">
  <div style="margin-bottom: 1rem;">
    <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">用户名</label>
    <div 
      class="sa-input" 
      id="username-input"
      data-placeholder="请输入用户名" 
      data-prefix-icon="search"
      data-clearable="true"
      data-autocomplete="off"
      style="width: 100%;"
    ></div>
  </div>
  
  <div style="margin-bottom: 1rem;">
    <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">密码</label>
    <div 
      class="sa-input" 
      id="password-input"
      data-placeholder="请输入密码" 
      data-type="password"
      data-show-password="true"
      data-clearable="false"
      data-autocomplete="off"
      style="width: 100%;"
    ></div>
  </div>
  
  <button type="submit" class="sa-button sa-button--primary" style="width: 100%;">
    登录
  </button>
</form>

<script>
  SA.init('body');
  
  const form = document.getElementById('login-form');
  const usernameInput = document.getElementById('username-input');
  const passwordInput = document.getElementById('password-input');
  
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    
    const username = usernameInput._saInputInstance?.getValue() || '';
    const password = passwordInput._saInputInstance?.getValue() || '';
    
    // 简单验证
    if (!username) {
      alert('请输入用户名');
      usernameInput._saInputInstance?.focus();
      return;
    }
    
    if (!password) {
      alert('请输入密码');
      passwordInput._saInputInstance?.focus();
      return;
    }
    
    // 模拟登录
    console.log('登录信息:', { username, password });
    alert('登录成功!');
  });
</script>
加载 SanoUI 组件中...
            
          

场景 2:实时搜索

带搜索功能的输入框,支持实时搜索和清除功能。

html
<div style="max-width: 500px;">
  <div 
    class="sa-input" 
    id="search-input"
    data-placeholder="搜索用户、文章、标签..." 
    data-prefix-icon="search"
    data-clearable="true"
    data-autocomplete="off"
    style="width: 100%;"
  ></div>
  
  <div id="search-results" style="margin-top: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 4px; min-height: 100px;">
    <p style="color: #999; margin: 0;">输入关键词开始搜索...</p>
  </div>
</div>

<script>
  SA.init('body');
  
  const searchInput = document.getElementById('search-input');
  const searchResults = document.getElementById('search-results');
  let searchTimer = null;
  
  // 模拟搜索结果
  const mockResults = [
    '用户:张三',
    '用户:李四',
    '文章:如何使用 SanoUI',
    '文章:组件库最佳实践',
    '标签:前端开发',
    '标签:UI 设计'
  ];
  
  // 监听输入事件
  if (searchInput._saInputInstance) {
    searchInput._saInputInstance.config.onInput = (value) => {
      // 防抖处理
      clearTimeout(searchTimer);
      
      if (!value) {
        searchResults.innerHTML = '<p style="color: #999; margin: 0;">输入关键词开始搜索...</p>';
        return;
      }
      
      searchTimer = setTimeout(() => {
        // 模拟搜索
        const results = mockResults.filter(item => 
          item.toLowerCase().includes(value.toLowerCase())
        );
        
        if (results.length > 0) {
          searchResults.innerHTML = results.map(item => 
            `<div style="padding: 0.5rem; border-bottom: 1px solid #eee;">${item}</div>`
          ).join('');
        } else {
          searchResults.innerHTML = '<p style="color: #999; margin: 0;">未找到相关结果</p>';
        }
      }, 300);
    };
    
    // 清除时重置结果
    searchInput._saInputInstance.config.onClear = () => {
      searchResults.innerHTML = '<p style="color: #999; margin: 0;">输入关键词开始搜索...</p>';
    };
  }
</script>
加载 SanoUI 组件中...
            
          

场景 3:表单验证

带实时验证的输入框,显示验证错误信息。

html
<div style="max-width: 400px;">
  <div style="margin-bottom: 1.5rem;">
    <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">邮箱地址</label>
    <div 
      class="sa-input" 
      id="email-input"
      data-placeholder="请输入邮箱地址" 
      data-type="email"
      data-clearable="true"
      data-autocomplete="off"
      style="width: 100%;"
    ></div>
    <div id="email-error" style="color: #f56c6c; font-size: 0.875rem; margin-top: 0.25rem; display: none;"></div>
  </div>
  
  <div style="margin-bottom: 1.5rem;">
    <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">手机号码</label>
    <div 
      class="sa-input" 
      id="phone-input"
      data-placeholder="请输入手机号码" 
      data-type="tel"
      data-clearable="true"
      data-autocomplete="off"
      style="width: 100%;"
    ></div>
    <div id="phone-error" style="color: #f56c6c; font-size: 0.875rem; margin-top: 0.25rem; display: none;"></div>
  </div>
  
  <button class="sa-button sa-button--primary" onclick="validateForm()">
    提交
  </button>
</div>

<script>
  SA.init('body');
  
  const emailInput = document.getElementById('email-input');
  const phoneInput = document.getElementById('phone-input');
  const emailError = document.getElementById('email-error');
  const phoneError = document.getElementById('phone-error');
  
  // 邮箱验证
  function validateEmail(email) {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return re.test(email);
  }
  
  // 手机号验证
  function validatePhone(phone) {
    const re = /^1[3-9]\d{9}$/;
    return re.test(phone);
  }
  
  // 邮箱输入验证
  if (emailInput._saInputInstance) {
    emailInput._saInputInstance.config.onChange = (value) => {
      if (value && !validateEmail(value)) {
        emailError.textContent = '请输入有效的邮箱地址';
        emailError.style.display = 'block';
      } else {
        emailError.style.display = 'none';
      }
    };
  }
  
  // 手机号输入验证
  if (phoneInput._saInputInstance) {
    phoneInput._saInputInstance.config.onChange = (value) => {
      if (value && !validatePhone(value)) {
        phoneError.textContent = '请输入有效的手机号码';
        phoneError.style.display = 'block';
      } else {
        phoneError.style.display = 'none';
      }
    };
  }
  
  function validateForm() {
    const email = emailInput._saInputInstance?.getValue() || '';
    const phone = phoneInput._saInputInstance?.getValue() || '';
    
    let isValid = true;
    
    if (!email) {
      emailError.textContent = '请输入邮箱地址';
      emailError.style.display = 'block';
      isValid = false;
    } else if (!validateEmail(email)) {
      emailError.textContent = '请输入有效的邮箱地址';
      emailError.style.display = 'block';
      isValid = false;
    } else {
      emailError.style.display = 'none';
    }
    
    if (!phone) {
      phoneError.textContent = '请输入手机号码';
      phoneError.style.display = 'block';
      isValid = false;
    } else if (!validatePhone(phone)) {
      phoneError.textContent = '请输入有效的手机号码';
      phoneError.style.display = 'block';
      isValid = false;
    } else {
      phoneError.style.display = 'none';
    }
    
    if (isValid) {
      alert('验证通过!');
    }
  }
</script>
加载 SanoUI 组件中...
            
          

场景 4:密码强度检测

密码输入框带实时强度检测功能。

html
<div style="max-width: 400px;">
  <div style="margin-bottom: 0.5rem;">
    <label style="display: block; margin-bottom: 0.5rem; font-weight: 500;">设置密码</label>
    <div 
      class="sa-input" 
      id="password-strength-input"
      data-placeholder="请输入密码" 
      data-type="password"
      data-show-password="true"
      data-clearable="true"
      data-autocomplete="off"
      style="width: 100%;"
    ></div>
  </div>
  
  <div id="password-strength" style="margin-bottom: 1rem;">
    <div style="display: flex; gap: 4px; margin-bottom: 0.5rem;">
      <div id="strength-bar-1" style="flex: 1; height: 4px; background: #ddd; border-radius: 2px;"></div>
      <div id="strength-bar-2" style="flex: 1; height: 4px; background: #ddd; border-radius: 2px;"></div>
      <div id="strength-bar-3" style="flex: 1; height: 4px; background: #ddd; border-radius: 2px;"></div>
    </div>
    <div id="strength-text" style="font-size: 0.875rem; color: #999;">请输入密码</div>
  </div>
</div>

<script>
  SA.init('body');
  
  const passwordInput = document.getElementById('password-strength-input');
  const strengthText = document.getElementById('strength-text');
  const bars = [
    document.getElementById('strength-bar-1'),
    document.getElementById('strength-bar-2'),
    document.getElementById('strength-bar-3')
  ];
  
  function checkPasswordStrength(password) {
    let strength = 0;
    let text = '';
    let color = '#999';
    
    if (password.length === 0) {
      return { strength: 0, text: '请输入密码', color: '#999' };
    }
    
    if (password.length >= 6) strength++;
    if (password.length >= 10) strength++;
    if (/[a-z]/.test(password) && /[A-Z]/.test(password)) strength++;
    if (/\d/.test(password)) strength++;
    if (/[^a-zA-Z\d]/.test(password)) strength++;
    
    if (strength <= 2) {
      text = '弱';
      color = '#f56c6c';
    } else if (strength <= 3) {
      text = '中';
      color = '#e6a23c';
    } else {
      text = '强';
      color = '#67c23a';
    }
    
    return { strength: Math.min(strength, 3), text, color };
  }
  
  if (passwordInput._saInputInstance) {
    passwordInput._saInputInstance.config.onInput = (value) => {
      const result = checkPasswordStrength(value);
      
      // 更新强度条
      bars.forEach((bar, index) => {
        if (index < result.strength) {
          bar.style.background = result.color;
        } else {
          bar.style.background = '#ddd';
        }
      });
      
      // 更新文本
      strengthText.textContent = `密码强度:${result.text}`;
      strengthText.style.color = result.color;
    };
  }
</script>
加载 SanoUI 组件中...
            
          

场景 5:动态禁用/启用

根据条件动态控制输入框的禁用状态。

html
<div style="max-width: 400px;">
  <div style="margin-bottom: 1rem;">
    <label>
      <input type="checkbox" id="enable-input" checked onchange="toggleInput()">
      启用输入框
    </label>
  </div>
  
  <div 
    class="sa-input" 
    id="dynamic-input"
    data-placeholder="此输入框可动态启用/禁用" 
    data-clearable="true"
    data-autocomplete="off"
    style="width: 100%;"
  ></div>
</div>

<script>
  SA.init('body');
  
  const enableCheckbox = document.getElementById('enable-input');
  const dynamicInput = document.getElementById('dynamic-input');
  
  function toggleInput() {
    if (dynamicInput._saInputInstance) {
      dynamicInput._saInputInstance.setDisabled(!enableCheckbox.checked);
    }
  }
  
  // 初始化状态
  toggleInput();
</script>
加载 SanoUI 组件中...
            
          

注意事项

  1. 自动初始化:使用 SA.init() 会自动初始化所有带 class="sa-input" 的输入框
  2. 实例访问:初始化后可以通过 element._saInputInstance 访问组件实例
  3. 密码类型:当 type="password" 时,默认启用 showPassword 功能
  4. 浏览器自动填充:通过 data-autocomplete 属性可以控制浏览器的自动填充行为
    • data-autocomplete="off" - 禁用自动填充(适用于用户名等敏感信息)
    • data-autocomplete="new-password" - 告诉浏览器这是新密码,不要自动填充(适用于注册/修改密码场景)
    • data-autocomplete="username" - 允许自动填充用户名
    • 其他标准 autocomplete 值也支持,如 emailtel
  5. 清除按钮:清除按钮只在有输入值且 clearable="true" 时显示
  6. 事件触发onChange 在失焦时触发,onInput 在输入时实时触发
  7. 方法返回值setValue()setDisabled()setReadonly() 等方法返回 this,支持链式调用

常见问题

Q: 如何获取输入框的值?

A: 通过组件实例的 getValue() 方法:

javascript
const value = inputElement._saInputInstance.getValue();

Q: 如何动态设置输入框的值?

A: 使用 setValue() 方法:

javascript
inputElement._saInputInstance.setValue('新值');

Q: 如何监听输入事件?

A: 在配置中设置 onInput 回调,或通过实例配置:

javascript
inputElement._saInputInstance.config.onInput = (value) => {
  console.log('输入值:', value);
};

Q: 如何实现输入框的联动?

A: 通过事件回调实现:

javascript
// 输入框 A 变化时,更新输入框 B
inputA._saInputInstance.config.onChange = (value) => {
  inputB._saInputInstance.setValue(value.toUpperCase());
};

Released under the MIT License.