stencil js,将数组作为自定义元素中的属性值传递

stencil js, pass an array as attribute value in custom element

我正在寻找一种方法来将数组作为使用 stencil js 制作的 Web 组件的属性值进行传递。这可能吗?

我正在尝试让这样的东西起作用!

index.html

<mv-select options=['one','two','three']></mv-select>

mv-select.tsx

@Component({
  tag: 'mv-select',
  styleUrl: 'mv-select.scss',
  assetsDirs: ['assets'],
    shadow: true
})
export class MvSelect {
  @Element() private element: HTMLElement;
  @Prop() options: string[];

写在代理后面。所以你可以直接在对象中赋值。

// 样本:

var cmp = document.querySelector('my-comp');
cmp.data = arr; // arr is the array you are want to pass

//其他Way:Pass作为数据串解析

export class TodoList {
  @Prop() name: string = 'Stencil';

  @Watch('name')
  validateName(newValue: string, oldValue: string) {
    const isBlank = typeof newValue == null;
    const has2chars = typeof newValue === 'string' && newValue.length >= 2;
    if (isBlank) { throw new Error('name: required') };
    if (!has2chars) { throw new Error('name: has2chars') };
  }
}

Ref:

  1. https://stenciljs.com/docs/properties#prop-decorator

  2. https://medium.com/@gilfink/using-complex-objects-arrays-as-props-in-stencil-components-f2d54b093e85

问题是HTML属性只能是字符串,不能是数组或对象。传一个数组有a couple ways个:

  1. 将其作为 属性:
  2. 传递
document.querySelector('mv-select').options = ['one', 'two', 'three'];
  1. 将其作为 JSON 编码字符串属性传递:
<mv-select options='["one", "two", "three"]'></mv-select>

要将 JSON 转换为数组,您可以使用 @Watch 方法更新内部 @State 属性:

export class MvSelect {
  @Prop() options: string;
  @State() internalOptions: string[];

  componentWillLoad() {
    this.parseOptions();
  }

  @Watch('options')
  parseOptions() {
    if (this.options) {
      this.innerOptions = JSON.parse(this.options);
    }
  }
}

此代码确保每当您更改 options 时,它都会被 JSON 解析,并且您可以将 innerOptions 用作数组。

请注意,您必须在 componentWillLoad 中手动调用 this.parseOptions(),因为在初始化时不会调用观察者。

你说的一切都是准确的,在 HTML 属性中只能是字符串,为什么数组属性不能按预期工作(在 Vue 中)... 但是,我们可以像那样应用通用解决方案;

function stringToArray<T>(arg: T[] | string): T[] {
  const opts = typeof arg === 'string'
    ? (arg as string)
        .split(',')
        .map(p => +p.trim())
        .filter(hasValue)
    : arg;

  return opts as T[];
}

而且,我们还应该使用相关的 属性 和 stringtoArray 函数,例如,

stringToArray<number>(options) // if options = [10,20,30]
stringToArray<string>(options) // if options = ['one','two',tree']
stringToArray<Date>(options)  // if option = [new Date.now(),new Date.now().addDay(1)

您可以对所有数组类型使用此函数