LitElement 및 TypeScript를 사용한 웹 구성 요소 통합
9197 단어 litelementtypescript
웹 구성 요소 생성에 대해 자세히 살펴보고 이를 재사용하고 속성 변경에 응답하고 사용자 지정 이벤트를 전달하는 방법을 이해하겠습니다.
웹 구성 요소 작성
웹 애플리케이션의 모든 블로그 게시물에 대한 개요를 표시하는 기본 템플릿을 정의해 보겠습니다.
<div class="blog-card">
<div class="blog-description">
<h1>Title</h1>
<h2>Author</h2>
<p>
Brief Description
</p>
<p class="blog-footer">
<a class="blog-link">Read More</a>
</p>
</div>
</div>
이 템플릿을 사용하면 게시물 콘텐츠를 표시하기 위해 간단한 카드를 그릴 수 있습니다. 새 구성 요소의 내부 DOM을 정의합니다.
LitElement 및
@customElement
데코레이터를 사용하여 웹 구성 요소를 만들어 보겠습니다.// blog-card.ts
import { LitElement, html, customElement, css } from 'lit-element';
import { Post } from './post';
@customElement('blog-card')
export class BlogCard extends LitElement {
static styles = css`
.blog-card {
margin: 20px;
display: flex;
flex-direction: column;
margin-bottom: 15px;
background: white;
border-radius: 5px;
overflow: hidden;
border-radius: 10px;
}
.blog-description {
padding: 20px;
background: white;
}
.blog-footer {
text-align: right;
}
.blog-link {
color: #008cba;
}
h1 {
margin: 0;
font-size: 1.5rem;
}
h2 {
font-size: 1rem;
font-weight: 300;
color: #5e5e5e;
margin-top: 5px;
}
`;
render() {
return html`
<div class="blog-card">
<div class="blog-description">
<h1>Title</h1>
<h2>Author</h2>
<p>
Brief Description
</p>
<p class="blog-footer">
<a class="blog-link">Read More</a>
</p>
</div>
</div>
`;
}
}
이 구성 요소는 렌더링할 준비가 되었습니다. 그러나 내용은 항상 동일하므로 재사용할 수 없습니다. 각 인스턴스에 대해 다른 콘텐츠를 표시할 수 있도록 이 구성 요소를 구성하는 방법이 필요합니다(이상적이어야 합니다. 맞습니까?).
속성 추가
요소의 속성을 선언하는 TypeScript 방식은 다음과 같습니다.
// blog-card.ts
@customElement('blog-card')
export class BlogCard extends LitElement {
@property({ type: String }) postTitle?: string;
@property({ type: String }) author?: string;
@property({ type: String }) description?: string;
}
새 구성 요소를 구성하고 블로그 게시물의 개요를 표시할 수 있을 것 같습니다. 그러나 다른 속성을 추가하기로 결정하면 어떻게 될까요? 속성 목록의 수가 증가할 것이며 이 시나리오를 처리하는 최선의 방법이 아닐 수도 있습니다.
다른 옵션은 TypeScript 인터페이스를 통해
Post
모델을 정의하는 것입니다.// post.ts
export interface Post {
id: number;
title: string;
author: string;
description: string;
}
그런 다음 Post 개체를 예상하는 단일 속성을 정의해 보겠습니다.
// blog-card.ts
@customElement('blog-card')
export class BlogCard extends LitElement {
@property({ type: Object }) post?: Post;
}
바인딩 속성
render
기능을 개선하고 템플릿에 속성 바인딩을 생성할 때입니다.// blog-card.ts
render() {
return html`
<div class="blog-card">
<div class="blog-description">
<h1>${this.post?.title}</h1>
<h2>${this.post?.author}</h2>
<p>
${this.post?.description}
</p>
<p class="blog-footer">
<a class="blog-link">Read More</a>
</p>
</div>
</div>
`;
}
@property
선언(이전에 정의됨)은 지정된 속성이 변경될 때마다 템플릿을 렌더링합니다.이벤트 추가
웹 구성 요소에 대한 이벤트 리스너를 추가하는 방법에는 여러 가지가 있습니다. 이 경우
@event
표기법을 사용하여 선언적 이벤트 리스너를 사용할 수 있습니다. render() {
return html`
<div class="blog-card">
<div class="blog-description">
<h1>${this.post?.title}</h1>
<h2>${this.post?.author}</h2>
<p>
${this.post?.description}
</p>
<p class="blog-footer">
<a class="blog-link" @click="${this.handleClick}">Read More</a>
</p>
</div>
</div>
`;
}
private handleClick() {
this.dispatchEvent(
new CustomEvent('readMore', { detail: this.post })
);
}
템플릿이 브라우저에서 렌더링되면 이벤트 리스너
@click="${this.handleClick}"
가 추가됩니다. 클릭 동작은 handleClick
함수에 의해 처리됩니다.이 함수는 Lit 기반 웹 구성요소에서 이벤트를 발생시킵니다.
CustomEvent
를 사용하면 개체Post
가 함께 전파될 수 있습니다.부모-자식 구성 요소 통신
blog-card
구성 요소를 응용 프로그램에 통합할 준비가 되었습니다.블로그 게시물 페이지를 부모로, 블로그 카드를 자식 구성 요소로 생각해 봅시다.
// blog-posts.ts
import { POSTS } from './data';
import { Post } from './post';
@customElement('lit-blog-posts')
export class BlogPosts extends LitElement {
@property({ type: Array }) blogPosts?: Post[];
constructor() {
super();
}
render() {
return html`
<h2>Blog Posts</h2>
${this.blogPosts?.map(
post => html`<blog-card .post="${post}"></blog-card>`
)}
`;
}
firstUpdated() {
this.blogPosts = POSTS;
}
}
상위 구성 요소는
@property({ type: Array }) blogPosts?: Post[];
를 사용하여 블로그 게시물 세트를 저장하는 속성을 정의합니다.웹 구성 요소 템플릿이 있고 속성을 바인딩하려는 경우 다음 규칙을 고려하십시오.
<p>${...}</p>
<p id="${...}"></p>
?disabled="${...}"
.value="${...}"
@event="${...}"
firstUpdated 함수는 요소의 DOM이 처음 업데이트된 후에 호출됩니다. 실제 시나리오에서 앱은 데이터를 가져오기 위해 HTTP 호출을 수행해야 합니다.
이 예에서는
data.ts
파일에서 데이터를 로드해 보겠습니다.// data.ts
import { Post } from './post';
export const POSTS: Post[] = [
{
id: 0,
title: 'Web Components Introduction',
author: 'Luis Aviles',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
},
{
id: 1,
title: 'LitElement with TypeScript',
author: 'Luis Aviles',
description:
'Sed felis nisi, consectetur sed ipsum dignissim, semper porta risus...',
},
{
id: 2,
title: 'Navigation and Routing with Web Components',
author: 'Luis Aviles',
description:
'Ut ipsum arcu, sodales aliquet nisi iaculis, faucibus varius mauris...',
},
];
하위 이벤트 듣기
상위 구성 요소가 블로그 게시물을 표시할 준비가 되었습니다. 그러나 "자세히 보기"링크를 클릭할 때마다 듣고 블로그 게시물 페이지에서 제어할 수 있다면 좋을 것입니다.
// blog-posts.ts
firstUpdated() {
this.blogPosts = POSTS;
this.addEventListener('readMore', event => {
const post = (event as CustomEvent).detail as Post; //event.detail has a the Post object
Router.go(`/blog/posts/${post.id}`); // Get the Post id and redirect
});
}
이벤트 리스너는 첫 번째 페인트 후에 실행됩니다. 이러한 추가 방법은 여러 수신기를 추가할 때 유용할 수 있습니다.
최종 결과는 다음과 같습니다.
소스 코드 프로젝트
이 GitHub 저장소에서 전체 프로젝트를 찾으십시오: https://github.com/luixaviles/litelement-website . 별표 ⭐️를 주고 코드를 가지고 놀아보는 것을 잊지 마세요.
내 작업에 대해 더 보려면 및 GitHub에서 나를 팔로우할 수 있습니다.
Reference
이 문제에 관하여(LitElement 및 TypeScript를 사용한 웹 구성 요소 통합), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thisdotmedia_staff/web-components-integration-using-litelement-and-typescript-2jbo텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)