Ionic表单组件 #

一、输入框组件(Input) #

1.1 基本用法 #

html
<!-- 基本输入框 -->
<ion-input placeholder="请输入内容"></ion-input>

<!-- 带标签 -->
<ion-item>
  <ion-label position="floating">用户名</ion-label>
  <ion-input></ion-input>
</ion-item>

1.2 输入类型 #

html
<!-- 文本输入 -->
<ion-item>
  <ion-label position="floating">文本</ion-label>
  <ion-input type="text"></ion-input>
</ion-item>

<!-- 数字输入 -->
<ion-item>
  <ion-label position="floating">数字</ion-label>
  <ion-input type="number"></ion-input>
</ion-item>

<!-- 邮箱输入 -->
<ion-item>
  <ion-label position="floating">邮箱</ion-label>
  <ion-input type="email"></ion-input>
</ion-item>

<!-- 密码输入 -->
<ion-item>
  <ion-label position="floating">密码</ion-label>
  <ion-input type="password"></ion-input>
</ion-item>

<!-- 电话输入 -->
<ion-item>
  <ion-label position="floating">电话</ion-label>
  <ion-input type="tel"></ion-input>
</ion-item>

<!-- URL输入 -->
<ion-item>
  <ion-label position="floating">网址</ion-label>
  <ion-input type="url"></ion-input>
</ion-item>

1.3 标签位置 #

html
<!-- 浮动标签 -->
<ion-item>
  <ion-label position="floating">浮动标签</ion-label>
  <ion-input></ion-input>
</ion-item>

<!-- 固定标签 -->
<ion-item>
  <ion-label position="fixed">固定标签</ion-label>
  <ion-input></ion-input>
</ion-item>

<!-- 堆叠标签 -->
<ion-item>
  <ion-label position="stacked">堆叠标签</ion-label>
  <ion-input></ion-input>
</ion-item>

1.4 输入框图标 #

html
<!-- 带图标 -->
<ion-item>
  <ion-icon name="mail" slot="start"></ion-icon>
  <ion-label position="floating">邮箱</ion-label>
  <ion-input type="email"></ion-input>
</ion-item>

<!-- 带清除按钮 -->
<ion-item>
  <ion-label position="floating">搜索</ion-label>
  <ion-input clearInput></ion-input>
  <ion-icon name="search" slot="end"></ion-icon>
</ion-item>

1.5 输入验证 #

html
<!-- 必填字段 -->
<ion-item>
  <ion-label position="floating">用户名 *</ion-label>
  <ion-input required></ion-input>
</ion-item>

<!-- 最小/最大长度 -->
<ion-item>
  <ion-label position="floating">密码</ion-label>
  <ion-input type="password" minlength="6" maxlength="20"></ion-input>
</ion-item>

<!-- 正则验证 -->
<ion-item>
  <ion-label position="floating">手机号</ion-label>
  <ion-input type="tel" pattern="[0-9]{11}"></ion-input>
</ion-item>

1.6 Angular表单绑定 #

typescript
// 组件
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-login',
  templateUrl: 'login.page.html'
})
export class LoginPage {
  loginForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.loginForm = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(6)]]
    });
  }

  onSubmit() {
    if (this.loginForm.valid) {
      console.log(this.loginForm.value);
    }
  }
}
html
<!-- 模板 -->
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
  <ion-item>
    <ion-label position="floating">邮箱</ion-label>
    <ion-input formControlName="email" type="email"></ion-input>
  </ion-item>
  <ion-text color="danger" *ngIf="loginForm.get('email')?.errors?.['required']">
    邮箱是必填项
  </ion-text>
  <ion-text color="danger" *ngIf="loginForm.get('email')?.errors?.['email']">
    请输入有效的邮箱地址
  </ion-text>

  <ion-item>
    <ion-label position="floating">密码</ion-label>
    <ion-input formControlName="password" type="password"></ion-input>
  </ion-item>
  <ion-text color="danger" *ngIf="loginForm.get('password')?.errors?.['minlength']">
    密码至少6位
  </ion-text>

  <ion-button expand="block" type="submit" [disabled]="loginForm.invalid">
    登录
  </ion-button>
</form>

二、文本域组件(Textarea) #

2.1 基本用法 #

html
<!-- 基本文本域 -->
<ion-textarea placeholder="请输入内容"></ion-textarea>

<!-- 带标签 -->
<ion-item>
  <ion-label position="floating">描述</ion-label>
  <ion-textarea></ion-textarea>
</ion-item>

2.2 行数控制 #

html
<!-- 固定行数 -->
<ion-textarea rows="4"></ion-textarea>

<!-- 自动增长 -->
<ion-textarea autoGrow></ion-textarea>

<!-- 最大行数 -->
<ion-textarea autoGrow [maxlength]="500"></ion-textarea>

2.3 文本域样式 #

scss
ion-textarea {
  --background: #f5f5f5;
  --padding-start: 12px;
  --padding-end: 12px;
  --padding-top: 8px;
  --padding-bottom: 8px;
  border-radius: 8px;
}

三、选择器组件(Select) #

3.1 基本用法 #

html
<!-- 基本选择器 -->
<ion-item>
  <ion-label>城市</ion-label>
  <ion-select>
    <ion-select-option value="beijing">北京</ion-select-option>
    <ion-select-option value="shanghai">上海</ion-select-option>
    <ion-select-option value="guangzhou">广州</ion-select-option>
    <ion-select-option value="shenzhen">深圳</ion-select-option>
  </ion-select>
</ion-item>

3.2 多选 #

html
<!-- 多选 -->
<ion-item>
  <ion-label>爱好</ion-label>
  <ion-select multiple="true">
    <ion-select-option value="reading">阅读</ion-select-option>
    <ion-select-option value="music">音乐</ion-select-option>
    <ion-select-option value="sports">运动</ion-select-option>
    <ion-select-option value="travel">旅行</ion-select-option>
  </ion-select>
</ion-item>

3.3 选择器接口 #

html
<!-- Action Sheet -->
<ion-item>
  <ion-label>城市</ion-label>
  <ion-select interface="action-sheet">
    <ion-select-option value="beijing">北京</ion-select-option>
    <ion-select-option value="shanghai">上海</ion-select-option>
  </ion-select>
</ion-item>

<!-- Alert -->
<ion-item>
  <ion-label>城市</ion-label>
  <ion-select interface="alert">
    <ion-select-option value="beijing">北京</ion-select-option>
    <ion-select-option value="shanghai">上海</ion-select-option>
  </ion-select>
</ion-item>

<!-- Popover -->
<ion-item>
  <ion-label>城市</ion-label>
  <ion-select interface="popover">
    <ion-select-option value="beijing">北京</ion-select-option>
    <ion-select-option value="shanghai">上海</ion-select-option>
  </ion-select>
</ion-item>

3.4 表单绑定 #

typescript
// 组件
export class MyPage {
  selectedCity = 'beijing';
  selectedHobbies: string[] = [];
  
  cities = [
    { value: 'beijing', label: '北京' },
    { value: 'shanghai', label: '上海' },
    { value: 'guangzhou', label: '广州' }
  ];
}
html
<!-- 模板 -->
<ion-item>
  <ion-label>城市</ion-label>
  <ion-select [(ngModel)]="selectedCity">
    <ion-select-option 
      *ngFor="let city of cities" 
      [value]="city.value">
      {{ city.label }}
    </ion-select-option>
  </ion-select>
</ion-item>

四、复选框组件(Checkbox) #

4.1 基本用法 #

html
<!-- 基本复选框 -->
<ion-item>
  <ion-label>同意条款</ion-label>
  <ion-checkbox></ion-checkbox>
</ion-item>

<!-- 带颜色 -->
<ion-item>
  <ion-label>记住我</ion-label>
  <ion-checkbox color="primary"></ion-checkbox>
</ion-item>

4.2 复选框状态 #

html
<!-- 选中状态 -->
<ion-item>
  <ion-label>已选中</ion-label>
  <ion-checkbox checked="true"></ion-checkbox>
</ion-item>

<!-- 禁用状态 -->
<ion-item>
  <ion-label>禁用</ion-label>
  <ion-checkbox disabled="true"></ion-checkbox>
</ion-item>

4.3 表单绑定 #

typescript
// 组件
export class MyPage {
  agree = false;
  hobbies = [
    { id: 1, name: '阅读', checked: false },
    { id: 2, name: '音乐', checked: true },
    { id: 3, name: '运动', checked: false }
  ];
  
  onHobbyChange(hobby: any) {
    console.log('选中:', hobby);
  }
}
html
<!-- 模板 -->
<ion-item>
  <ion-label>同意条款</ion-label>
  <ion-checkbox [(ngModel)]="agree"></ion-checkbox>
</ion-item>

<ion-list>
  <ion-item *ngFor="let hobby of hobbies">
    <ion-label>{{ hobby.name }}</ion-label>
    <ion-checkbox 
      [(ngModel)]="hobby.checked"
      (ionChange)="onHobbyChange(hobby)">
    </ion-checkbox>
  </ion-item>
</ion-list>

4.4 复选框样式 #

scss
ion-checkbox {
  --background: #e0e0e0;
  --background-checked: #3880ff;
  --border-color: #999999;
  --border-color-checked: #3880ff;
  --checkmark-color: #ffffff;
  --size: 24px;
}

五、单选按钮组件(Radio) #

5.1 基本用法 #

html
<!-- 单选按钮组 -->
<ion-radio-group>
  <ion-item>
    <ion-label>选项一</ion-label>
    <ion-radio value="option1"></ion-radio>
  </ion-item>
  <ion-item>
    <ion-label>选项二</ion-label>
    <ion-radio value="option2"></ion-radio>
  </ion-item>
  <ion-item>
    <ion-label>选项三</ion-label>
    <ion-radio value="option3"></ion-radio>
  </ion-item>
</ion-radio-group>

5.2 单选按钮样式 #

html
<!-- 标签位置 -->
<ion-radio-group>
  <ion-item>
    <ion-radio slot="start" value="option1"></ion-radio>
    <ion-label>选项一</ion-label>
  </ion-item>
</ion-radio-group>

<!-- 不同颜色 -->
<ion-radio-group>
  <ion-item>
    <ion-label>Primary</ion-label>
    <ion-radio color="primary" value="primary"></ion-radio>
  </ion-item>
  <ion-item>
    <ion-label>Danger</ion-label>
    <ion-radio color="danger" value="danger"></ion-radio>
  </ion-item>
</ion-radio-group>

5.3 表单绑定 #

typescript
// 组件
export class MyPage {
  selectedGender = 'male';
  selectedPayment = 'alipay';
  
  paymentMethods = [
    { value: 'alipay', label: '支付宝' },
    { value: 'wechat', label: '微信支付' },
    { value: 'card', label: '银行卡' }
  ];
}
html
<!-- 模板 -->
<ion-radio-group [(ngModel)]="selectedGender">
  <ion-list-header>
    <ion-label>性别</ion-label>
  </ion-list-header>
  <ion-item>
    <ion-label>男</ion-label>
    <ion-radio value="male"></ion-radio>
  </ion-item>
  <ion-item>
    <ion-label>女</ion-label>
    <ion-radio value="female"></ion-radio>
  </ion-item>
</ion-radio-group>

5.4 单选按钮样式 #

scss
ion-radio {
  --color: #999999;
  --color-checked: #3880ff;
  --border-width: 2px;
  --inner-border-width: 2px;
}

六、开关组件(Toggle) #

6.1 基本用法 #

html
<!-- 基本开关 -->
<ion-item>
  <ion-label>通知</ion-label>
  <ion-toggle></ion-toggle>
</ion-item>

<!-- 带颜色 -->
<ion-item>
  <ion-label>深色模式</ion-label>
  <ion-toggle color="primary"></ion-toggle>
</ion-item>

6.2 开关状态 #

html
<!-- 选中状态 -->
<ion-item>
  <ion-label>已开启</ion-label>
  <ion-toggle checked="true"></ion-toggle>
</ion-item>

<!-- 禁用状态 -->
<ion-item>
  <ion-label>禁用</ion-label>
  <ion-toggle disabled="true"></ion-toggle>
</ion-item>

6.3 表单绑定 #

typescript
// 组件
export class SettingsPage {
  settings = {
    notifications: true,
    darkMode: false,
    autoUpdate: true
  };
  
  onToggleChange(setting: string, value: boolean) {
    console.log(`${setting}: ${value}`);
  }
}
html
<!-- 模板 -->
<ion-list>
  <ion-item>
    <ion-label>通知</ion-label>
    <ion-toggle 
      [(ngModel)]="settings.notifications"
      (ionChange)="onToggleChange('notifications', $event.detail.checked)">
    </ion-toggle>
  </ion-item>
  <ion-item>
    <ion-label>深色模式</ion-label>
    <ion-toggle [(ngModel)]="settings.darkMode"></ion-toggle>
  </ion-item>
  <ion-item>
    <ion-label>自动更新</ion-label>
    <ion-toggle [(ngModel)]="settings.autoUpdate"></ion-toggle>
  </ion-item>
</ion-list>

6.4 开关样式 #

scss
ion-toggle {
  --background: #e0e0e0;
  --background-checked: #3880ff;
  --handle-background: #ffffff;
  --handle-background-checked: #ffffff;
}

七、范围滑块组件(Range) #

7.1 基本用法 #

html
<!-- 基本滑块 -->
<ion-item>
  <ion-label>音量</ion-label>
  <ion-range></ion-range>
</ion-item>

<!-- 带范围 -->
<ion-item>
  <ion-label>亮度</ion-label>
  <ion-range min="0" max="100" value="50"></ion-range>
</ion-item>

7.2 滑块标签 #

html
<!-- 带刻度标签 -->
<ion-item>
  <ion-label>价格范围</ion-label>
  <ion-range min="0" max="1000" step="100" snaps="true">
    <ion-label slot="start">0</ion-label>
    <ion-label slot="end">1000</ion-label>
  </ion-range>
</ion-item>

<!-- 双滑块 -->
<ion-item>
  <ion-label>价格区间</ion-label>
  <ion-range dualKnobs="true" min="0" max="1000">
    <ion-label slot="start">0</ion-label>
    <ion-label slot="end">1000</ion-label>
  </ion-range>
</ion-item>

7.3 表单绑定 #

typescript
// 组件
export class MyPage {
  volume = 50;
  brightness = 80;
  priceRange = { lower: 100, upper: 500 };
  
  onVolumeChange(value: number) {
    console.log('音量:', value);
  }
}
html
<!-- 模板 -->
<ion-item>
  <ion-label>音量: {{ volume }}</ion-label>
  <ion-range 
    min="0" 
    max="100" 
    [(ngModel)]="volume"
    (ionChange)="onVolumeChange($event.detail.value)">
  </ion-range>
</ion-item>

7.4 滑块样式 #

scss
ion-range {
  --bar-background: #e0e0e0;
  --bar-background-active: #3880ff;
  --bar-height: 4px;
  --knob-background: #3880ff;
  --knob-size: 28px;
  --pin-background: #3880ff;
  --pin-color: #ffffff;
}

八、日期时间组件(Datetime) #

8.1 基本用法 #

html
<!-- 基本日期选择 -->
<ion-datetime></ion-datetime>

<!-- 带标签 -->
<ion-item>
  <ion-label>日期</ion-label>
  <ion-datetime displayFormat="YYYY-MM-DD"></ion-datetime>
</ion-item>

8.2 格式设置 #

html
<!-- 日期格式 -->
<ion-datetime displayFormat="YYYY-MM-DD"></ion-datetime>

<!-- 日期时间格式 -->
<ion-datetime displayFormat="YYYY-MM-DD HH:mm"></ion-datetime>

<!-- 时间格式 -->
<ion-datetime displayFormat="HH:mm"></ion-datetime>

8.3 日期限制 #

html
<!-- 最小/最大日期 -->
<ion-datetime 
  min="2024-01-01" 
  max="2024-12-31">
</ion-datetime>

<!-- 禁用特定日期 -->
<ion-datetime [dayValues]="[1, 15, 30]"></ion-datetime>

8.4 表单绑定 #

typescript
// 组件
export class MyPage {
  selectedDate = '2024-01-15';
  
  onDateChange(event: any) {
    console.log('选择日期:', event.detail.value);
  }
}
html
<!-- 模板 -->
<ion-item>
  <ion-label>选择日期</ion-label>
  <ion-datetime 
    displayFormat="YYYY年MM月DD日"
    [(ngModel)]="selectedDate"
    (ionChange)="onDateChange($event)">
  </ion-datetime>
</ion-item>

九、完整表单示例 #

9.1 注册表单 #

typescript
// 组件
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-register',
  templateUrl: 'register.page.html'
})
export class RegisterPage {
  registerForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.registerForm = this.fb.group({
      username: ['', [Validators.required, Validators.minLength(3)]],
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(6)]],
      confirmPassword: ['', Validators.required],
      gender: ['male', Validators.required],
      birthday: [''],
      city: [''],
      hobbies: [[]],
      agree: [false, Validators.requiredTrue]
    }, { validators: this.passwordMatchValidator });
  }

  passwordMatchValidator(form: FormGroup) {
    const password = form.get('password')?.value;
    const confirmPassword = form.get('confirmPassword')?.value;
    return password === confirmPassword ? null : { mismatch: true };
  }

  onSubmit() {
    if (this.registerForm.valid) {
      console.log('注册信息:', this.registerForm.value);
    }
  }
}
html
<!-- 模板 -->
<ion-content>
  <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
    <ion-list>
      <ion-item>
        <ion-label position="floating">用户名 *</ion-label>
        <ion-input formControlName="username"></ion-input>
      </ion-item>
      
      <ion-item>
        <ion-label position="floating">邮箱 *</ion-label>
        <ion-input formControlName="email" type="email"></ion-input>
      </ion-item>
      
      <ion-item>
        <ion-label position="floating">密码 *</ion-label>
        <ion-input formControlName="password" type="password"></ion-input>
      </ion-item>
      
      <ion-item>
        <ion-label position="floating">确认密码 *</ion-label>
        <ion-input formControlName="confirmPassword" type="password"></ion-input>
      </ion-item>
      
      <ion-radio-group formControlName="gender">
        <ion-list-header>
          <ion-label>性别</ion-label>
        </ion-list-header>
        <ion-item>
          <ion-label>男</ion-label>
          <ion-radio value="male"></ion-radio>
        </ion-item>
        <ion-item>
          <ion-label>女</ion-label>
          <ion-radio value="female"></ion-radio>
        </ion-item>
      </ion-radio-group>
      
      <ion-item>
        <ion-label>生日</ion-label>
        <ion-datetime formControlName="birthday" displayFormat="YYYY-MM-DD"></ion-datetime>
      </ion-item>
      
      <ion-item>
        <ion-label>城市</ion-label>
        <ion-select formControlName="city">
          <ion-select-option value="beijing">北京</ion-select-option>
          <ion-select-option value="shanghai">上海</ion-select-option>
          <ion-select-option value="guangzhou">广州</ion-select-option>
        </ion-select>
      </ion-item>
      
      <ion-item>
        <ion-label>同意条款 *</ion-label>
        <ion-checkbox formControlName="agree"></ion-checkbox>
      </ion-item>
    </ion-list>
    
    <ion-button 
      expand="block" 
      type="submit" 
      [disabled]="registerForm.invalid">
      注册
    </ion-button>
  </form>
</ion-content>

十、总结 #

10.1 组件对比 #

组件 用途 特点
Input 文本输入 多种类型、验证支持
Textarea 多行文本 自动增长、字符限制
Select 下拉选择 单选/多选、多种接口
Checkbox 多选框 多选场景
Radio 单选框 单选场景
Toggle 开关 布尔值切换
Range 范围选择 数值范围
Datetime 日期时间 日期时间选择

10.2 下一步 #

掌握了表单组件后,接下来让我们学习 导航组件,了解Ionic的导航系统!

最后更新:2026-03-28