You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI Autocomplete定制:按label搜索、渲染并绑定phone值

解决MUI Autocomplete定制搜索、显示与提交值的问题

需求明确:

  • 基于country.label进行搜索匹配
  • 选中后输入框显示country.phone
  • 最终提交到表单的值为country.phone

原代码的核心问题是将options处理成了纯label字符串数组,导致后续无法直接关联到完整的country对象。下面是修改后的完整实现,关键调整点已标注:

export const countries = [
  { code: '', label: '', phone: '' },
  { code: 'AD', label: 'Andorra', phone: '376' },
  {
    code: 'AE',
    label: 'United Arab Emirates',
    phone: '971',
  },
  { code: 'AF', label: 'Afghanistan', phone: '93' }
]

<Controller
  name="userDTO.phoneCode"
  control={control}
  render={({ field, fieldState: { error } }) => (
    <Autocomplete
      {...field}
      // 1. 直接传入完整的countries数组,每个option是country对象
      options={countries}
      // 2. 指定搜索匹配的依据是country.label
      getOptionLabel={(option) => option.label}
      // 3. 选中后提交country.phone作为值
      onChange={(event, newValue) => {
        setValue("userDTO.phoneCode", newValue?.phone || '', { shouldValidate: true })
      }}
      // 4. 设置输入框显示的内容为选中country的phone
      renderInput={(params) => {
        // 根据当前提交的phone值找到对应的country
        const selectedCountry = countries.find(country => country.phone === field.value);
        const { code } = selectedCountry || { code: "", label: "", phone: "" };
        
        return ( 
          <TextField
            {...params}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                <InputAdornment position="start">
                  <Iconify
                    key={code}
                    icon={`circle-flags:${code.toLowerCase()}`}
                    width={28}
                    sx={{mr: 1}}
                  />
                </InputAdornment>)
            }}
            label="Phone Code"
            // 覆盖输入框的显示值为选中的phone
            value={field.value || ''}
          />
        );
      }}
      renderOption={(props, option) => {
        if (!option.label) {
          return null;
        }

        return (
          <li {...props} key={option.label}>
            <Iconify
              key={option.label}
              icon={`circle-flags:${option.code.toLowerCase()}`}
              width={28}
              sx={{mr: 1}}
            />
            {option.label} ({option.code}) +{option.phone}
          </li>
        );
      }}
      // 设置默认值匹配逻辑,根据提交的phone找到对应的country对象
      defaultValue={countries.find(country => country.phone === field.value) || countries[0]}
    />
  )}
/>

关键修改说明:

  • options传递:不再映射成label数组,直接使用完整的country对象数组,让Autocomplete能直接访问每个选项的所有属性。
  • 搜索逻辑:通过getOptionLabel指定用option.label作为搜索匹配的字段,满足按label搜索的需求。
  • 提交值设置:onChange中提取选中country的phone属性作为表单提交值。
  • 输入框显示:在renderInput里根据当前表单的field.value(即phone)找到对应的country,输入框直接显示phone值,同时保留国旗图标。
  • 选项渲染优化:renderOption直接从option参数获取所有属性,无需再遍历数组查找,提升效率。

内容的提问来源于stack exchange,提问作者user3379331

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:05:21