Appearance
BizAmountInput 金额输入
表单侧金额/数量录入(与 BizAmount 展示侧互补):v-model 按 unit(元/分)收发、界面统一元并失焦千分位(聚焦还原原样编辑)、上下限失焦回弹提示、uppercase 实时人民币大写、allowNegative 放开负数(退款/违约金);units 数量单位组进入换算模式——件↔箱↔吨切换数值按 rate 联动互转,v-model 恒为基准单位数量(ERP/WMS 数量录入);percent 进入费率模式——v-model 即百分数值(3.5 = 3.5%),后缀展示 + 默认 0~100 回弹,min 传负值即负数档(同比 / 回撤),precision 支持多位小数(利率 / 费率 / 折扣 / 提成比例)。
基础用法
¥
壹万贰仟捌佰肆拾伍元陆角
v-model:12845.6|最近确认:(未确认)
失焦千分位格式化、聚焦原样编辑;
change 在失焦/回车通过范围校验后触发。<script setup lang="ts">
/** 基础用法:失焦千分位、聚焦原样编辑、change 确认事件 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const amount = ref<number | undefined>(12845.6)
const lastChange = ref('(未确认)')
const onChange = (value: number | undefined): void => {
lastChange.value = value === undefined ? '(清空)' : `¥${value.toFixed(2)}`
ElMessage.success(`确认金额:${lastChange.value}`)
}
</script>
<template>
<div style="max-width: 360px">
<BizAmountInput v-model="amount" uppercase @change="onChange" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
v-model:{{ amount }}|最近确认:{{ lastChange }}
</div>
</div>
</template>
显示代码
分单位接口(cent)
¥
v-model(分):199900 —— 界面展示 1,999.00 元,无需手工 ×100/÷100
接口存分、界面显元:
unit="cent" 时 v-model 为分(自动换算),避免 0.1 + 0.2 浮点误差。<script setup lang="ts">
/** 场景:分单位接口——unit="cent" 时 v-model 为分,界面统一元展示 */
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { BizAmountInput } from 'vue3-ep-biz-lib'
/** 接口字段 pay_amount 单位为分 */
const form = ref({ pay_amount: 199900 })
const submit = (): void => {
window.console.log('提交给后端(分):', form.value.pay_amount)
}
</script>
<template>
<div style="max-width: 360px">
<BizAmountInput v-model="form.pay_amount" unit="cent" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
v-model(分):{{ form.pay_amount }} —— 界面展示 1,999.00 元,无需手工 ×100/÷100
</div>
<ElButton style="margin-top: 8px" type="primary" size="small" @click="submit">提交(看控制台)</ElButton>
</div>
</template>
显示代码
范围校验
¥
竞价范围 ¥100 ~ ¥100,000:输入 50 或 200000 失焦后自动回弹并警告
min / max 越界失焦回弹到边界并提示——预算上限、起投金额等硬约束场景。<script setup lang="ts">
/** 场景:范围校验——min/max 越界失焦回弹到边界并提示 */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const bid = ref<number | undefined>(500)
</script>
<template>
<div style="max-width: 360px">
<BizAmountInput v-model="bid" :min="100" :max="100000" symbol="¥" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
竞价范围 ¥100 ~ ¥100,000:输入 50 或 200000 失焦后自动回弹并警告
</div>
</div>
</template>
显示代码
合同金额大写联动
合同金额
¥
壹拾贰万零伍拾元零伍分
违约金(允许负数)
¥
负叁佰元整
uppercase 实时渲染人民币大写(角分/元整/负数),合同与凭证录入的标准搭配。<script setup lang="ts">
/** 场景:合同金额大写联动——uppercase 实时人民币大写(含负数违约金) */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const contractAmount = ref<number | undefined>(120050.05)
const penalty = ref<number | undefined>(-300)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 16px; max-width: 360px">
<div>
<div style="margin-bottom: 4px; font-size: 13px; color: var(--el-text-color-secondary)">合同金额</div>
<BizAmountInput v-model="contractAmount" uppercase />
</div>
<div>
<div style="margin-bottom: 4px; font-size: 13px; color: var(--el-text-color-secondary)">违约金(允许负数)</div>
<BizAmountInput v-model="penalty" uppercase allow-negative />
</div>
</div>
</template>
显示代码
报销表单弹框
与 el-form 集成:金额作为表单字段参与必填校验,上限 5 万失焦回弹。
<script setup lang="ts">
/** 场景:报销表单——el-form 集成(事由 + 金额必填校验,金额上限 5 万回弹) */
import { reactive, ref } from 'vue'
import { ElButton, ElForm, ElFormItem, ElInput, ElMessage } from 'element-plus'
import { BizAmountInput } from 'vue3-ep-biz-lib'
import type { FormInstance, FormRules } from 'element-plus'
interface ExpenseForm {
title: string
amount: number | undefined
}
const formRef = ref<FormInstance>()
const form = reactive<ExpenseForm>({ title: '', amount: undefined })
const rules: FormRules = {
title: [{ required: true, message: '请填写报销事由', trigger: 'blur' }],
amount: [{ required: true, message: '请输入金额', trigger: 'change' }],
}
const onSubmit = (): void => {
formRef.value?.validate((valid) => {
if (!valid) return
ElMessage.success(`报销提交成功:${form.title} ¥${form.amount?.toFixed(2)}`)
})
}
</script>
<template>
<div style="max-width: 420px">
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px">
<ElFormItem label="报销事由" prop="title">
<ElInput v-model="form.title" placeholder="如:客户拜访交通费" />
</ElFormItem>
<ElFormItem label="金额" prop="amount">
<BizAmountInput v-model="form.amount" :max="50000" />
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="onSubmit">提交报销</ElButton>
</ElFormItem>
</ElForm>
</div>
</template>
显示代码
多币种与精度
$
JP¥
¥
symbol 切换货币符号、precision 控制小数位(美元 2 位 / 日元 0 位)。<script setup lang="ts">
/** 场景:多币种与精度——美元 2 位 / 日元 0 位 / 人民币 2 位 */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const usd = ref<number | undefined>(2499.99)
const jpy = ref<number | undefined>(38000)
const cny = ref<number | undefined>(89900)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 16px; max-width: 360px">
<BizAmountInput v-model="usd" symbol="$" />
<BizAmountInput v-model="jpy" symbol="JP¥" :precision="0" />
<BizAmountInput v-model="cny" symbol="¥" />
</div>
</template>
显示代码
币种换算(rate 本位币联动)
$
≈ 8,978.59 CNY(本位币 · 捌仟玖佰柒拾捌元伍角玖分)
rate 注入即启用:输入外币金额,下方实时联动本位币(千分位 + 人民币大写);v-model 保持外币原值。<script setup lang="ts">
/** 币种换算基础:rate 注入即启用——输入外币金额,下方实时联动本位币(千分位 + 人民币大写) */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const amount = ref(1250.5)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 6px; max-width: 280px">
<BizAmountInput v-model="amount" symbol="$" :rate="7.18" placeholder="输入美元金额" />
<span style="font-size: 12px; color: var(--el-text-color-placeholder)">
v-model = {{ amount }}(美元原值) · 汇率 7.18:输入即换算 ≈ ¥ 8,978.59 CNY
</span>
</div>
</template>
显示代码
汇率变化重算
$
≈ 7,180.00 CNY(本位币 · 柒仟壹佰捌拾元整)
切币种 / 调牌价:symbol、precision、rate 响应式联动,换算行即时重算无需重输。
<script setup lang="ts">
/** 汇率变化重算:rate / symbol / precision 响应式联动(切币种 + 调牌价场景) */
import { computed, ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const amount = ref(1000)
const currencyKey = ref<'usd' | 'eur' | 'jpy'>('usd')
const rate = ref(7.18)
const CURRENCIES = {
usd: { symbol: '$', rate: 7.18, precision: 2 },
eur: { symbol: '€', rate: 7.82, precision: 2 },
jpy: { symbol: '¥', rate: 0.047, precision: 0 },
} as const
const current = computed(() => CURRENCIES[currencyKey.value])
const onSwitch = (key: 'usd' | 'eur' | 'jpy'): void => {
currencyKey.value = key
rate.value = CURRENCIES[key].rate
}
const bumpRate = (): void => {
rate.value = Number((rate.value * 1.01).toFixed(4))
}
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 10px; max-width: 300px">
<BizAmountInput v-model="amount" :symbol="current.symbol" :precision="current.precision" :rate="rate" />
<div style="display: flex; gap: 8px">
<el-button size="small" @click="onSwitch('usd')">美元 7.18</el-button>
<el-button size="small" @click="onSwitch('eur')">欧元 7.82</el-button>
<el-button size="small" @click="onSwitch('jpy')">日元 0.047</el-button>
<el-button size="small" type="primary" plain @click="bumpRate">汇率 +1%</el-button>
</div>
<span style="font-size: 12px; color: var(--el-text-color-placeholder)">当前汇率:{{ rate }}(换算行随 rate 响应式重算,无需重输)</span>
</div>
</template>
显示代码
本位币大写与只读回显
€
≈ 69,337.28 CNY(本位币 · 陆万玖仟叁佰叁拾柒元贰角捌分)
换算行自带本位币大写(≈ 69,337.28 CNY · 陆万玖仟叁佰叁拾柒元贰角捌分); 跨币种请勿另开 uppercase(其大写口径仅适配人民币输入)。
审批快照只读回显:
$
≈ 88,641.41 CNY(本位币 · 捌万捌仟陆佰肆拾壹元肆角壹分)
换算行自带本位币大写(跨币种勿开 uppercase,其大写口径仅适配人民币输入);disabled 适配审批快照回显。
<script setup lang="ts">
/** 本位币大写联动 + 只读回显:换算行自带人民币大写;disabled 适配审批快照 */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const amount = ref(8866.66)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 14px; max-width: 300px">
<div>
<BizAmountInput v-model="amount" symbol="€" :rate="7.82" base-currency="CNY" />
<p style="margin: 6px 0 0; font-size: 12px; color: var(--el-text-color-placeholder)">
换算行自带本位币大写(≈ 69,337.28 CNY · 陆万玖仟叁佰叁拾柒元贰角捌分);
跨币种请勿另开 uppercase(其大写口径仅适配人民币输入)。
</p>
</div>
<div>
<span style="font-size: 12px; color: var(--el-text-color-secondary)">审批快照只读回显:</span>
<BizAmountInput :model-value="12345.6" symbol="$" :rate="7.18" disabled />
</div>
</div>
</template>
显示代码
单位换算(件↔箱↔打)
基准数量:120(件)
v-model(基准/件):120;当前单位:件
切到「箱」时 120 件自动显示为 5,输入 6 箱回写 144 件——提交口径始终是基准单位。
units + v-model:measure-unit:切换单位显示数值按 rate 联动互转,v-model 恒为基准单位(rate=1)数量,组件下方实时提示基准换算。<script setup lang="ts">
/** 场景:单位换算基础——件/箱/打切换数值联动互转,v-model 恒为基准单位(件) */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
import type { BizAmountUnitOption } from 'vue3-ep-biz-lib'
const units: BizAmountUnitOption[] = [
{ label: '件', rate: 1 },
{ label: '打', rate: 12 },
{ label: '箱', rate: 24 },
]
const qty = ref<number | undefined>(120)
const measure = ref('件')
</script>
<template>
<el-space direction="vertical" size="large">
<BizAmountInput
v-model="qty"
v-model:measure-unit="measure"
:units="units"
:precision="0"
placeholder="请输入数量"
style="width: 280px"
/>
<el-alert type="info" :closable="false" style="width: 380px">
<p style="margin: 0">v-model(基准/件):<strong>{{ qty }}</strong>;当前单位:<strong>{{ measure }}</strong></p>
<p style="margin: 4px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
切到「箱」时 120 件自动显示为 5,输入 6 箱回写 144 件——提交口径始终是基准单位。
</p>
</el-alert>
</el-space>
</template>
显示代码
重量换算(吨/千克/克)
基准数量:2.5(吨)
基准单位为「吨」(rate=1):2.5 吨切「千克」显示 2,500,切「克」显示 2,500,000;v-model 始终为吨。
非整数 rate 同样适用:基准单位「吨」,切千克/克自动放大显示。
<script setup lang="ts">
/** 场景:吨/千克/克重量换算——非整数 rate 与小数精度 */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
import type { BizAmountUnitOption } from 'vue3-ep-biz-lib'
const units: BizAmountUnitOption[] = [
{ label: '吨', rate: 1 },
{ label: '千克', rate: 0.001 },
{ label: '克', rate: 0.000001 },
]
const weight = ref<number | undefined>(2.5)
const measure = ref('吨')
</script>
<template>
<el-space direction="vertical" size="large">
<BizAmountInput
v-model="weight"
v-model:measure-unit="measure"
:units="units"
:precision="2"
placeholder="请输入重量"
style="width: 280px"
/>
<p style="margin: 0; font-size: 13px; color: var(--el-text-color-secondary)">
基准单位为「吨」(rate=1):2.5 吨切「千克」显示 2,500,切「克」显示 2,500,000;v-model 始终为吨。
</p>
</el-space>
</template>
显示代码
采购单数量表单
min/max 与 v-model 同为基准单位口径,失焦回弹按当前单位提示;提交 payload 始终基准单位。
<script setup lang="ts">
/** 场景:采购单数量表单——min/max 基准口径校验 + 提交 payload(件为基准) */
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizAmountInput } from 'vue3-ep-biz-lib'
import type { BizAmountUnitOption } from 'vue3-ep-biz-lib'
const units: BizAmountUnitOption[] = [
{ label: '件', rate: 1 },
{ label: '箱', rate: 24 },
]
const form = reactive({
material: '温湿度传感器(电池版)',
qty: 48,
measure: '件',
})
const submitting = ref(false)
const onSubmit = (): void => {
if (form.material.trim() === '') {
ElMessage.warning('请填写物料名称')
return
}
if (form.qty === undefined) {
ElMessage.warning('请输入采购数量')
return
}
submitting.value = true
setTimeout(() => {
submitting.value = false
ElMessage.success(`已下单:${form.material} × ${form.qty} 件`)
}, 600)
}
</script>
<template>
<el-form label-width="92px" style="max-width: 460px">
<el-form-item label="物料名称">
<el-input v-model="form.material" />
</el-form-item>
<el-form-item label="采购数量" required>
<BizAmountInput
v-model="form.qty"
v-model:measure-unit="form.measure"
:units="units"
:precision="0"
:min="1"
:max="960"
placeholder="请输入数量"
@change="(v: number | undefined) => { if (v !== undefined && v < 1) ElMessage.warning('最低 1 件') }"
/>
</el-form-item>
<el-form-item label="口径说明">
<span style="font-size: 13px; color: var(--el-text-color-secondary)">min/max 与 v-model 同为基准单位(件):1 ~ 960 件</span>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="submitting" @click="onSubmit">提交采购单</el-button>
</el-form-item>
</el-form>
</template>
显示代码
费率模式(基础)
%
v-model:3.5(直接是百分数值,无单位换算);输入 120 或 -5 失焦回弹到边界。
percent 开启费率模式:v-model 直接是百分数值(3.5 = 3.5%,无元分换算),后缀 % + 千分位复用,默认 0 ~ 100 越界失焦回弹;与 units 互斥(percent 优先)。<script setup lang="ts">
/** 费率模式基础用法:v-model 即百分数值(3.5 = 3.5%),% 后缀 + 千分位 + 默认 0~100 失焦回弹 */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const rate = ref<number | undefined>(3.5)
const history = ref<string[]>([])
const onChange = (value: number | undefined): void => {
history.value.unshift(`费率确认为 ${value === undefined ? '空' : `${value}%`}`)
if (history.value.length > 3) history.value.pop()
}
</script>
<template>
<div style="max-width: 320px">
<BizAmountInput v-model="rate" percent @change="onChange" />
<p style="margin: 8px 0 0; font-size: 13px; color: var(--el-text-color-secondary)">
v-model:{{ rate }}(直接是百分数值,无单位换算);输入 120 或 -5 失焦回弹到边界。
</p>
<p v-for="item in history" :key="item" style="margin: 4px 0 0; font-size: 13px; color: var(--el-text-color-secondary)">
· {{ item }}
</p>
</div>
</template>
显示代码
费率模式(自定义口径)
贷款本金(元)
年化利率(0 ~ 36)
%
手续费率(精度 3 位)
%
预估年成本:4,725.00 元 (min / max 覆盖默认 0~100 口径,失焦回弹提示带后缀)
min / max 覆盖默认 0~100 口径(年化利率上限 36),precision 支持三位小数费率——金融产品 / 结算费配置录入。<script setup lang="ts">
/** 自定义口径的费率录入:年化利率 0~36、手续费率精确到 0.001,联动预估年息 */
import { computed, ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
import { ElInputNumber } from 'element-plus'
const principal = ref<number | undefined>(100000)
const annualRate = ref<number | undefined>(4.35)
const feeRate = ref<number | undefined>(0.375)
/** 预估年息 = 本金 ×(利率 + 费率)/ 100 */
const annualCost = computed(() => {
const p = principal.value ?? 0
const r = (annualRate.value ?? 0) + (feeRate.value ?? 0)
return Number(((p * r) / 100).toFixed(2))
})
</script>
<template>
<div style="max-width: 360px; display: flex; flex-direction: column; gap: 12px">
<div>
<p style="margin: 0 0 4px; font-size: 13px">贷款本金(元)</p>
<ElInputNumber v-model="principal" :min="0" :step="10000" style="width: 100%" />
</div>
<div>
<p style="margin: 0 0 4px; font-size: 13px">年化利率(0 ~ 36)</p>
<BizAmountInput v-model="annualRate" percent :max="36" placeholder="年化利率" />
</div>
<div>
<p style="margin: 0 0 4px; font-size: 13px">手续费率(精度 3 位)</p>
<BizAmountInput v-model="feeRate" percent :precision="3" placeholder="手续费率" />
</div>
<p style="margin: 0; font-size: 13px; color: var(--el-text-color-secondary)">
预估年成本:{{ annualCost.toLocaleString('zh-CN', { minimumFractionDigits: 2 }) }} 元
(min / max 覆盖默认 0~100 口径,失焦回弹提示带后缀)
</p>
</div>
</template>
显示代码
费率模式(折扣)
折
原价 568 元 → 折后 499.84 元;范围 0 ~ 9.9 折,精度 1 位。
percent-suffix 改后缀为「折」:配合 max=9.9 + precision=1 即成折扣录入,联动计算折后价。<script setup lang="ts">
/** 折扣录入:percent-suffix 改「折」+ max=9.9 + 精度 1,实时联动折后价 */
import { computed, ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const price = 568
const discount = ref<number | undefined>(8.8)
/** 折后价 = 原价 × 折扣 / 10 */
const finalPrice = computed(() => Number(((price * (discount.value ?? 0)) / 10).toFixed(2)))
</script>
<template>
<div style="max-width: 320px">
<BizAmountInput
v-model="discount"
percent
percent-suffix="折"
:max="9.9"
:precision="1"
placeholder="请输入折扣"
/>
<p style="margin: 8px 0 0; font-size: 13px; color: var(--el-text-color-secondary)">
原价 {{ price }} 元 → 折后 <b>{{ finalPrice }}</b> 元;范围 0 ~ 9.9 折,精度 1 位。
</p>
</div>
</template>
显示代码
费率模式(负数档)
营收同比(-100 ~ 100)
%
最大回撤(-100 ~ 0)
%
min=-100 放开负百分比:同比下滑、最大回撤等负向指标与正向费率同一录入组件统一口径。<script setup lang="ts">
/** 负数档费率:min=-100 放开负百分比(同比下滑 / 回撤录入口径统一在费率模式内) */
import { ref } from 'vue'
import { BizAmountInput } from 'vue3-ep-biz-lib'
const growth = ref<number | undefined>(-12.5)
const drawdown = ref<number | undefined>(-8.2)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 10px; max-width: 320px">
<div>
<p style="margin: 0 0 4px; font-size: 13px">营收同比(-100 ~ 100)</p>
<BizAmountInput v-model="growth" percent :min="-100" :max="100" :precision="1" placeholder="同比增减" />
</div>
<div>
<p style="margin: 0 0 4px; font-size: 13px">最大回撤(-100 ~ 0)</p>
<BizAmountInput v-model="drawdown" percent :min="-100" :max="0" :precision="2" placeholder="区间回撤" />
</div>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model | number | — | 金额/数量数值(金额模式按 unit 单位;units 模式恒为基准单位数量;percent 模式即百分数值) |
| unit | 'yuan' | 'cent' | 'yuan' | v-model 单位:元 / 分(接口存分自动换算;金额模式) |
| units | BizAmountUnitOption[] | [] | 数量单位组(传入即启用换算模式):{ label, rate },rate = 1 个该单位对应多少基准单位 |
| percent | boolean | false | 费率模式:v-model 即百分数值(3.5 = 3.5%),后缀展示 + 千分位,默认 0~100 失焦回弹(min/max 可覆盖口径);与 units 互斥(percent 优先) |
| percent-suffix | string | '%' | 费率模式后缀文案(折扣场景传 '折' 配合 max=10) |
| v-model:measure-unit | string | 首单位 | units 模式当前单位(切换时显示数值联动换算,v-model 基准值不变) |
| precision | number | 2 | 小数位数(元展示精度) |
| min / max | number | — | 上下限(与 v-model 同口径:金额模式 unit 单位、units 模式基准单位),越界失焦回弹并提示 |
| symbol | string | '¥' | 货币符号前缀(空串隐藏) |
| rate | number | — | 汇率(1 输入币种 = rate 本位币):> 0 且非 units/percent 模式时,输入框下方联动展示本位币金额(千分位 + 人民币大写);v-model 保持外币原值 |
| base-currency | string | 'CNY' | 本位币种代码(换算行展示口径) |
| uppercase | boolean | false | 下方实时人民币大写(大写口径仅适配人民币输入;外币场景请用 rate 换算行自带的本位币大写) |
| allow-negative | boolean | false | 允许负数(退款/违约金) |
| placeholder | string | 见说明 | 占位提示(金额模式默认 '请输入金额',percent 模式默认 '请输入比例') |
| disabled | boolean | false | 禁用 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:model-value | (value: number | undefined) | 输入实时更新(含换算) |
| change | (value: number | undefined) | 失焦/回车确认且通过范围校验后触发 |
Slots
| 插槽名 | 说明 |
|---|---|
| — | 无自定义插槽 |
Expose
| 属性/方法 | 说明 |
|---|---|
| focus() / blur() | 聚焦 / 失焦(表单校验滚动定位用) |