Skip to content

Vue ​

来自 tinyval-mask/vue 的 v-mask 指令可以把掩码绑定到字段上。该包运行时不依赖 Vue:指令只是一个普通对象,Vue 仅用于类型。

vue
<script setup lang="ts">
import { ref } from 'vue';
import { phone, money } from 'tinyval-mask/presets';
import { vMask } from 'tinyval-mask/vue';

// create masks once, not inline in the template
const phoneMask = phone();
const moneyMask = money({ currency: '₽' });

const tel = ref('');
const amount = ref('');
</script>

<template>
  <input v-model="tel" v-mask="phoneMask" />
  <input v-model="amount" v-mask="moneyMask" inputmode="decimal" />
  <input v-mask="'99.99.9999'" />
</template>
  • v-model 得到的是带掩码的值:+7 (999) 123-45-67。如需去掉掩码的值,请添加 .raw 修饰符 —— 见下文。
  • 请在 <script> 中创建掩码:像 v-mask="phone()" 这样的表达式会在每次渲染时创建新的掩码。
  • 指令可以放在包裹元素上 —— 它会找到内部的 <input>。这样掩码就能用于 UI 组件库的字段。
  • 全局注册:app.directive('mask', vMask)。

去掉掩码的值 —— .raw ​

使用 .raw 修饰符时,输入框显示掩码,而 v-model 得到的是去掉掩码的值 —— 与 unmask 的返回值相同。可以直接保存:

vue
<input v-model="tel" v-mask.raw="phoneMask" />    <!-- tel: '79991234567' -->
<input v-model="amount" v-mask.raw="moneyMask" /> <!-- amount: '1500.5' -->

模型中的值会带掩码显示:tel = '79991234567' → 输入框显示 +7 (999) 123-45-67。即使 Vue 重新渲染输入框,在中间编辑时光标也不会跳动。

可见模板 ​

传入占位字符 —— 获得焦点时输入框会显示完整模板,光标位于第一个空位:

vue
<input v-model="tel" v-mask.raw="{ mask: phoneMask, placeholder: '_' }" placeholder="Phone" />
<!-- on focus: +7 (___) ___-__-__   typing: +7 (999) 12_-__-__ -->
  • 模板不会进入 v-model:不使用 .raw 时为 +7 (999) 12,使用 .raw 时为 7999912。
  • 空输入框失去焦点时会被清空 —— 显示普通的 placeholder 提示。部分填写的输入框会保留模板。
  • 数字掩码没有模板:它们的长度不固定。

与 tinyval-vue 一起使用 ​

v-mask 可以用于 <TvField> 以及任何 tinyval-vue 表单字段。使用 .raw 时表单直接得到数字,Schema 无需 unmask 即可校验:

vue
<script setup lang="ts">
import { object, string, pipe, length } from 'tinyval';
import { useForm, TvForm, TvField, TvError } from 'tinyval-vue';
import { phone } from 'tinyval-mask/presets';
import { vMask } from 'tinyval-mask/vue';

const phoneMask = phone();

const Contact = object({
  phone: pipe(string(), length(11)),
});

const form = useForm(Contact, { initial: { phone: '' } });
</script>

<template>
  <TvForm :form="form" @submit="(data) => api.post('/contacts', data)">
    <TvField name="phone" v-mask.raw="{ mask: phoneMask, placeholder: '_' }" inputmode="tel" />
    <TvError name="phone" />
  </TvForm>
</template>

字段中显示 +7 (999) 123-45-67;form.values.phone 和 data 中为 79991234567。

UI 组件库 ​

vue
<el-input v-model="tel" v-mask="phoneMask" />
<v-text-field v-model="tel" v-mask="phoneMask" />

另请参阅 ​