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:
问题是HTML属性只能是字符串,不能是数组或对象。传一个数组有a couple ways个:
- 将其作为 属性:
传递
document.querySelector('mv-select').options = ['one', 'two', 'three'];
- 将其作为 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)
您可以对所有数组类型使用此函数
我正在寻找一种方法来将数组作为使用 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:
问题是HTML属性只能是字符串,不能是数组或对象。传一个数组有a couple ways个:
- 将其作为 属性: 传递
document.querySelector('mv-select').options = ['one', 'two', 'three'];
- 将其作为 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)
您可以对所有数组类型使用此函数