我正在用 Stencil 编写我的第一个 Web 组件。
这是此处发布的药丸组件:https ://github.com/reservoir-dogs/rp-pills
组件代码:
import { Component, Prop, Watch, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'rp-pills',
styleUrl: 'rp-pills.scss',
shadow: false
})
export class RpPills {
@Prop() items: any[] = [];
@Prop() displayProperty: string;
@Prop({ mutable: true }) value: any;
@Prop() class: string;
@Prop() theme: string = 'default';
@Prop() emptyMessage: string = 'No item';
classes: string;
@Event() valueChange: EventEmitter;
onClick(item: any) {
this.value = item;
this.valueChange.emit(this.value);
}
@Watch('class')
@Watch('theme')
watchHandler() {
this.classes = `nav nav-pills ${this.theme} ${this.class}`;
}
render() {
if (this.items.length > 0)
return (
<ul class={this.classes}>
{this.items.map((item) =>
<li onClick={() => this.onClick(item)} class={this.value === item ? 'active' : ''} >
<a>{item[this.displayProperty]}</a>
</li>)}
</ul>
);
else
return (
<ul class={this.classes}>
<li class="empty">
<a>{this.emptyMessage}</a>
</li>
</ul>
);
}
}
这个测试工作正常:
it('should work with a list of items and selected item', async () => {
const cmp = new RpPills();
cmp.valueChange = {
emit: () => { }
};
const spy = jest.spyOn(cmp.valueChange, 'emit');
cmp.onClick({name:'Coucou'});
expect(spy).toHaveBeenCalledWith({ name: 'Coucou' });
});
但是我的 HTML 示例和 Ionic App 中的集成不起作用并返回以下消息:{"isTrusted":false}
HTML 示例:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
<title>Stencil Component Starter</title>
<script src="/build/rppills.js"></script>
</head>
<style>
.orange .active a {
background-color: #ff0000;
}
.orange a {
background-color: #ff6a00;
}
div {
float: left;
clear: both;
}
</style>
<body>
<div>
<rp-pills display-property="name" class="nav-pills-bordered" theme="orange">
</rp-pills>
<span></span>
</div>
<div>
<rp-pills display-property="name" class="nav-justified">
</rp-pills>
<span></span>
</div>
<div>
<rp-pills display-property="name" class="nav-pills-bordered nav-justified">
</rp-pills>
<span></span>
</div>
<div>
<rp-pills class="nav-pills-bordered">
</rp-pills>
<span></span>
</div>
<div>
<rp-pills empty-message="Aucun message" class="nav-pills-bordered">
</rp-pills>
<span></span>
</div>
<div>
<rp-pills>
</rp-pills>
<span></span>
</div>
<script>
var cmps = document.querySelectorAll('rp-pills');
for (var i = 0; i < cmps.length; i++) {
var cmp = cmps[i];
if (cmp.attributes.length > 0 && cmp.attributes[0].name == 'display-property') {
cmp.value = { 'name': 'Coucou' };
cmp.items = [cmp.value, { 'name': 'Comment ca va ?' }, { 'name': 'Au revoir' }];
cmp.addEventListener('valueChange', (event) => { alert(JSON.stringify(event)); });
}
}
setInterval(() => {
var cmps = document.querySelectorAll('rp-pills');
var spans = document.querySelectorAll('span');
for (var i = 0; i < cmps.length; i++) {
if (cmps[i].value != undefined)
spans[i].innerText = cmps[i].value.name;
}
}, 1000);
</script>
</body>
</html>