JavaScript >> Javascript 文檔 >  >> JavaScript

在 Rails 5 中使用 Angular

你以前聽過這個故事。您已經有一個應用程序在您的去中心化且功能齊全的後端 API 上運行,以及一個使用任何普通工具集製作的前端。

現在,您想繼續使用 Angular。或者,也許您只是在尋找一種將 Angular 與 Rails 項目集成的方法,因為您更喜歡這種方式。我們不怪你。

通過這種方法,您可以利用這兩個世界並決定是否要使用 Rails 或 Angular 的功能來格式化內容。

我們將構建什麼

沒有必要擔心。本教程就是為此目的而編寫的。我們將深入研究如何在一個用戶域上創建一個功能齊全的 CRUD 應用程序。

在文章的最後,您將了解一些關於 Angular 的基本概念,以及如何為前端建立一個直接與 Angular 集成的 Rails 後端項目,如下所示:

使用 Rails 和 Angular 製作的用戶的 CRUD

該應用程序將處理從外部偽造測試 Web 服務檢索到的用戶域上的所有四個 CRUD 操作。該應用程序將構建在 MVC 架構之上,每個 Angular 層都進行了詳細解釋,以幫助您更好地了解事物是如何联系在一起的。樣式由 Bootstrap 決定。

設置

您可能已經猜到了,我們將需要以下軟件:

  • Ruby(我選擇了 2.7.0preview1 版本),
  • Ruby 和 Rails(我使用的是 5.0.7.2 版),
  • Node.js(我將使用 v13.7.0),
  • Yarn(至少是 1.22.4 版)

確保正確安裝所有內容。然後,我們可以繼續進行項目。選擇您喜歡的文件夾並運行以下命令:

rails new crud-rails-angular

等待設置完成並在您喜歡的 IDE 中打開項目。我們將在本文中使用 VS Code,因為它簡單、強大,並且可以順利地包含 Rails 和 Angular 語法。

如果您已經使用 Rails 5 一段時間,您可能已經註意到它的 new 命令在 Gemfile 中生成一個錯誤 對於 SQLite 配置。它沒有最低版本,這將使它運行時出錯。讓我們通過更新來解決這個問題

gem 'sqlite3', '~> 1.3.10'

完美!

Webpacker 設置

在 Rails 中管理類 JavaScript 應用程序的最佳方式是通過 Webpacker。它在後台使用 Webpack 提供功能,例如預處理和將 JavaScript 應用程序(如 Angular)捆綁到現有的 Rails 應用程序中。

要安裝它,只需在您的 Gemfile 中添加一個新行 :

gem 'webpacker', '~> 4.3.x'

這將確保您將安裝最新版本。接下來,運行以下命令:

bundle install
bundle exec rake webpacker:install
bundle exec rake webpacker:install:angular

第一個命令將下載並更新添加的 Rails 依賴項。

第二個相當於npm install 因為它創建了 node_modules 文件夾並安裝一堆必需的 Angular 依賴項,例如 Babel、Sass、Browserlist 和 Webpack。現在,我們在同一個項目中同時擁有 Node 和 Rails 應用。

在最新的命令中,我們有 npm install angular 的等價物 ,它將下載所有 Angular 所需的依賴項,並使其與我們的 Rails 項目一起工作。

在這些命令的末尾,您還可以看到 package.json 創建的文件。我們所有需要的依賴都放在那裡,你可以在以後添加任何你需要的。

此外,在 /app 下創建了一些文件夾和文件 文件夾,例如新的 /javascript .在這個文件夾中,你已經有一個 /hello_angular 為支持開始開發而創建的文件夾。

為了爭取一些時間,我會要求您使用以下鏡像來鏡像您的文件夾和文件結構:

一些角度調整

Webpacker 建議在您生成的 Rails 項目中進行一系列調整。所以,讓我們花點時間整理一下房子吧。

首先,打開你的 application.js /packs 下的文件 文件夾(如上圖所示)並添加以下代碼:

import "core-js/stable";
import "regenerator-runtime/runtime";

這些導入作為穩定 Rails 項目中 JavaScript 環境的輔助力量。

現在,我們需要通知 Rails 它必須從哪裡選擇輸出到它的頁面。一旦 Webpacker 完成打包,它會生成一堆 Rails 必須注意的可分發靜態文件。

轉到 application.html.erb app/views/layout 下的文件 文件夾並更改其 <head> 標記內容如下:

<head>
  <title>CrudRailsAngular</title>
  <base href="/" />
  <!-- 1 -->
  <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
  <!-- 2 -->
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application' %>
  <!-- 3 -->
</head>

讓我們分解一下:

  1. 在這裡,我們添加 base 標記,它告訴 Rails 應用程序啟動時到哪裡查看。
  2. 我們將使用 Bootstrap 來推斷頁面的樣式,因此我們可以只專注於實現。
  3. 這裡是你必須放置映射到 /packs 的 Webpacker 標籤的地方 文件夾內容(與每次編譯後由 Webpacker 自動生成的內容相同)。

模型和數據庫

繼續進行數據庫設置。為了讓事情變得更快,我們將構建一個名為 User 的新模型 .這是實現它必須運行的命令:

rails g scaffold User name:string age:integer address:text && rake db:migrate

它將創建我們模型的所有文件夾和文件,我們需要讓 Rails 操作數據庫信息(來自 SQLite)並將其存儲到我們的 CRUD 操作中。

然後,你會看到一個新文件 XXX1_create_users.rbdb/migrate/ 下創建 文件夾。打開它,你會看到新創建的CreateUsers 記錄。

app/models/ 內 文件夾,您將看到當時創建的 User user.rb 中的模型 文件。

現在,打開 db/seeds.rb 文件並添加以下代碼:

User.create(name: 'Luke Wan', age: 23, address: '123 Test St.')
User.create(name: 'Mary Poppins', age: 41, address: '123 ABC St.')
User.create(name: 'John Neilman', age: 76, address: '000 Test St.')

此代碼將初始化我們的 Users 啟動時包含一些數據的表。保存,運行命令:

rake db:seed

這將通過上面列出的命令為表播種。接下來,您可以進入 SQLite 數據庫並通過發出命令檢查是否有效:

sqlite3 db/development.sqlite3

然後,選擇表格數據:

select * from users;

你可能會看到結果。

用戶組件

您將需要安裝更多的依賴項來幫助將 HTML 和 CSS 轉換為我們的 Rails 頁面;添加 Angular 路由器、表單庫和 ngx-bootstrap,我們將使用它們來促進 Bootstrap 組件的創建和操作。所以,發出以下命令:

yarn add @angular/router @angular/forms html-loader css-loader ngx-bootstrap

不過,在我們進入組件代碼之前,我們需要指出一些重要的概念,首先是 Angular 組件的剖析。

什麼是組件?

在 Angular 中,存在一個組件來將您的視圖與 TypeScript 中的應用程序邏輯連接起來。

換句話說,組件就像一個容器,包含您的視圖支持其功能所需的所有邏輯。它定義了視圖將呈現的值並控制它們的流程。它相當於類似框架中的“控制器”。

要創建一個組件,您需要做的就是定義一個新類,實現 OnInit 接口,並使用 @Component 註釋類 裝飾師:

export class UserIndexComponent implements OnInit {
    constructor() { ... }

    ngOnInit() { ... }
}

@Component 和 OnInit

@Component 裝飾器很重要,因為它將此類標記為可識別的 Angular 組件,並提供元數據配置,幫助 Angular 在運行時處理、實例化和使用它們。

採用以下元數據配置:

@Component({
    selector: "users",
    template: templateString,
})

這裡,selector 告訴 Angular 提供的值是 CSS 選擇器,它可以用來將當前指令標識到模板中;是的,它與下一個元數據屬性中提供的模板相同。

OnInit 然而,接口是可選的,它是在組件完成其生命週期之前初始化東西的好方法。它的工作方式類似於構建後的方法。

依賴注入

Angular 是一個 DI(依賴注入 ) 框架,這一特性提高了其模塊化和生產力。

Angular 中的依賴關係可以從您的服務和存儲庫到您認為適合注入代碼中其他位置的任何類型的普通對象。

要使一個類“可注入”,您只需要使用 @Injectable 對其進行註釋 裝飾師:

@Injectable({
    providedIn: "root",
})
export class UserService {
    ...
}

providedIn 指示哪個注入器將提供您正在創建的注入器。 root value 告訴 Angular 注入器應該是應用程序級別的。您可以在此處查看更多內容。

例如,要將類註入到組件中,請讓 Angular 在組件的構造函數中執行此操作:

constructor(
    private userService: UserService,
) {}

就這麼簡單!

成品組件

下面,您可以找到我們的用戶組件的最終代碼清單。將其放入 index.component.ts ,在 javascript/hello_angular/app/ 下 文件夾。

import { Component, OnInit, TemplateRef } from "@angular/core";
import { FormGroup, FormBuilder } from "@angular/forms";
import { BsModalRef, BsModalService } from "ngx-bootstrap/modal";

import templateString from "./index.component.html";
import { UserService } from "../user.service";
import { User } from "../user.class";

@Component({
  selector: "users",
  template: templateString,
})
export class UserIndexComponent implements OnInit {
  users: User[];
  modalRef: BsModalRef;
  userForm: FormGroup;
  isNew: Boolean;

  constructor(public fb: FormBuilder, private userService: UserService, private modalService: BsModalService) {}

  public newUser(template: TemplateRef<any>) {
    this.reset();
    this.modalRef = this.modalService.show(template);
  }

  public createUser() {
    this.userService.create(this.userForm.value).subscribe(() => {
      console.log("User created!");
      this.reset();

      this.modalRef.hide();
    });
  }

  public editUser(user, template: TemplateRef<any>) {
    this.isNew = false;
    this.userForm = this.fb.group({
      id: [user.id],
      name: [user.name],
      age: [user.age],
      address: [user.address],
    });

    this.modalRef = this.modalService.show(template);
  }

  public updateUser() {
    const { id } = this.userForm.value;
    this.userService.update(id, this.userForm.value).subscribe(() => {
      console.log("User updated!");
      this.reset();

      this.modalRef.hide();
    });
  }

  public deleteUser(id) {
    if (confirm("Are you sure?")) {
      this.userService.delete(id).subscribe(() => {
        console.log("User deleted!");
        this.reset();
      });
    }
  }

  ngOnInit() {
    this.reset();
  }

  public reset() {
    this.isNew = true;
    this.userService.getUsers().subscribe((users) => {
      this.users = users;
    });

    this.userForm = this.fb.group({
      id: [""],
      name: [""],
      age: [""],
      address: [""],
    });
  }
}

users 數組將保存屏幕上列出的當前表格數據,並從 reset 中檢索 該方法反過來通過 UserService 調用我們的 Rails API (待創建)。

userForm 只是幫助創建和更新我們的用戶的參考,因為相同的表單將用於兩個操作。 isNew 也有助於確定我們目前所處的流程。

在這裡,我們對每個操作都有一個與 CRUD 等效的方法。他們每個人都調用各自的 UserService 在 Rails API 中提交進程的方法。

我們還需要設置 HTML 模塊以將我們的模板轉換為 HTML(我們很快就會看到更多關於模塊的內容)。所以,打開 html.d.ts 在同一文件夾中的文件並添加:

declare module "*.html" {
  const content: string;
  export default content;
}

Angular 服務和模型

讓我們繼續 Angular 的 UserService 創建。 Angular 是一個框架,就像 Rails 一樣。因此,這意味著即使這意味著有重複(或非常相似)的模型,也可以遵守他們的規則。

什麼是模型?

Angular 模型是簡單的對象,它們將有意義的數據屬性保存在一起(即,它們代表您領域的一個簡潔部分)。它們就像大多數語言和框架中的任何其他模型一樣。

將您的數據集中在一個地方會很有幫助,而不是像我們對用戶模型那樣在整個代碼中復制它:

export class User {
  constructor(public id: number, public name: string, public age: number, public address: string) {}
}

請記住,它是 TypeScript,因此您的模型的屬性必須始終定義類型。

創建一個名為 user.class.ts 的新文件 在 javascript/hello_angular/app/user/ 下 文件夾並將上面的代碼放入其中。

服務怎麼樣?

服務是一個寬泛的概念,但我們可以將它們理解為定義明確且有目的的對象。它們幫助具有更複雜邏輯的組件,為它們提供處理和轉換的數據,通常來自外部服務或數據庫。

服務不需要任何特定的註解或接口;您只需創建一個類並使其可注入 ,正如我們之前所見。然後,您可以將其註入到您的組件中。

可觀察服務

Angular 另一個有趣的特性是它允許你在你的類中使用 RxJS。

例如,Angular 的默認 HTTP 客戶端,也就是我們用來從外部服務獲取信息的客戶端,返回 RxJS Observables .這就是為什麼當您調用我們的任何 UserService 用戶組件中的方法,您可以 subscribeObservable 結果:

this.userService.getUsers().subscribe((users) => {
  this.users = users;
});

請注意,如果您不熟悉 RxJS,我強烈建議您簡要閱讀其文檔;沒那麼難!;)

同樣,在 javascript/hello_angular/app/user/ 文件夾,創建另一個名為 user.service.ts 的文件 .這是它的內容:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { map } from "rxjs/operators";
import { Observable } from "rxjs";

import { User } from "./user.class";

@Injectable({
  providedIn: "root",
})
export class UserService {
  constructor(private http: HttpClient) {}

  httpOptions = {
    headers: new HttpHeaders({
      "Content-Type": "application/json",
    }),
  };

  getUsers(): Observable<User[]> {
    return this.http.get("/users.json").pipe(
      map((users: User[]) =>
        users.map((user) => {
          return new User(user.id, user.name, user.age, user.address);
        })
      )
    );
  }

  create(user): Observable<User> {
    return this.http.post<User>("/users.json", JSON.stringify(user), this.httpOptions);
  }

  update(id, user): Observable<User> {
    return this.http.put<User>("/users/" + id + ".json", JSON.stringify(user), this.httpOptions);
  }

  delete(id) {
    return this.http.delete<User>("/users/" + id + ".json", this.httpOptions);
  }
}

你能發現這個和我們剛剛創建的組件之間的相似之處嗎?這是因為我們需要對應的操作來支持組件中的操作。

請注意,HttpClient 也必須在類的構造函數中註入,所以我們可以在類中使用它。

每個操作都會對自動生成的 Rails API 進行 HTTP 調用。

查看次數

Angular 使用模板作為其視圖。模板是一種分層的 HTML 和 JavaScript 組合,它告訴 Angular 如何渲染每個組件。

不過,在進一步構建我們的視圖之前,讓我們先了解一下 Angular 是如何拆分其模板系統的。

角度指令

因為 Angular 模板本質上是動態的,所以一些 指令 需要通過正確的方式來驅動 Angular 來渲染東西。

指令只是帶有 @Directive 的類 裝飾器,就像組件一樣。是的,@Component 繼承自 @Directive ,所以它也是一個正式的指令。

但是,還有兩種其他類型:結構屬性 指令。

結構指令

這些指令表示從 JavaScript 轉換為 Angular 模板的條件和循環結構。它們有助於使模板盡可能動態化,就像您在原生 JavaScript 代碼中進行編程一樣。舉個例子:

<tr *ngFor="let user of users">
  <td>{{ user.name }}</td>
</tr>

*ngFor 指令告訴 Angular 遍歷 users 的數組 並將每個用戶的名稱打印到 DOM。

屬性指令

這些直接與元素的外觀或行為一起工作。舉個例子:

<form [formGroup]="userForm" (ngSubmit)="isNew ? createUser() : updateUser()" novalidate></form>

在這裡,我們通過有條件地設置它的 submit 來修改表單的行為 功能和使用 Angular 的 FormGroup 對每個表單輸入進行數據綁定。

數據綁定

如果不提供數據綁定,使用 Web 框架創建表單可能是一項棘手且容易出錯的任務。

Angular 支持雙向數據綁定,這意味著您可以將模板的各個部分直接連接到組件,反之亦然。

上面的表格是 FormGroup 的一個很好的例子 數據綁定能力。它自動將每個表單字段綁定到 userForm 在我們的組件中創建的對象。

editUser 方法,例如,您可以看到綁定的相反版本,其中 userForm 的值在組件內設置,並應在視圖上反映表單。

構建索引視圖

讓我們分解 index.component.html 的內容 分成兩部分。這是第一個:

<div class="container pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center">
  <h1 class="display-4">User's Listing</h1>
  <p class="lead">A quick CRUD example of how to integrate Rails with Angular</p>

  <table class="table">
    <tr>
      <th>Id</th>
      <th>Name</th>
      <th>Age</th>
      <th>Address</th>
      <th>Actions</th>
    </tr>

    <tbody>
      <tr *ngFor="let user of users">
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
        <td>{{ user.address }}</td>
        <td colspan="2">
          <button class="btn btn-secondary" (click)="editUser(user, template)">Edit</button>
          |
          <button class="btn btn-danger" (click)="deleteUser(user.id)">Delete</button>
        </td>
      </tr>
    </tbody>
  </table>

  <button class="btn btn-primary float-right mt-4" (click)="newUser(template)">Insert New</button>
</div>

其中大部分由純 HTML 組成。我們不會詳細介紹 Bootstrap 類。

這裡重要的部分是 ngFor 表行上的指令。它有助於迭代 users 數組(還記得嗎?)通過 {{ … }} 將其每個屬性打印到 HTML 輸出 運營商。

每當您想要添加 DOM 事件之一時,例如 onClick ,只需將事件名稱用括號括起來,並添加點擊時會調用的組件函數即可。

構建模態視圖

第二部分與modal內容有關,所以在上一部分下面添加:

<ng-template #template>
  <div class="modal-header">
    <h4 class="modal-title pull-left">{{ isNew ? "New User" : "Update User" }}</h4>
    <button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <form [formGroup]="userForm" (ngSubmit)="isNew ? createUser() : updateUser()" novalidate>
      <input type="hidden" formControlName="id" class="form-control" />
      <div class="form-group">
        <label>Name</label>
        <input type="text" formControlName="name" class="form-control" />
      </div>
      <div class="form-group">
        <label>Age</label>
        <input type="text" formControlName="age" class="form-control" />
      </div>
      <div class="form-group">
        <label>Address</label>
        <textarea class="form-control" formControlName="address" rows="3"></textarea>
      </div>

      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  </div>
</ng-template>

請注意,我們正在使用 <ng-template> 標籤,它允許您在 HTML 和 Angular 之間錨定元素。模板 ID 緊跟在 # 之後 簽到。

在表單中,還要注意我們正在使用 isNew 組件變量來驗證這個表單的當前使用是否與用戶的創建或更新有關。

最後,我們需要注入整個 hello_angular 應用到 Rails index.html.erb 頁。所以,在 views/users/ 下打開這個文件 文件夾並將其內容更改為以下內容:

<hello-angular>We're almost done...</hello-angular> <%= javascript_pack_tag 'hello_angular' %>

Angular 模塊

現在,我們需要告訴 Angular 在哪裡可以找到東西。它發生在其模塊的配置中。

讓我們從向 app-bootstrap.module.ts 添加內容開始 :

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";

import { ModalModule } from "ngx-bootstrap/modal";

@NgModule({
  imports: [CommonModule, ModalModule.forRoot()],
  exports: [ModalModule],
})
export class AppBootstrapModule {}

這僅限於我們從 ngx-bootstrap 繼承的 Bootstrap 組件。我們目前使用的唯一組件是 Bootstrap 模態。

然後,打開 app-routing.module.ts 文件並將其內容更改為以下內容:

import { RouterModule, Routes } from "@angular/router";
import { NgModule } from "@angular/core";

import { UserIndexComponent } from "./user/index/index.component";

const appRoutes: Routes = [
  { path: "users", component: UserIndexComponent },
  { path: "", redirectTo: "/users", pathMatch: "full" },
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { scrollPositionRestoration: "enabled" })],
  exports: [RouterModule],
})
export class AppRoutingModule {}

這將確保 Angular 在 /users 時匹配正確的用戶組件 路徑被調用。

最後,在主 AppModule 中註冊所有這些 班級。打開 app.module.ts 文件並確保它看起來像這樣:

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";

import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app-routing.module";
import { AppBootstrapModule } from "./app-boostrap.module";
import { UserIndexComponent } from "./user/index/index.component";

@NgModule({
  declarations: [AppComponent, UserIndexComponent],
  imports: [HttpClientModule, AppRoutingModule, BrowserModule, FormsModule, ReactiveFormsModule, AppBootstrapModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

在這裡,一切都已映射。從我們的表單、HTTP 客戶端和用戶組件到 Bootstrap 模塊的配置和路由。

完成配置

在開始測試之前,我們需要完成一些工作,從 app.component.ts 開始 文件:

import { Component } from "@angular/core";

@Component({
  selector: "hello-angular",
  template: "<router-outlet></router-outlet>",
})
export class AppComponent {
  name = "Angular!";
}

主應用程序組件需要知道如何路由路徑,因此 RouterOutlet 將完成這項工作。

然後,我們需要確保 Webpacker 理解我們目前正在使用的 HTML 擴展。為此,打開 webpacker.yml 文件,並在 /config 下 文件夾,搜索 extensions 部分並添加以下項目:

- .html

Webpacker 只識別 Angular 默認自帶的內置 TypeScript 加載器。我們需要處理 HTML,這就是我們之前安裝 html-loader 的原因 依賴。要進行設置,請打開 environment.js 文件,在 config/webpack 下 文件夾,並添加以下加載器配置:

environment.loaders.append("html", {
  test: /\.html$/,
  use: [
    {
      loader: "html-loader",
      options: {
        minimize: true,
      },
    },
  ],
});

最後,為了防止我們的 Angular 服務在其 HTTP 調用中接收到錯誤,我們需要禁用 Rails 執行的 CSRF 令牌檢查。為此,打開 application_controller.rb 文件,在 app/controllers 下 文件夾,並將其內容更改為以下內容:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session
end

測試

而已!這看起來有點棘手,因為設置需要大量自定義,但結果是值得的。

通過發出 rails s 來測試、保存所有內容並啟動服務器 命令。

然後,轉到您的 Web 瀏覽器並鍵入地址 http://localhost:3000/users。繼續玩 CRUD Web 應用程序。

結論

讓這個 CRUD 啟動並運行是一條漫長的道路。在第一次試用之後,您會發現您未來的項目變得更容易了。我希望這個項目可以幫助那些想要通過加入這兩個技術來快速啟動項目的人建立一個起點。

雖然我們沒有開源的腳手架項目來幫助它,但我們依靠彼此的努力來獲得這樣的材料。現在輪到你了; fork 項目(或從頭開始創建)並開始進行自定義。

可以在此處找到此示例的 GitHub 存儲庫。玩得開心!


Tutorial JavaScript 教程
  1. 如何僅使用 JavaScript 製作數字掩碼?

  2. 使用 JavaScript 對值進行排序

  3. 在Javascript中模擬window.location.href

  4. 哦,你會戴的帽子

  5. javascript有文字字符串嗎?

  6. 是否有 0b 或類似的東西來表示 Javascript 中的二進制數

  7. 使用 IntersectionObserver API 進行延遲加載

  1. 停止僅使用 console.log 並使用內置節點調試器

  2. superplate - 具有流行工具的面向性能的前端應用程序創建者

  3. ReactJS:在 ReactJS 中使用閉包之前需要考慮的事項

  4. tsParticles 1.13.2

  5. Vue 3 提示/檢測外部點擊

  6. 投資組合 V1

  7. React &React Native:2021 年 10 月成為主流

  1. 餘燼時報 - 第 147 期

  2. Express API 的單元測試要點:分步指南

  3. 生成器函數 JavaScript(Redux Saga 異步 Api 調用中的示例和用法)

  4. 身份驗證令牌管理