news 2026/9/20 12:39:04

Quasar 框架 QInput 组件完全指南:从基础用法到 Mask 掩码与表单验证的实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Quasar 框架 QInput 组件完全指南:从基础用法到 Mask 掩码与表单验证的实战解析
  • 前端
  • UI组件
  • 跨平台

【免费下载链接】quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time

项目地址:https://gitcode.com/gh_mirrors/qu/quasar
点击查看免费下载

导读

本文基于 Quasar Framework 官方文档docs/src/pages/vue-components/input.md编写,系统讲解 UI 组件库中 QInput 的完整使用方式:从五种互斥的设计风格(filled/outlined/standout/borderless)、文本输入与原生属性透传,到业界少见的强大 Mask 掩码系统(含自定义 token、反向填充、多掩码动态切换),再到内部/外部/异步表单验证、无障碍支持与原生表单提交。读完本文,你将掌握 QInput 在真实业务表单(电话号码、金额、序列号、身份证等格式受限输入)中的完整落地方案,并能结合源码理解其底层行为。

快速了解 QInput

QInput 是 Quasar 框架中用于捕获用户文本输入的核心表单组件,位于ui/src/components/input/QInput.js。它与原生<input>类似使用v-model双向绑定,同时内置了错误与验证支持,并提供丰富的样式、颜色与类型组合。

从源码看,QInput 的modelValue类型为StringNumberFileList(SSR/SSG 下不含 FileList,见 QInput.js),意味着它天然覆盖了普通文本、数字和文件选择三种场景。组件基于 QField 构建:QInput.js通过useField(见ui/src/composables/private.use-field/use-field.js)复用了 QField 的框架、标签、错误提示、插槽等全部能力,因此 QInput 的所有属性与行为都可以视为"QField 框架 + 原生 input/textarea + 掩码/防抖等增强"的组合。

组件暴露的方法(见 QInput.json):

方法说明
focus()聚焦底层原生 input 元素
blur()让底层原生 input 失去焦点
select()选中输入框文本
getNativeElement()获取原生 input/textarea DOM 元素(已废弃,请改用nativeEl

nativeEl是响应式计算属性(computed),同样返回底层原生元素。组件 API 的完整类型定义可查看 types/api/QInput.d.ts 或直接阅读QInput.json

设计(Design)

QInput 支持五种主要视觉设计。需要注意的是,这五种设计彼此互斥,一个 QInput 只能使用其中一种,不能混用。

  • Standard(标准):默认设计,输入框底部有一条下划线。
  • Filled(填充):输入框带有填充背景色。
  • Outlined(描边):输入框四周有边框轮廓。
  • Standout(突出):背景在聚焦/悬停时变化,常用于 QToolbar 中集成搜索框等场景(见 StandoutToolbar.vue)。
  • Borderless(无边框):不绘制边框、不改变背景色,用于将输入框无缝嵌入其他组件中。

颜色(Coloring)

QInput 支持通过color属性改变主题色,同时 Quasar 的dark布尔属性可强制切换暗色模式(见 Dark.vue)。颜色主题遵循 Quasar 全局色彩体系(primary、secondary、accent 等),可参考 ui/src/css/index.sass 中的主题变量定义。

Rounded 与 Square

  • rounded属性仅在Filled、Outlined、Standout三种设计下生效,用于将输入框四角变圆(见 Rounded.vue)。
  • square属性同样只在上述三种设计下有意义,用于去掉圆角、强制直角边框(见 SquareBorders.vue)。

Force dark mode

通过dark属性可以强制 QInput 使用暗色样式,而不管当前应用是否处于暗色主题,适用于局部区域深色化场景。

基础功能

原生属性透传

QInput 上所有不在其 props 列表中的属性都会被自动透传给内部的原生元素(<input><textarea>),例如autocompleteplaceholder等。这是通过inheritAttrs: false加手动合并 attrs 实现的(见 QInput.js),透传时还会自动带上tabindexmaxlengthdisabledreadonly等映射属性。这意味着你可以直接使用 HTML 原生规范中的属性,无需额外封装。原生属性完整清单可参考 MDN 的 input 与 textarea 文档。

Clearable 一键清空

添加clearable属性后,当有输入内容时会在输入框尾部出现一个清空图标,点击后将 model 重置为null。从源码看,清空动作调用onClear()(QInput.js),它会取消所有待执行的防抖/惰性更新并删除临时值,然后通过 QField 的onClear机制重置显示。

输入类型(type)

type属性支持渲染原生等价输入类型,取值包括textpasswordtextareaemailsearchtelfilenumberurltimedatedatetime-local(见 QInput.json)。

[!WARNING] 各浏览器对输入类型的支持与行为完全取决于浏览器自身渲染,与 Quasar 核心代码无关。

[!TIP] 某些输入类型(如datetime)始终会渲染浏览器控件。如果同时使用label,建议配合stack-label让标签始终悬浮在上方,否则标签会与原生控件重叠。

数字类型

使用数字输入时,应同时使用v-model.number(注意.number修饰符)与type="number"

<q-input v-model.number="age" type="number" label="Age" />

源码中对number类型做了专门处理:输入过程中先暂存字符串形式的临时值(temp.value),在update:modelValue发出时 Vue 的.number修饰符会将其转换为数字;同时floatingLabel计算属性对number类型会检查Number.isFinite,避免空值/非法值时标签异常悬浮(QInput.js)。

文件类型

[!TIP] 需要文件选择时,通常更推荐使用 QFile 或 QUploader 组件,而非 QInput 的type="file"

[!WARNING]切勿对type="file"的 QInput 使用v-model浏览器安全策略不允许为文件输入设置 value。因此你只能读取它(通过@update:model-value事件),无法写入。源码中对此有专门分支:当type === 'file'时,onInput直接 emite.target.files(FileList)而非字符串值(QInput.js),且渲染时使用useFileFormDomProps提供 DOM 属性而非 value(QInput.js)。

Textarea 文本域

type设为textarea(或使用autogrow)即可渲染为多行文本域。文本域的行距随字体大小变化,因此通过input-class/input-style调整字号时行距会自动保持均匀。

当内容增长时,可使用autogrow属性让文本域随内容自动增高。底层实现有两种路径(见 use-autogrow.js):

  • CSS 路径:浏览器支持field-sizing: content时直接交给 CSS 处理(性能最优);
  • JS 测量路径:不支持时,将 textarea 高度折叠为 1px、读取scrollHeight再写回为内联高度,并用requestAnimationFrame合并每帧内的多次触发,同时处理 Firefox 的 overflow 与滚动位置保留等边界情况。

前缀与后缀(Prefix and suffix)

通过prefixsuffix属性(或对应的prepend/append插槽)可在输入框前后附加静态文本,适合单位(如$kg)、货币符号等场景,见 PrefixSuffix.vue。

自定义标签(Custom label)

使用label插槽可完全自定义标签的展示形式,例如在标签内嵌入 QTooltip:

<q-input label-slot filled> <template #label> <q-icon name="info" size="14px" /> 用户名 </template> </q-input>

[!TIP] 使用label插槽时必须设置label-slot属性;若需要在插槽元素上交互(如 QTooltip 悬停),请为元素添加all-pointer-eventsclass。

Shadow text 阴影文本

shadowText属性可以在输入内容之后显示一段"影子"文字,用于预览提示完整格式,例如输入金额时提示小数点后位数。源码中通过getShadowControl()渲染一个不可见副本加影子文字的叠加层(QInput.js),该功能对type="file"不生效。

Slots 中的 submit 按钮

[!WARNING] 当把type="submit"的 QBtn 放入 QField / QInput / QSelect 的beforeafterprependappend插槽时,必须在该 QBtn 上额外添加@click监听器来调用表单提交方法。这些插槽内的 click 事件不会向上传播到父元素,因此仅靠原生 form submit 无法触发。

防抖(Debounce)

当你在 watch model 时执行昂贵操作(如请求远程校验),希望用户先输入完成再触发更新,而不是每次按键都更新 model。此时使用debounce属性(单位毫秒):

<q-input v-model="search" debounce="500" label="Search" />

源码中防抖通过emitTimer = setTimeout(emitValueFn, props.debounce)实现,防抖期间把用户输入暂存在temp.value中以保持界面即时反馈,定时器到点后才发出update:modelValue(QInput.js)。同时源码还处理了一个易被忽视的细节:当 model 已被外部重置时,会取消仍在途中的防抖发射(cancelPendingValueEmission()),避免过期中间值污染模型(use-mask.js)。

惰性更新(v-model.lazy)

使用v-model.lazy修饰符时,model 只在用户完成编辑时更新(原生change事件或输入框失焦时),而不是每次按键都更新,与原生<input>的行为一致。注意:使用v-model.lazydebounce属性会被忽略。源码中emitValueFn在 lazy 模式下保持待定状态,直到onChange(change 事件)或onFinishEditing(失焦)时被调用(QInput.js)。另外,v-model.trimv-model.number由 Vue 本身处理。

加载状态(Loading state)

QInput 支持loading属性,开启后显示加载指示器,常用于异步校验或远程数据回填场景(见 LoadingState.vue)。

Mask 掩码

mask属性可以强制/辅助用户输入特定格式,这是 QInput 最强大的功能之一,实现位于 use-mask.js。

[!WARNING] Mask 仅在typetext(默认)、searchurltelpassword时可用。源码通过getIsTypeText()检查类型并据此决定是否启用掩码逻辑(use-mask.js)。

[!WARNING]maxlength的冲突:Mask 本身已按槽位限制输入长度,因此不要maxlength组合使用。原生maxlength统计的是完整显示值(含字面符与填充字符),任何小于掩码全长的值都会过早阻断输入;而配合fill-mask时显示值始终是掩码全长,这样的maxlength会直接锁死整个输入框。

默认掩码 Token

Token说明
#数字
S字母 a-z,大小写不敏感
N字母数字,字母大小写不敏感
A字母,自动转换为大写
a字母,自动转换为小写
X字母数字,字母自动转换为大写
x字母数字,字母自动转换为小写

这些 token 在 use-mask.js 中定义:A/a/X/x带有transform函数(toLocaleUpperCase/toLocaleLowerCase),pattern用于单字符匹配,negate用于取反匹配。源码还针对纯 ASCII 的三种 pattern 做了零分配的性能优化(patternTesters,use-mask.js),其它 pattern 才回退到正则。

除自定义字符串外,mask还内置了命名掩码(见 use-mask.js):

名称展开的掩码
date####/##/##
datetime####/##/## ##:##
time##:##
fulltime##:##:##
phone(###) ### - ####
card#### #### #### ####

基本用法示例(摘自 MaskBasic.vue):

<q-input filled v-model="id" label="Special ID" mask="###/##" hint="Mask: ###/##" /> <q-input filled v-model="phone" label="Phone" mask="(###) ### - ####" /> <q-input filled v-model="serialNumber" label="Serial number" mask="AAAA - #### - #### - SSS" />

填充掩码(fill-mask)

默认掩码在未填满时只显示已输入的部分。fill-mask属性(布尔值或字符串)会用指定字符(传字符串时取第一个字符,默认_)填充掩码的剩余槽位:

<q-input v-model="date" mask="date" fill-mask="0" label="Date" />

注意源码中一个关键边界处理:当填充字符恰好满足某个 token(如fill-mask="0"#token),仅凭渲染值无法区分"填充"与"真实数据",因此 use-mask 维护了innerValueDataLen(填充前数据长度)来精确判定每个位置是否承载真实数据,避免每次按键都错误吞掉/多出一个填充字符(use-mask.js)。

光标与按键行为

Mask 会接管光标移动(跨越掩码字面符)以及BACKSPACE/DELETE的边界逻辑。你可以通过阻止其keydown事件来禁用掩码自身的按键处理——但注意这同时会取消浏览器对该键的原生处理,例如@keydown.left.prevent会让光标停留在原处而非跳过字面符,重新定位光标需要自己实现。底层由onMaskedKeydown实现(use-mask.js),它维护了 Shift 多选锚点(selectionAnchor)与四种方向移动(moveCursor.left/right/leftReverse/rightReverse)。

unmasked-value 原始值模式

如果你希望强制用户按格式输入,但 model 中保存的是去除格式的原始值,则使用unmasked-value属性:

<q-input v-model="phone" mask="phone" unmasked-value label="Phone" />

此时 model 保存纯数字(如0212345678),显示层仍带格式。源码在updateMaskValue中对unmasked-value使用unmaskValue(preMasked)在填充之前去掩码(use-mask.js)。

reverse-fill-mask 反向填充

reverse-fill-mask强制用户从掩码末尾开始填充,且允许输入长度不固定(不足部分不占位):

<q-input v-model="price" mask="#.##" fill-mask="#" reverse-fill-mask label="Price" />

源码专门实现了maskValueReverse从右侧向左装配数据,并处理了"字面符在左侧数据落地前不提前输出"等细节(use-mask.js)。

多掩码动态切换

当一个字段需要接受多种格式时(例如电话号码可能是 8 位或 9 位本地号码),可将mask绑定到计算属性,根据值的长度选择掩码。两个关键细节保证可靠性:

  1. 使用unmasked-value,让纯数字长度(而非当前掩码字面符)驱动切换决策;
  2. 给较短的掩码末尾多留一个 token 槽位,使跨越阈值的那个数字能够被输入——一旦输入,计算属性切换掩码并重新排版,光标保持在原数据位置。

实现示例可查看 MaskMultiple.vue。源码中掩码切换会保留光标前的数据字符数量(dataBeforeCaret),切换后在新的布局中重新锚定光标(use-mask.js)。

自定义掩码 Token(v2.18.4+)

mask-tokens属性允许在默认 token 基础上新增自定义 token,甚至可以覆盖部分/全部默认 token。自定义 token 的语法必须与默认 token 一致:pattern(必填,匹配单个字符的正则字符串)、negate(必填,不匹配的正则字符串)、transform(可选,字符转换函数)。

示例(摘自 MaskCustomTokens.vue):

<q-input filled v-model="id" label="Special ID" mask="AA-CC-XX-CC" :mask-tokens="customTokens" />
const customTokens = { C: { pattern: '[0-4a-eA-E]', negate: '[^0-4a-eA-E]', transform: v => v.toLocaleUpperCase() }, X: { pattern: '[5-8]', negate: '[^5-8]' } // 覆盖默认的 X }

源码中mask-tokens通过getTokenMap解析并与默认 token map 合并({ ...DEFAULT_TOKEN_MAP, ...customTokens }),且对mask-tokens做了深度监听,变更时自动重算掩码(use-mask.js)。

使用第三方掩码处理器

你也可以轻松接入任意第三方掩码处理器。思路是利用 QField 的control插槽替换内部控件。以 v-money 指令为例,从标准 QInput:

<q-input filled v-model="price" label="Price with 2 decimals" mask="#.##" fill-mask="#" reverse-fill-mask hint="Mask: #.00" input-class="text-right" />

改为 QField + 原生 input + v-money 指令:

<q-field filled v-model="price" label="Price with v-money directive" hint="Mask: $ #,###.00 #" > <template #control="{ id, floatingLabel, modelValue, emitValue }"> <input :id="id" class="q-field__input text-right" :value="modelValue" @change="e => emitValue(e.target.value)" v-money="moneyFormatForDirective" v-show="floatingLabel" /> </template> </q-field>
moneyFormatForDirective: { decimal: '.', thousands: ',', prefix: '$ ', suffix: ' #', precision: 2, masked: false /* doesn't work with directive */ }

或使用 money 组件:

<q-field filled v-model="price" label="Price with v-money component" hint="Mask: $ #,###.00 #" > <template #control="{ id, floatingLabel, modelValue, emitValue }"> <money :id="id" class="q-field__input text-right" :model-value="modelValue" @update:model-value="emitValue" v-bind="moneyFormatForComponent" v-show="floatingLabel" /> </template> </q-field>
moneyFormatForComponent: { decimal: '.', thousands: ',', prefix: '$ ', suffix: ' #', precision: 2, masked: true }

control插槽暴露的id(用于 label 关联)、floatingLabel(标签是否悬浮)、modelValueemitValue是接入第三方控件的关键协议,这正是 QField 将"框架渲染"与"控件渲染"解耦的体现。

验证(Validation)

内部验证(:rules)

通过:rules属性验证 QInput:传入内建规则数组或自定义校验器。自定义校验器是一个函数,校验成功返回true,失败返回错误消息字符串:

value => condition || errorMessage // 示例: value => value.includes('Hello') || 'Field must contain word Hello'

[!TIP] 出于性能考虑,默认情况下规则的变化不会触发重新验证,直到 model 变化。若希望规则变化时也触发验证,使用reactive-rules布尔属性。代价是性能开销(仅在确实需要时使用!),并且可以通过把规则写成计算属性(而不是在模板中内联)来略微缓解。

调用 QInput 的resetValidation()方法可重置验证状态(示例见 ValidationRequired.vue):

<q-input ref="inputRef" filled v-model="model" label="Required Field" :rules="[val => !!val || 'Field is required']" /> <q-btn label="Reset Validation" @click="inputRef.resetValidation()" />

[!WARNING]原生约束与 rules 是两套体系:原生 HTML 约束(如email/url类型,或透传到原生 input 的pattern/required属性)只会在原生表单提交时由浏览器强制执行。程序化的validate()方法(QInput 自身或外层 QForm)只评估 rules,不检查原生约束。因此任何需要被validate()捕获的约束都应同时写成规则,例如:rules="['email']"。注意 QInput 提供内建的常用规则字符串,如emailurl等,可直接复用。

lazy-rules 触发时机

设置lazy-rules后,验证在字段失焦时触发(readonly字段也触发,只有disabled字段豁免);错误显示期间,每次变更都会重新验证,一旦值合法错误立即清除。字段内部打开的菜单或对话框(如append插槽中的 QPopupProxy)在其打开期间保持字段聚焦,不算失焦。

lazy-rules设置为字符串ondemand,则验证在手动调用组件validate()方法或外层 QForm 提交时触发,适合完全由表单控制的场景。

异步规则(Async rules)

规则支持异步:使用 async/await 或直接返回 Promise。如果异步验证进行中值发生变化或字段失焦,字段会在异步验证结束后自动重新验证,确保显示的结论始终匹配当前值。

[!TIP] 建议将异步规则与debounce属性配合使用,避免每次按键都立即触发异步规则,造成性能损耗。

示例模式:

const rules = [ async val => { const ok = await checkUnique(val) return ok || '该值已被占用' } ]

外部验证(External validation)

也可以完全使用外部验证,只传入errorerror-message属性(需启用bottom-slots来显示错误消息):

<q-input filled v-model="model" :error="hasError" error-message="用户名已存在" bottom-slots />

[!TIP] 根据需求,你可以连接 Regle(官方推荐方案)或其他验证库到 QInput。

错误消息的显示槽位也可以自定义(见 ValidationSlots.vue),例如在错误文本旁加图标或改变布局。

无障碍(Accessibility,v2.25+)

QInput 在 QField 框架内渲染原生<input>(或<textarea>),因此 QField 的无障碍章节所述内容全部适用:

  • 通过生成的 SSR 安全 id 建立 label 关联;
  • 错误消息以role="alert"播报,并通过aria-invalid/aria-errormessage/aria-describedby从控件引用;
  • 清空按钮可通过键盘操作。

在此基础上,label属性会额外作为aria-label暴露到原生元素(自行设置的aria-label/aria-labelledby优先级更高);disablereadonly会映射为原生disabledreadonly属性(因此 readonly 输入框保留在 Tab 顺序中,聚焦时显示聚焦态)。其余原生属性(placeholderautocompleteinputmode等)均透传到原生元素。这与 QInput.js 中inputAttrs的组装逻辑完全一致。

原生表单提交

当 QInput 用于带actionmethod的原生表单时(例如 Quasar 配合 ASP.NET 控制器),必须指定name属性,否则 formData 中不会包含该字段(如果需要提交它的话):

<form action="/submit" method="post"> <q-input name="username" v-model="username" label="Username" /> </form>

源码通过useFormInputNameAttr为控件提供 name 属性(QInput.js),未设置name时该字段不会进入 formData。

进阶:结合源码理解输入管线

了解 QInput 的底层工作流有助于排查疑难问题。核心输入管线如下:

  1. 输入事件:用户键入触发onInput,非 file 类型时读取e.target.value
  2. 暂存与发射emitValue(val)根据修饰符决定发射策略——debounce走定时器、v-model.lazy挂起等待 change/blur、其余立即发射(QInput.js);
  3. 掩码介入:有 mask 时走updateMaskValue,完成去掩码、重装配、光标定位与unmasked-value转换;
  4. IME 输入法合成:通过qComposing标记跳过掩码重写,避免中文等输入法合成期间值被篡改(QInput.js);
  5. 失焦收尾onFinishEditing清空暂存值、取消待发射的防抖定时器并同步显示值。

对应的测试覆盖可参考 QInput.test.js 与 use-mask.test.js,其中包含大量针对光标移动、填充字符边界、反向填充、防抖竞态等场景的回归用例。

结语

QInput 远不止是一个"带样式的 input":它由 QField 框架提供一致的布局/标签/错误体系,自带防抖、惰性更新、加载态与无障碍支持,更内置了一套可自定义 token、可反向填充、可动态切换的生产级掩码引擎。无论是简单的登录表单,还是复杂的电话号码、金额、序列号输入,QInput 都能在保持原生输入体验的同时完成格式约束与验证闭环。结合 input.md 官方文档、docs/src/examples/QInput 目录下的 37 个可运行示例,以及 use-mask.js 等源码,你可以进一步验证并扩展本文涉及的所有能力。

  • 前端
  • UI组件
  • 跨平台

【免费下载链接】quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time

项目地址:https://gitcode.com/gh_mirrors/qu/quasar
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 12:38:06

伺服增益参数简述及其调整

参考文献 [1] 颜嘉男. 伺服电机应用技术[M]. 第1版. 北京:科学出版社, 2010. [2] 台达. ASDA-B2伺服手册[EB/OL]. [3] 陈国强, Putra A S. 工业自动化中的驱动与控制[M]. 第1版. 北京:机械工业出版社, 2016 :86-105. [4] 汇川技术. IS620F系列伺服用户手册[EB/OL]. 相关内容回…

作者头像 李华
网站建设 2026/9/20 12:36:34

甲烷燃烧模拟必备:GRI-Mech 3.0机理详解与Cantera实操

简介&#xff1a;GRI-Mech 3.0 是燃烧仿真中广泛采用的甲烷多步反应机理&#xff0c;涵盖 325 个化学反应步骤&#xff0c;能够刻画链分支、链终止以及自由基生成与消耗等核心过程。资源面向从事天然气燃烧、火焰传播和污染物排放模拟的工程师与研究人员&#xff0c;可在 ANSYS…

作者头像 李华
网站建设 2026/9/20 12:35:16

GBD疾病负担数据分析:R语言从指标解读到可视化实战

简介&#xff1a;这是一套基于R语言与GlobalBurdenR工具包分析全球疾病负担&#xff08;GBD&#xff09;数据的代码包&#xff0c;面向公共卫生研究人员、流行病学分析者及有一定R基础的开发者&#xff0c;用于解决GBD数据加载、合并、清洗、筛选及APC模型构建中的实际问题。压…

作者头像 李华
网站建设 2026/9/20 12:35:13

3D激光SLAM算法选型:从Cartographer3D到LIO-SAM的工程实践对比

这两年我几乎每周都会收到类似的咨询&#xff1a;“手头一个机器人项目&#xff0c;室内外都有&#xff0c;雷达是16线机械式&#xff0c;到底该上Cartographer3D还是直接上LIO-SAM&#xff1f;”说实话&#xff0c;每次看到这种问题&#xff0c;我都会多问一句&#xff1a;你先…

作者头像 李华
网站建设 2026/9/20 12:33:17

基于KITTI的YOLOv2/YOLOv3修订实践:anchor重聚类与训练调优

简介&#xff1a;面向自动驾驶与目标检测研究者的KITTI数据集修订版YOLOv2/YOLOv3资源包&#xff0c;基于Darknet框架实现&#xff0c;专门针对车辆、行人、交通标志等复杂交通场景进行网络结构与损失函数优化。压缩包共982个文件&#xff0c;包含大量png标注图像、C语言与CUDA…

作者头像 李华
网站建设 2026/9/20 12:31:28

MI50 32G 本地大模型部署实战:从 ROCm 驱动到 llama.cpp 推理

1. 为什么选择 MI50 32G 搭建本地大模型环境1.1 一张被低估的推理卡MI50 是 AMD 在 2018 年底推出的数据中心级加速卡&#xff0c;基于 Vega 20 核心&#xff0c;7nm 工艺&#xff0c;16GB 和 32GB 两个版本。当年它的直接竞争对手是英伟达的 V100&#xff0c;但时过境迁&#…

作者头像 李华