摘要:我們的應(yīng)用由一個(gè)或者多個(gè)模塊組成,并且必須要有一個(gè)根模塊,我們通常命名為,每個(gè)模塊都會有一個(gè)叫的裝飾器函數(shù),它接收一個(gè)用來描述模塊屬性的元數(shù)據(jù)對象,我們在這個(gè)對象屬性上配置我們應(yīng)用所需的組件路由指令管道服務(wù)等。
前言
相信大家在逛技術(shù)論壇或者技術(shù)博客的時(shí)候,都會發(fā)現(xiàn)有些寫的很好的文章我們想保存下來以便可以重復(fù)翻閱和查看,在一些相對大的站點(diǎn),比如SegmentFault或者掘金都會提供類似收藏這樣的功能來幫我們做這個(gè)保存的工作,我們以后可以回來重復(fù)查看,但是我們平時(shí)瀏覽的站點(diǎn)肯定不止一個(gè),并且有時(shí)候一些個(gè)人的技術(shù)博客并沒有這樣的功能,我們就只能存瀏覽器書簽這樣做了,這樣我們平時(shí)保存下來的一些文章就會比較分散,沒有一個(gè)統(tǒng)一的地方來幫我們管理,如果有這樣一個(gè)應(yīng)用,我們只要輸入某篇我們想保存的文章的URL地址就可以幫我們生成這篇文章的正文內(nèi)容,并且可以支持標(biāo)簽的分類和搜索等功能就好了,就是基于這個(gè)需求和我平時(shí)個(gè)人的使用經(jīng)驗(yàn)開發(fā)出了這個(gè)應(yīng)用。大家可以進(jìn)這個(gè)地址先體驗(yàn)一下,賬號是test,密碼123456。該應(yīng)用采用Angular4開發(fā),koa2提供數(shù)據(jù)接口,因?yàn)槲沂茿ngular的初學(xué)者,邊看官方文檔邊把這個(gè)應(yīng)用做了出來的,也遇到了一些問題,下面我大概說一下開發(fā)的過程和遇到的一些問題的解決方案。技術(shù)方案選型如下
Angular 前端框架
Angular Cli 前端打包構(gòu)建
koa2 提供數(shù)據(jù)接口
MongoDB 提供數(shù)據(jù)儲存
phantom 和 node-readability 提供對文章正文的提取
一、項(xiàng)目的初始化Angular是一個(gè)正式發(fā)布于16年九月的一個(gè)前端框架(其實(shí)Angular的定位是一個(gè)平臺了),它和vue、react不太一樣的是,Angular不只是針對視圖層的一個(gè)庫,它提供的是一個(gè)完整的解決方案和生態(tài),它本身內(nèi)置了組件化方案、模塊化方案、測試、表單驗(yàn)證、路由、國際化和HTTP服務(wù)等,這些東西我們開發(fā)者不用再去糾結(jié)怎么選擇,直接按官方的建議說明走就好了,選擇困難癥患者肯定很喜歡這樣的,但相對的它也就沒有vue和react那么靈活了,這個(gè)怎么看待得根據(jù)我們每個(gè)人的項(xiàng)目需求來選擇。既然Angular它本身是這么完整的了,它肯定也有CLI工具,那就是Angular CLI,Angular CLI是一個(gè)命令行界面工具,它可以創(chuàng)建項(xiàng)目、添加文件以及執(zhí)行一大堆開發(fā)任務(wù),比如測試、打包和發(fā)布。我們可以先執(zhí)行以下命令全局安裝Angular CLI
npm install -g @angular/cli
然后執(zhí)行ng new [ProjectName]就可以初始化一個(gè)項(xiàng)目了。
二、模塊化與組件化Angular 應(yīng)用是模塊化的,并且 Angular 有自己的模塊系統(tǒng),它被稱為NgModules。我們的應(yīng)用由一個(gè)或者多個(gè)模塊組成,并且必須要有一個(gè)根模塊,我們通常命名為AppModule,每個(gè)模塊都會有一個(gè)叫@NgModule的裝飾器函數(shù),它接收一個(gè)用來描述模塊屬性的元數(shù)據(jù)對象,我們在這個(gè)對象屬性上配置我們應(yīng)用所需的組件、路由、指令、管道、服務(wù)等。然后Angular會引導(dǎo)根模塊來啟動應(yīng)用,有如下代碼
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; import { AppModule } from "./app/app.module"; platformBrowserDynamic().bootstrapModule(AppModule);
Angular應(yīng)用還是組件化的,組件負(fù)責(zé)控制屏幕上的一小塊區(qū)域,稱之為視圖,每個(gè)組件也有一個(gè)叫@Component的裝飾器函數(shù),它也接收一個(gè)元數(shù)據(jù)對象,我們可以在該對象屬性上配置組件的模板文件,和組件模板的樣式文件等,看如下代碼
@Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.scss"] })
這樣我們就可以組合不同的組件拼裝起我們整個(gè)應(yīng)用了。整體架構(gòu)圖如下
Angular的路由是通過一個(gè)叫RouterModule的模塊來配置的,RouterModule在@angular/router這個(gè)包里面,所以路由配置模塊RouterModule需要先從@angular/router這個(gè)包導(dǎo)出來,然后調(diào)用RouterModule的forRoot方法給他傳進(jìn)去一個(gè)數(shù)組配置對象就好了,需要注意的是我們還要有一個(gè)路由來匹配我們所有路由都不配置的情況,它的path應(yīng)該寫成兩個(gè)星號
import { Routes, RouterModule } from "@angular/router"; const routes: Routes = [ { path: "index", component: IndexComponent }, { path: "**", redirectTo: "index", pathMatch: "full" } ]) @NgModule({ imports: [RouterModule.forRoot(routes)] ... })
路由配置好后把它的返回值添加到AppModule的imports數(shù)組里面就好了。然后在我們的根組件appComponent的模板里面添加
目錄的劃分我是根據(jù)個(gè)人的開發(fā)習(xí)慣來做的,我們的業(yè)務(wù)邏輯的開發(fā)大多在app文件夾下進(jìn)行,我一般會在app文件夾下新建一個(gè)pages文件來做頁面級別組件的存放,然后會分別新建directive、pip、service、animation、interceptor文件夾來存放我們應(yīng)用的指令、管道、服務(wù)、動畫、攔截器,因?yàn)檫@個(gè)應(yīng)用我沒有用一些第三方的UI組件庫,一些通用的組件都是自己封裝的,所以還需要一個(gè)component文件夾來存放整個(gè)應(yīng)用所需的一些通用UI組件,這樣我們整個(gè)應(yīng)用的劃分就很清晰了。最后的目錄說明大致如下
app ├── animations // 動畫 │?? └── global-router-animation.ts ├── app-routing.module.ts // 路由的配置文件 ├── app.component.html // 根組件的模板文件 ├── app.component.scss // 根組件的樣式文件 ├── app.component.spec.ts // 根組件的測試文件 ├── app.component.ts // 根組件 ├── app.module.ts // 根模塊 ├── component // 通用的UI組件 ├── button │?? └── dropdown ├── directives // 指令 │?? └── markdown-editor ├── interceptor // 攔截器 │?? └── global-response-interceptor.ts ├── page // 頁面級別的組件 │?? ├── add-link-note │?? ├── add-note │?? ├── classification │?? ├── edit-note │?? ├── index │?? ├── search │?? ├── tag │?? └── view-note └─ services // 服務(wù) ├── loading-bar ├── msg ├── note └── tag五、跨域問題
跨域問題幾乎是現(xiàn)代前端項(xiàng)目都會遇到的了,在vue,react等項(xiàng)目項(xiàng)目中我們可以通過webpack-dev-server的代理配置來解決,Angular CLI創(chuàng)建出來的項(xiàng)目底層也是通過webpack來進(jìn)行應(yīng)用的打包編譯的,但是Angular CLI把webpack的配置給包裝隱藏起來了,我們可以通過執(zhí)行命令ng eject來暴露出webpack的配置文件,但就為了配置跨域問題就把webpack的配置暴露出來其實(shí)沒有必要。我們可以這樣做,先在項(xiàng)目的根目錄地下新建一個(gè)proxy.config.json配置文件,在該文件里面寫下如下代碼,告訴Angular,應(yīng)用里面所有以api開頭的HTTP請求都轉(zhuǎn)發(fā)到localhost的3002端口。
{ "/api":{ "target":"http://localhost:3002" } }
寫完該配置文件后我們還需要在package.json的start命令里面加上這個(gè)配置
"start" : "ng serve --proxy-config proxy.config.json"
然后執(zhí)行npm run start重啟服務(wù),這樣我們的跨域問題就很簡單的解決了。
六、未解決的問題前面有說過這個(gè)應(yīng)用沒有使用一些第三方的UI組件庫,項(xiàng)目中用到的一些UI組件是我自己封裝的,其中有一個(gè)LoadingBar組件和message消息提示組件,它的調(diào)用方式應(yīng)該是通過服務(wù)的形式來調(diào)用的,類似如下代碼
this.loadingBar.start() this.msg.info("這是消息提示")
但是在Angular里面服務(wù)本身是不帶模板的,只有組件才有模板,所以這樣的組件應(yīng)該是要通過服務(wù)去動態(tài)的加載一個(gè)帶模板的組件,但是我沒有找到相關(guān)的實(shí)現(xiàn)方案,去看了一下ng-zorro的源碼沒看懂?,這里希望有大神賜教。最后我的實(shí)現(xiàn)是通過最不優(yōu)雅的一種方案,直接在服務(wù)里面是操作DOM了。比如我的LoadingBar服務(wù)
import { Injectable } from "@angular/core"; @Injectable() export class LoadingBarService { constructor() { } public $Loading = { start: function(){ const myLoadingBar = document.querySelector(".my-loading-bar"); if (myLoadingBar !== null && myLoadingBar instanceof HTMLElement) { let LoadingBarDivWidth = 0; this.timer = setInterval(() => { LoadingBarDivWidth++; myLoadingBar.style.width = LoadingBarDivWidth + "vw"; if (LoadingBarDivWidth >= 100) { clearInterval(this.timer); } }, 25); } else { const LoadingBarDiv = document.createElement("div"); LoadingBarDiv.className = "my-loading-bar"; const bodyEl = document.querySelector("body"); bodyEl.appendChild(LoadingBarDiv); let LoadingBarDivWidth = 0; this.timer = setInterval(() => { LoadingBarDivWidth++; LoadingBarDiv.style.width = LoadingBarDivWidth + "vw"; if (LoadingBarDivWidth >= 100) { clearInterval(this.timer); } }, 25); } }, finish: function(){ const myLoadingBar = document.querySelector(".my-loading-bar"); if (myLoadingBar !== null && myLoadingBar instanceof HTMLElement) { clearInterval(this.timer); myLoadingBar.style.width = 0 + "vw"; } } }; }七、打包
在我們整個(gè)應(yīng)用開發(fā)完成后我們需要build出靜態(tài)文件交由node來部署,這里有幾個(gè)需要注意一下。在CLI生成的項(xiàng)目的編譯配置命令里面是沒有開啟加--prod配置的,需要我們手動去加上命令開啟,加上--prod之后打包出來的資源就不會再有resource map了,這樣文件體積會小很多,如果Angular Cli用的是1.3.0以上的版本還可以加上--build-optimizer(搖樹優(yōu)化),文件體積會更加小,在我做這個(gè)項(xiàng)目時(shí)用的版本還是1.2.7。最后build的命令配置如下
"build" : "ng build --prod --build-optimizer"八、總結(jié)
本文只是一個(gè)Angular新手做的第一個(gè)項(xiàng)目的流水總結(jié),并沒有說到什么新意有深度的東西。Angular是一個(gè)很好的框架,上手門檻沒有大多數(shù)人想象的那么高,只要你JavaScript基礎(chǔ)扎實(shí),對ES6的語法有基本的了解就可以去學(xué)習(xí),相信會給到你不一樣的開發(fā)體驗(yàn)。最后奉上項(xiàng)目的基本信息
體驗(yàn)地址 https://weiweinote.cn/index
GitHub源碼地址 https://github.com/linguowei/micro-note
其實(shí)該應(yīng)用如果大家有自己的個(gè)人服務(wù)器的話完全可以部署給自己使用,如果沒有也可以部署到國外的一些免費(fèi)服務(wù)提供商比如heroku上。好啦,如果大家對該項(xiàng)目有什么問題和建議歡迎留言一起討論。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/19088.html
摘要:具體來說,包管理器就是可以通過命令行,幫助你把外部庫和插件放到你的項(xiàng)目里面并在之后進(jìn)行版本升級,這樣就不用手工復(fù)制和更新庫?,F(xiàn)在有的包管理器主要是和。 一、基礎(chǔ) 1、學(xué)習(xí)HTML基礎(chǔ) HTML給你的網(wǎng)頁賦予了結(jié)構(gòu)。它就像是人的骨架那樣讓你保持站立。首先你需要去學(xué)習(xí)語法以及它必須提供的一切。你的學(xué)習(xí)應(yīng)該聚焦在下面這些東西上: 學(xué)習(xí)HTML基礎(chǔ),了解如何編寫語義HTML 理解如何把網(wǎng)頁分...
摘要:具體來說,包管理器就是可以通過命令行,幫助你把外部庫和插件放到你的項(xiàng)目里面并在之后進(jìn)行版本升級,這樣就不用手工復(fù)制和更新庫。現(xiàn)在有的包管理器主要是和。 一、基礎(chǔ) 1、學(xué)習(xí)HTML基礎(chǔ) HTML給你的網(wǎng)頁賦予了結(jié)構(gòu)。它就像是人的骨架那樣讓你保持站立。首先你需要去學(xué)習(xí)語法以及它必須提供的一切。你的學(xué)習(xí)應(yīng)該聚焦在下面這些東西上: 學(xué)習(xí)HTML基礎(chǔ),了解如何編寫語義HTML 理解如何把網(wǎng)頁分...
摘要:你們說能不能就用的開發(fā)模式來實(shí)現(xiàn)客戶端啊這樣版版版就都有了。有道云筆記可能就是最貼近我們想法的產(chǎn)品,有客戶端,有版。這個(gè)項(xiàng)目由發(fā)起和維護(hù)。 最近一個(gè)多月一直在用 AngularJS 做公司的一個(gè)項(xiàng)目(還沒有做完),我之前主要是用 PHP 開發(fā)服務(wù)端的,AngularJS 也是現(xiàn)學(xué)現(xiàn)賣,整個(gè)過程還是比較有意義的,覺得很有必要寫篇文章記錄一下。 緣起 事情是這樣的……我們團(tuán)隊(duì)的產(chǎn)品是一款 ...
摘要:你們說能不能就用的開發(fā)模式來實(shí)現(xiàn)客戶端啊這樣版版版就都有了。有道云筆記可能就是最貼近我們想法的產(chǎn)品,有客戶端,有版。這個(gè)項(xiàng)目由發(fā)起和維護(hù)。 最近一個(gè)多月一直在用 AngularJS 做公司的一個(gè)項(xiàng)目(還沒有做完),我之前主要是用 PHP 開發(fā)服務(wù)端的,AngularJS 也是現(xiàn)學(xué)現(xiàn)賣,整個(gè)過程還是比較有意義的,覺得很有必要寫篇文章記錄一下。 緣起 事情是這樣的……我們團(tuán)隊(duì)的產(chǎn)品是一款 ...
閱讀 1823·2021-10-11 10:59
閱讀 2498·2021-09-30 09:53
閱讀 1868·2021-09-22 15:28
閱讀 2872·2019-08-29 15:29
閱讀 1627·2019-08-29 13:53
閱讀 3287·2019-08-29 12:34
閱讀 2922·2019-08-26 10:16
閱讀 2713·2019-08-23 15:16