跳转到内容

attributes — HTML 属性设置

本文介绍如何通过 Actions 设置字段的 HTML attributes。

attributes 通过 setAttribute 写在字段组件的宿主元素上。下方示例:悬停输入框看 title;敲击键盘,日志会实时读出宿主上的 data-role / data-lengthpatchAsync 随值更新)。

actions.attributes.set — 设置属性值

Section titled “actions.attributes.set — 设置属性值”

将指定对象设置为字段的 HTML attributes:

import { actions } from '@piying/view-angular-core';

const schema = v.pipe(
  v.string(),
  actions.attributes.set({
    'data-testid': 'username-field',
    'aria-label': '请输入用户名',
    autocomplete: 'username',
  }),
);

actions.attributes.patch — 合并属性值

Section titled “actions.attributes.patch — 合并属性值”

在已有属性上合并新的键值对:

const schema = v.pipe(
  v.string(),
  actions.attributes.set({ 'data-testid': 'name' }),
  actions.attributes.patch({ readonly: true }),
);

// 最终 attributes = { 'data-testid': 'name', readonly: true }

actions.attributes.remove — 移除属性键

Section titled “actions.attributes.remove — 移除属性键”
const schema = v.pipe(
  v.string(),
  actions.attributes.set({ 'data-testid': 'name', autocomplete: 'on' }),
  actions.attributes.remove(['autocomplete']),
);

// 最终 attributes = { 'data-testid': 'name' }

actions.attributes.patchAsync — 异步设置属性

Section titled “actions.attributes.patchAsync — 异步设置属性”

通过字段引用动态创建异步属性值:

const schema = v.pipe(
  v.string(),
  actions.attributes.patchAsync({
    'data-value': (field) => field.form.control?.value ?? '',
  }),
);

actions.attributes.mapAsync — 映射属性值

Section titled “actions.attributes.mapAsync — 映射属性值”

patchAsync「按 key 赋值」不同,mapAsync 拿到整个 attributes 对象做函数式变换。写法是 (field) => (value) => 新值

const schema = v.pipe(
  v.string(),
  actions.attributes.set({ 'data-role': 'input', 'data-len': '0' }),
  // 给所有 key 加上命名空间前缀,并注入当前值的长度
  actions.attributes.mapAsync((field) => {
    return (value: Record<string, any>) => {
      const len = String(field.form.control?.value?.length ?? 0);
      return Object.fromEntries(
        Object.entries(value).map(([k, v]) => [`piying-${k}`, k === 'data-len' ? len : v]),
      );
    };
  }),
);

// 最终 attributes = { 'piying-data-role': 'input', 'piying-data-len': '<当前输入长度>' }

mapAsync 适合「批量改写已有属性」的场景(加前缀、脱敏、统一注入)。只是根据字段状态设几个值时,用 patchAsync 更直接。

actions.attributes.top — 作用于最外层容器

Section titled “actions.attributes.top — 作用于最外层容器”

top.set / top.patch 把属性写到字段的最外层 wrapper(无 wrapper 时为字段自身),常用于由 wrapper 渲染的卡片/fieldset 等容器:

const schema = v.pipe(
  v.string(),
  actions.wrappers.set(['card']),
  actions.attributes.top.set({ id: 'my-card' }), // id 设在 card wrapper 上
  actions.attributes.top.patch({ 'data-role': 'field-card' }),
);
特性 inputs attributes
作用目标 组件的 @Input() 属性 HTML 原生 attribute
用法 actions.inputs.set({ placeholder: '...' }) actions.attributes.set({ 'data-testid': '...' })
绑定方式 Angular 属性绑定 [inputName] HTML 属性直接设置
适用场景 组件间数据传递 DOM 属性、ARIA 标签、自定义 data-*
import * as v from 'valibot';
import { actions, setComponent } from '@piying/view-angular-core';

const schema = v.object({
  username: v.pipe(
    v.string(),
    setComponent('input'),
    
    // 组件输入属性
    actions.inputs.set({
      label: '用户名',
      placeholder: '请输入 2-20 个字符',
    }),

    // HTML attributes
    actions.attributes.set({
      'data-testid': 'username-input',
      'aria-required': 'true',
      autocomplete: 'username',
    }),
  ),

  email: v.pipe(
    v.string(),
    setComponent('input'),
    actions.inputs.set({ type: 'email' }),
    actions.attributes.set({
      'aria-label': '邮箱地址',
    }),
  ),
});