How ? Basic, add your Html Implement RxJS from Scratch Fetch html files, Generate components Router and Pages Exemple Repo github
어때요? 그래서 Angular, Vue, React 등 현재 프레임워크에서 일한 적이 있습니다. 한 페이지의 프로그램을 구축하고 싶습니다. 하지만 이번에는 자신에게 도전하고 스트라이크부터 구축하고 싶고, 그게 모자라면 자신의 RXJ를 실현하고 싶다. 여기서 우리는 어떻게 간단하고 효과적으로 이 점을 할 수 있는지 보게 될 것이다. 따라서 자바스크립트, Html, Css, nodejs를 사용하여 실시간 리셋을 진행할 것입니다 원하는 경우 HTML Custom Elements
기본, 당신의 Html 추가
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>Exemple</title>
</head>
<body>
<my-header></my-header>
<div id="app"></div>
<my-footer></my-footer>
</body>
<script type="module" src="./index.js"></script>
<link rel="stylesheet" href="./styles/index.css" />
</html>
<script type="module" src="./index.js"></script>
스크립트를 가져오는 모듈처럼 가져오기 때문에, js 파일에서 'import {}from./any. js' 가 있는 js 파일을 가져옵니다.
<my-header></my-header>
<my-footer></my-footer>
<div id="app"></div>
이것은 우리가 단일 응용 프로그램 보기에 사용할 용기입니다. 이 사용자 정의 요소들은 아직 정의되지 않았습니다. 나중에 'my -' 를 자신의 이름으로 바꿀 수 있습니다.
RxJS를 처음부터 구현 이 부분에 대해서 우리는 감사하다고 말할 수 있다. 우리는 더욱 가벼운 버전을 사용할 것이다 그래서 만약 당신이 우리 자신의 RxJS를 실현하고 싶다면, 우리는Subscriptions 클래스부터 시작해야 한다. 이것은 함수를 포함하는 용기이며, 낡은 함수를 포함한다.unsubscribe 방법을 호출할 때, 그 중의 모든 함수를 호출합니다.
// a container for functions
class Subscription {
constructor() {
this.teardowns = [];
}
add(teardown) {
this.teardowns.push(teardown);
}
unsubscribe() {
this.teardowns.forEach((teardown) => teardown());
this.teardowns = [];
}
}
파이프를 띤 산자 합성pipe 의 개념이 간단하면 n 함수를 결합시켜 마지막 함수의 출력으로 모든 함수를 호출한다. 이것이 바로 우리가 관측 가능한 데이터를 연결해야 하는 논리이다pipe 방법은 또 다른 관측 가능한 데이터를 되돌려줄 것이다.
const pipe = (...fns) => (val) => fns.reduce((acc, f) => f(acc), val);
pipe 에 대해서도 우리는 하나의 유형으로 관찰할 수 있는 추상을 실현해야 한다. 우리가 그것을 초기화할 때, 이 클래스는 매개 변수initFunc 가 필요하기 때문에subscribe 함수를 사용하여 관찰자를 매개 변수로 호출할 것이다initFunc .
const pipe = (...fns) => (val) => fns.reduce((acc, f) => f(acc), val);
class Observable {
constructor(initFunc) {
this.initFunc = initFunc;
}
subscribe(observer) {
const subscription = new Subscription();
const subscriber = new Subscriber(observer, subscription);
const teardown = this.initFunc(subscriber);
subscription.add(teardown);
return subscription;
}
pipe(...fns) {
// provide source Obx to each function returned from pipeable operators,
// to start the chaining operation provide the current source Obx (this)
return pipe(...fns)(this);
}
}
마지막으로 우리는 유사한 대리 대상을 실현해야 한다. Subscriber 류의 역할은 complete 를 호출할 때 사건이 포장된 관찰자에게 전파되는 것을 멈추는 것이다.
// a safe wrapper around observers
export default class Subscriber {
constructor(_observer, _subscription) {
this.observer = _observer;
this.closed = false;
this.subscription = _subscription;
// 1. add an Observer completion logic to the Subscription container
this.subscription.add(() => (this.closed = true)); // <- first function inside the subscription
}
next(value) {
if (!this.closed) {
this.observer.next(value);
}
}
error(err) {
if (!this.closed) {
this.closed = true;
this.observer.error(err);
// 2. enable the Subscriber to call `unsubscribe` on completion
this.subscription.unsubscribe(); // <- unsubscribe on error
}
}
complete() {
if (!this.closed) {
this.closed = true;
this.observer.complete();
this.subscription.unsubscribe(); // <- unsubscribe on completion
}
}
}
html 파일 가져오기|구성 요소 생성 리콜 파트에 오신 걸 환영합니다!우리는 로컬에서 사용하기 때문에 어떠한 의존 관계도 없기 때문에 html 파일을 스스로 가져와야 한다.아니오, import * as htmlTemplate from './template.html 처럼 가져올 수 없습니다. 근데 그거 알아요?이제 우리는 자신의 RXJ를 실현했고 약속이 아니라 관찰할 수 있는 것을 사용할 수 있다. 우리는 _fetchLocal 파일에 api.js 라는 방법을 만들어서 새로운 Observable 와 요청 값을 되돌릴 수 있습니다._fetchLocal 는 가져올 html 파일의 경로와 이름을 사용합니다.따라서 동일한 기능을 가진 페이지와 구성 요소를 가져올 수 있습니다.
import Observable from "./../reactive/Observable.js";
export const _fetchLocal = (path, file) => {
return new Observable((observer) => {
const req = new XMLHttpRequest();
const url = `${path}/${file}`;
req.responseType = "text/html";
req.open("GET", url);
req.send();
req.onloadend = (e) => {
observer.next(req);
};
});
};
현재 dom.js 파일을 만들고 registerComponent 함수를 넣을 수 있습니다. 이 함수는 구성 요소 클래스를 매개 변수로 합니다. 이 함수에서 구성 요소나 페이지를 위한 이름 약정을 설정할 수 있습니다. (논리를 이 함수에 마음대로 추가할 수 있습니다.)
export const registerComponent = (componentClass) => {
const componentName = `my-${componentClass.name.toLowerCase()}`;
customElements.define(componentName, componentClass);
};
이제 우리는 당신의 기반이 생겨서 더욱 쉽게 일을 시작할 수 있습니다. 우리는 Components 폴더를 만들고 우리의 첫 번째 Components를 만들 수 있습니다. 꼬리와 꼬리를 위한 파일 ((Footer.html , Footer.js , Header.html , Header.js 을 만듭니다. Custom Elements 을 사용하는 것을 잊지 마십시오. 따라서 이 예에서 클래스를 HTMLElement 로 확장합니다. 구조 함수에서 우리는 _fetchLocal 방법을 사용하여 관련 템플릿을 얻는다.
<!-- footer -->
<div class="footer">
Hey footer
</div>
import { _fetchLocal } from "./../scripts/api/index.js";
// Footer
export default class Footer extends HTMLElement {
constructor() {
super();
_fetchLocal("/components", "Footer.html").subscribe({
next: (data) => {
this.innerHTML = data.response;
},
});
}
}
<!-- header -->
<div class="flex-row">
<nav class="nav">
<a href="/" class="nav__link" data-link>Home</a>
<a href="/dashboard" class="nav__link" data-link>Dashboard</a>
<a href="/thispagedontexist" class="nav__link" data-link
>This page don't exist</a
>
</nav>
</div>
// Header
export default class Header extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
_fetchLocal("/components", "Header.html").subscribe({
next: (data) => {
this.innerHTML = data.response;
},
});
}
}
그래서 지금 우리는 우리의 구성 요소를 등록해야 한다. 주로js에서 define 방법을 만듭니다. 모든 구성 요소를 등록하기 위해서 registerComponent 사용합니다.define 방법을 init 함수에 넣다.
import Header from "./../components/Header.js";
import Footer from "./../components/Footer.js";
import { _fetchLocal } from "./api/index.js";
import { registerComponent } from "./dom/index.js";
export function init() {
define();
}
function define() {
registerComponent(Header);
registerComponent(Footer);
}
및 라우터 페이지 우리는 반응 논리가 생겨서, 우리의 구성 요소가 응용 프로그램에 의해 다시 식별되었고, 현재 우리는 공격Router 과Pages 를 할 수 있다. 우리는 페이지를 위한 파일을 만들 수 있는 구성 요소처럼 구성 요소 논리를 존중합니다. 그래서 우리는 404, Dashboard, Home에 pages 폴더의 파일을 만들 수 있다.( 404.html , 404.js , Dashboard.html , Dashboard.js , Home.html , Home.js )
<!-- 404 -->
<div class="404">
<div>Are you lost ?</div>
</div>
import { _fetchLocal } from "./../scripts/api/index.js";
export default class NotFound extends HTMLElement {
constructor() {
super();
_fetchLocal("/components", "404.html").subscribe({
next: (data) => {
this.innerHTML = data.response;
},
});
}
}
<!-- Dashboard -->
<div class="dashboard">
<div>this is dashboard</div>
</div>
import { _fetchLocal } from "./../scripts/api/index.js";
export default class Dashboard extends HTMLElement {
constructor() {
super();
_fetchLocal("/components", "Dashboard.html").subscribe({
next: (data) => {
this.innerHTML = data.response;
},
});
}
}
<!-- Home -->
<div class="home">
<div>this is home</div>
</div>
import { _fetchLocal } from "./../scripts/api/index.js";
export default class Home extends HTMLElement {
constructor() {
super();
_fetchLocal("/components", "Home.html").subscribe({
next: (data) => {
this.innerHTML = data.response;
},
});
}
}
따라서 router 폴더와 index.js 파일을 만듭니다. 저희 index.js 파일에서 루트 논리를 androutes 대상에 넣고 path 와 component 를 키로 사용할 수 있습니다. 이렇게:
export const routes = [
{ path: "/", component: "Home" },
{ path: "/dashboard", component: "Dashboard" },
{ path: "/home", component: "Home" },
{ path: "/404", component: "404" },
];
현재 우리는 Views 클래스가 필요합니다. 그러면 보기에서 제공하는 가져오기 HTML 를 #app 용기에 설정할 수 있습니다. 구조 함수에서 사용자 위치 경로 이름을 가져와 저희routes 의 경로와 비교합니다. 일치하지 않으면 404페이지를 표시합니다.getHtml 방법은 _fetchLocal 의 결과를 되돌려주고setView 방법은 획득한 html을 #app 용기에 넣는다.
import { routes } from "./../router/index.js";
import { _fetchLocal } from "./../api/index.js";
export default class Views {
layout;
constructor() {
this.layout = routes.filter((route) => {
return route.path === location.pathname;
})[0] || { component: "404" };
this.getHtml().subscribe({ next: this.setView });
}
getHtml() {
return _fetchLocal("/pages", `${this.layout.component}.html`);
}
setView(data) {
document.querySelector("#app").innerHTML = data.response;
}
}
main.js 파일을 되돌려줍니다. Views 함수에서 define 클래스를 호출하는 실례입니다.
import Header from "./../components/Header.js";
import Footer from "./../components/Footer.js";
import { _fetchLocal } from "./api/index.js";
import { registerComponent } from "./dom/index.js";
import Views from "./dom/views.js";
export function init() {
define();
}
function define() {
registerComponent(Header);
registerComponent(Footer);
new Views();
}
프레젠테이션에 대해 css를 추가할 수 있습니다. 자동 크기와 가운데 배치에 다음과 같은 내용을 추가할 수 있습니다.
html,
body {
height: 100%;
width: auto;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
}
/* reset all */
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
a {
padding: 0.25em;
}
#app {
display: flex;
flex-grow: 1;
align-items: center;
align-self: center;
}
예제 현재 우리는 이 온라인 예시를 통해 우리의 결과를 볼 수 있다.보시다시피 저희 Header , 저희 Footer , 그리고 #app 용기의 레이아웃은 저희 공유기 논리를 사용하고 요청한 page 를 표시합니다.우리의 단일 페이지 응용 프로그램은 만들어진 것이고 수동적인 것이다. 모든 것이 매우 좋다. 모든 독자들에게 감사 드립니다. 만약 당신이 끝까지 용기를 가지고 서 있다면.
Repo github
NOPR9D
/
htmljs 단일 응용 프로그램 rx
0부터 의존 관계가 없다.공유기가 생겼어요...
RxJS가 포함된 단일 어플리케이션|의존성 없음 다음 네트워크 프로젝트에서 경반응 시작 프로그램을 사용하십시오.🚀 View on GitHub |