Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 99视频在线观看视频,亚洲第一免费,亚洲影视在线

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          放棄JSP吧-否則你無路可走

          放棄JSP吧-否則你無路可走

          說一下我自己學習和使用JSP的經歷吧

          我1998年開始學習Java,那時候學校里老師可能聽說過Java,但是同學基本上都不知道Java。校圖書館進第一批Java的書,后面的借閱記錄上都是我的名字。當時幾乎所有男同學都在學C++、PB、VB、Delphi,女生很多在學ASP。所以很多同學問我學的是什么,Java是干什么的。

          大學畢業以后,開始用Java做的第一個實際項目是對日外包,是2001年。日方有一套很老的系統,想用Java重構一下,要求用JSP。我下班就跑去西單圖書大廈,發現那里的書都還是Servlet的, 沒有JSP的!

          還好,當時的公司同時進行的一項業務就是代理BEA的Weblogic(BEA是三個從SUN出來的人創建的,后來被Oracle收購)。Weblogic的產品文檔里包含非常全面的JSP介紹,所以起初對JSP的學習都是從Weblogic開始的。

          那時候還沒聽說過什么Struts。自己在SUN的官網發現了WAF的文檔,全稱是Web Application Framework,算是最早MVC模式的介紹。這個WAF不算是框架,只是介紹了MVC模式應該是個什么樣子,如何用Servlet+JSP實現MVC模式。SUN的官網提供了少量的樣例代碼,剩下的都是我們根據文檔自己搭建和實踐。

          在項目的中后期(02年下半年吧),有一次坐班車,聽到后面座位上兩個人在說話。一個人問:你知道Struts嗎?另外一個人說:不知道。問的那個人說:就是S T R U T S這幾個字母,開發Java的。我偷偷記在心里,然后第二天上網查了一下(當時沒有智能機,家里也沒有WIFI),才算開啟了Apache這扇大門。后來在ASF上又學習了Cocoon、pluto、turbine等等很多框架。

          大概02年底,對日外包項目順利完成了,我公司開始接國內的項目。第一個國內項目是東北一所大學的科研經費審批項目。記得去給人家部署和演示的時候特別有意思。我們用了半天時間在服務器上部署好,然后去給客戶演示。打開瀏覽器,輸入ip+端口,開始操作。操作了十幾分鐘,所有的客戶沒有說一個字。越演示心里越沒底,不知道客戶啥反應。大概又過了幾分鐘,客戶的主任發話了:你們的軟件呢?

          我們的軟件呢?我給你演示了半天,這不就是我們的軟件嗎?最后才明白,用戶認為只有下載一個類似叫setup.exe或install.exe的程序,雙擊,然后下一步下一步,最后桌面上出現一個快捷方式,那才算是軟件!在經過片刻的不可思議之后,我認為實際用戶的理念總是落后于研發人員的理念,這個我很容易想明白。但后來發現,我那些學PB、Delphi的師兄弟也不是一時半會能接受B/S結構的應用算是軟件的...他們認為:你不就是寫個網頁嗎???

          再后來,從03-08年,長期從事企業應用開發,主要是基于Weblogic Platform,包括Server、Integration、Portal,其中在Portal上工作的時間最多。

          其中04-05年用Weblogic Portal做深圳市最大的電子政務項目,06-07年用Weblogic平臺做廣東省電信的3G業務平臺,08-09年用Aqualogic做南方電網的SOA。

          Weblogic Server中集成了Struts,沒記錯的話當時是1.1版本。BEA把Struts做了升級和改造,可以在Weblogic Workshop中可視化開發,就是下面這樣:

          其中圓形代表Action,有Begin Action,End Action,還有普通的中間節點Action。BEA把Struts的這個升級稱作Java Page Flow(Java 頁面流)。一組這樣的圖形當中包含的Action和JSP,會定義在一個擴展名是.jpf的文件中。

          后來,BEA把JPF捐獻給了Apache,成為ASF下的一個開源項目Apache Beehive。

          Welcome to Apache Beehivebeehive.apache.org

          這個項目現在已經停止更新了。

          大概從06年開始,接觸到了YUI,也就是Yahoo User Interface,Yahoo開源的一套前端JS組件庫。從此算是開啟了我的前端之路。

          07-08年開始用Extjs,作者說Ext就是Extension(擴展)的意思,擴展了YUI,提供了更豐富的適合企業開發的前端組件。但這時候,Extjs還僅僅是豐富的UI組件庫,算不上框架。就是在JSP生成的HTML里面嵌入Extjs的組件。

          09-11年用GWT,就是Google Web Toolkits。Google當時的想法很先進,用Java開發前端UI,最終編譯成JS。有點類似于現在TS編譯成JS的過程,就是打算利用上Java的強類型、面向對象等特點。這時候就已經完全前后端分離了。可以說從08年之后我就再也沒寫過JSP,一個頁面也沒寫過。

          10年開始用Bootstrap。這時候GWT的缺點就暴露出來了,CSS非常難改。直到13年初,開始用上了Angularjs。記得當時在智聯招聘上發布職位的時候搜了一下,北京市只有用友和我們公司招聘Angularjs開發。后來就從Angularjs用到React,又用回Angular4,一直到現在都以最新版本的Angular為主,企業應用和互聯網應用都有開發。移動開發主要用Ionic,React Native也用過。

          為什么要詳細介紹我過去和JSP以及前端框架相關的開發經歷呢?是因為我想表達一個觀點:如果要客觀公正評價JSP是否還有必要用,特別是還有必要學,需要一個真正長期用過JSP(前后端不分離)開發,也真正長期用前端框架(前后端分離)開發的人才可以。

          就像我在有些知乎答案下評論的那樣:

          遇到這種情況,我總想起福特的名言:“如果我當年去問顧客他們想要什么,他們肯定會告訴我:‘一匹更快的馬。’”

          滿大街跑馬車的時代,福特問顧客需要什么,顧客就說需要一匹更快的馬。他們不知道汽車時代會給生活帶來怎樣革命性的變化。

          在BP機時代,大家認為有人戴BP機已經很牛了。滿大街諾基亞摩托羅拉功能機的時代,大家也都覺得夠用了。問他們需要什么,他們估計會回答:充一次電能不能待機一個月?能不能把自己喜歡的MP3當彩鈴?

          我覺得要對比評價兩代產品,應該給兩代產品都熟練體驗過的人去判斷。從功能機時代過來的人,現在iphone都已經用到第三部了,你再問他功能機夠不夠用。就拿一個兩代產品都具有的功能(比如都可以QQ聊天)對比,你愿意回到功能機時代還是繼續用智能機。

          一直抱定JSP不撒手,沒動力、沒能力學習前端技術,沒有真正理解前后端分離開發模式的人,不可能得出公正全面的評價。

          在校期間或參加培訓班就學習了前端框架,參加工作后就開始前后端分離的人,也無法理解老人只用JSP或用JSP+JS前端UI組件的開發模式是個怎么回事。

          上面兩種人,據我實際接觸中了解,大部分都認為自己的開發模式是理所當然的。就像我之前描述自己剛畢業時候的經歷一樣。大部分客戶和我的一些同學,理所當然認為雙擊setup.exe,然后下一步下一步才是軟件。而我理所當然認為B/S架構的也是軟件,只是更便于開發和操作。

          JSP為什么不適合現在的主流開發,為什么正在被拋棄

          過去一年多,陸陸續續在知乎上回答了一些關于JSP的問題。當然,我的回答都是建議淘汰JSP,新人小白一定不要再學JSP了。我現在集中把這些技術因素歸納一下。

          一個現代主流Java Web應用,不管前端、后端、還是微服務架構,都在淘汰JSP。

          其中,我認為Java服務器端主流技術還是Spring(Spring Boot + Spring MVC + Spring Cloud)。

          下面三點,第一點幾乎盡人皆知,第二點有一部分人清楚,第三點卻很少有人意識到。

          前端框架已經非常成熟和穩定,不需要JSP
          前后端分離已經不是什么趨勢了,而是當前B/S架構開發的主流模式。前后端分離之后,前端只負責展現和交互,后端負責核心業務邏輯。前后端通過API進行交互,并且最好符合RESTful風格。服務器端把數據返回給前端就不再關心這些數據用在哪里、如何布局、什么樣式。

          這個層面的原因非常容易理解,也是絕大多數討論JSP是否還有必要學的時候里都會提到的。


          服務器端的Spring MVC/WebFlux 和 Spring Boot已經開始拋棄JSP
          從Spring 5開始,在原有的基于Servlet技術的Spring MVC之外增加了一個新的編程模型,就是Spring WebFlux。
          Spring WebFlux是響應式非阻塞的,而且不支持Servlet API,所以也就不支持JSP!

          上圖左側是Spring 5新引入的Spring WebFlux,右側是大家熟悉的Spring MVC,兩者并列,Spring同時支持。

          關于這一點,可以看Stack Overflow上面來自Spring Framework和Spring Boot團隊成員Brian Clozel的回答:

          Spring WebFlux - no JSP support??stackoverflow.com

          新的Spring WebFlux不支持JSP,那咱們不用就好了,至少Spring MVC還是支持JSP的啊。那我們繼續看。

          如果我們繼續使用Spring Boot+Spring MVC開發,那么Spring Boot對JSP是有限制的,看官方文檔怎么說的:

          鏈接在這里:

          Spring Boot Reference Guide?docs.spring.io

          其中那行備注:

          If possible, JSPs should be avoided. There are several known limitations when using them with embedded servlet containers.
          盡可能避免用JSP。當使用嵌入式Servlet容器時,有一些已知的限制。

          關于這些限制和如何繼續在Spring Boot中使用JSP,可以自己查一下,知乎里就有好多文章

          Spring Boot對JSP有限制,那咱們就湊合用唄,反正我是寫Java的,我的發展方向是架構師,我正打算學習微服務,正在看Spring Cloud。那咱們就繼續看看Spring Cloud吧。


          微服務架構下更沒有JSP的用武之地
          首先要明白Spring Boot和Spring Cloud的關系。可以先看我的這個回答:

          Spring boot與Spring cloud 是什么關系??www.zhihu.com

          還是看這張圖吧:

          右側綠色的部分都是Spring Cloud的組成部分,不管是API Gateway、Config Dashboard,Service Registry,還是多個MicroServices,他們都是Spring Boot應用!或者說Spring Boot是整個Spring Cloud的基石(其實也是Spring Cloud Data Flow的基石)。

          哦,你明白了,因為有Spring Boot對JSP的限制,而Spring Cloud的組成部分都是Spring Boot應用,所以Spring Cloud也對JSP有限制。其實不僅僅是表面上這個原因,咱們繼續分析。

          如果強行繼續在Spring Cloud環境中繼續使用JSP,那么JSP放在哪里?有兩種方案。

          1. API Gateway和每個MicroService里面都有@Controller以及對應的JSP。那么這種方案下,不同微服務中的JSP如何通信?用戶訪問的時候,同一個應用下的所有JSP頁面會在不同IP和端口下來回變換。一會是http://ip0:8081/xxx/xxx.jsp,一會是http://ip1:8082/xxx/xxx.jsp,點個連接又跳轉到http://ip2:8080/xxx/xxx.jsp....
          2. 把整個微服務應用下的所有@Controller和JSP都放在API Gateway里面,其他Microservice中只有提供REST API的@Controller和@Service。這種方案并不算理想的微服務架構,因為Gateway沒有解耦,里面的所有@Controller不能拆分部署。這樣就相當于在MicroService架構下有了一個局部的Monolithic(單體應用)。

          那怎么才算是使用Spring Cloud的正確姿勢?還是看上面那幅圖,這次關注左側三個灰色的部分。IoT(物聯網 Internet of Things)、Mobile(移動應用)、Browser(瀏覽器端),這三個也是應用啊。

          我們再看一幅圖:

          整個Spring體系的圖出來了。還是看左側,Your App,也就是IoT(物聯網 Internet of Things)、Mobile(移動應用)、Browser(瀏覽器端)這三類!

          Browser就是前后端分離之后的前端應用,獨立開發、獨立部署、只和服務器端有HTTP RESTful通信。

          我們看看Spring官方給出的Spring Cloud例子,鏈接在這里:

          Spring Projects?spring.io

          customers-stores-ui是前端應用,用Angularjs實現的。例子是便于學習的,不應該引入額外的太多其他技術!為什么Spring官方的例子非要用上前端技術?不能只用服務器端開發人員熟悉的模板引擎解(包括JSP)來演示Spring Cloud嗎?

          我們再看另外一個例子,Spring的Petclinic大家都熟悉吧?Spring 官方例子:

          spring-projects/spring-petclinic?github.com

          官方的是Monolithic(單體)應用,模板用的是Thymeleaf,自己去看代碼。

          用Spring Cloud實現的版本:

          Spring Petclinic community?github.com

          前端有Angular和React兩種實現,服務器端有Java和Kotlin兩種實現,都沒有用服務器端模板。

          同樣的問題。為什么演示Spring Cloud的開發,要引入額外的前端技術?

          答案都是同樣的,Spring Cloud就必須前后端分離開發!用JSP就無法完美拆分微服務,無法利用微服務本應帶來的各種優勢。


          總結:

          我曾經在知乎某一個問題下總結過:現在JSP處于被前后端夾擊的狀態,生存空間越來越小了。就算你不打算管前端,只想在服務器端有所建樹。微服務的前提也必須前后端分離。

          放棄JSP吧,讓自己的路走的寬一些。如果死守JSP不放,服務器端只能停留在SSH/SSM階段,用Spring Boot+Spring MVC已經是你的天花板了。

          xtJs Desktop桌面開始菜單動態生成

          ExtJs框架是目前市面上采用比較成熟的js框架,有著諸多優點特別適合用來實現一些內部的管理信息系統.ExtJs提供了一套組件來開發類似于windows桌面的單頁面系統,其中desktop桌面的開始菜單按照后臺提供的數據動態生成也是一個難點,下面將對desktop桌面動態開始菜單的生成進行介紹。

          ExtJs官方提供了desktop桌面的demo,其中關于開始菜單的生成是靜態的方式,在js腳本中設置好了固定的開始菜單內容再生成開始菜單。<font color=red>本文的講解內容均是在官方demo基礎上進行的修改</font>

          整個需要改進的腳本只有兩個一個是根目錄下的App.js以及BogusModule.js,前臺與后臺之間通過Ajax交互,數據交換個是為json

          后臺定義了Mids類,如下所示:

          public class Mids {
           private String mid; //菜單id
           private String text; //菜單名詞
           private String path; //菜單路徑
           private List<Mid> subs; //子菜單
           //Mid作為Mids內部類
           public class Mid {
           private String mid;
           private String text;
           private String path;
           }
          }
          

          因此前后臺交互的json數組示例如下:

          [{mid:”m1”,text:”菜單1”,path:”/m1”,subs:null},{mid:”m2”,text:”菜單2”,path:”/m1”,subs:[mid:”m21”,text:”菜單21”,path:”/m21”}]

          接下來我們就要修改App.js這個js文件

           getModules : function(){
          // return [
          // //new MyDesktop.Blockalanche(),
          // //new MyDesktop.BogusMenuModule(),
          // //new MyDesktop.BogusModule()
          // 
          // ];
           return mArr;
          },
          //找到這段代碼并注釋掉部分行并修改為return mArr,其中mArr就是開始菜單模塊會在另一個js文件中定義
          

          下面我們就看核心的BogusModule.js這個文件,這個文件定義了開始菜單的生成方式和類型

          //首先需要定義一個模塊類型MyDesktop.BogusModule
          Ext.define(
           'MyDesktop.BogusModule',
           {
           extend: 'Ext.ux.desktop.Module',
           init:function () {},
           createWindow: function (obj) {
           var desktop=this.app.getDesktop();
           createWindow(desktop,obj);//該方法另外定義
           }
           });
          

          菜單數組以及Menu模型與后臺傳遞的json數據進行綁定

          var mArr=[];
          Ext.define('Menu', {
           extend: 'Ext.data.Model',
           fields: ['mid', 'text', 'path','subs']
          });
          // 
          

          定義了一個store采用Ajax方式與后臺進行是數據交互store進行數據加載并實現開始菜單動態加載和綁定,并且生成桌面

          var store=Ext.create('Ext.data.Store', {
           model: 'Menu',
           proxy: {
           type: 'ajax',
           url: 'menu',
           reader: 'json'
           }
          });
          store.load({
          scope: this,
          callback: function (r, op, success) {
           if (success) {
           for (var i=0; i < r.length; i++) {
           var menu=Ext.define('MyDesktop.materialMenu', {
           extend: 'MyDesktop.BogusModule',
           init: function () {
           var mm=this;
           //判斷是否有子菜單,有子菜單則設置為點擊無效
           if (r[i].data.subs) {
           mm.launcher={
           text: r[i].data.text,
           iconCls: 'bogus',
           handler: function () {
           //有子菜單則點擊無效
           return false;
           },
           menu: {items: []}
           };
           //遍歷子菜單數據并生成子菜單項
           Ext.Array.each(r[i].data.subs, function (m, index, allItems) {
           mm.launcher.menu.items.push({
           text: m.text,
           iconCls: 'bogus',
           handler: function (src) {
           var desktop=mm.app.getDesktop();
           createWindow(desktop,src);
           },
           //scope: this,
           src: m.path,
           windowId: m.mid
           });
           });
           } else {
           //沒有子菜單則設置點擊打開窗口
           mm.launcher={
           text: r[i].data.text,
           iconCls: 'bogus',
           handler: this.createWindow,
           scope: this,
           src: r[i].data.path,
           windowId: r[i].data.mid
           };
           }
           }
           });
           mArr.push(new menu());
           }
           // 生成桌面
           var myDesktopApp;
           Ext.onReady(function () {
           myDesktopApp=new MyDesktop.App();
           });
           }
          }
          });
          

          定義對應的打開窗口模塊,每個窗口模塊均內嵌了一個iframe,通過該iframe可以加載其它頁面內容

          function createWindow(desktop,obj) {
          var win=desktop.getWindow('bogus' + obj.windowId);
          if (!win) {
           var iframeId='bogus_' + obj.windowId;
           win=desktop
           .createWindow({
           id: 'bogus' + obj.windowId,
           title: obj.text,
           //width: 800,
           //height: 600,
           maximizable: true,
           maximized: true,
           closable: true,
           resizable: true,
           html: "<iframe id='"
           + iframeId
           + "' style='width:100%;height:100%;border:0px;margin:0px;padding:0px;' frameborder='0' src=''></iframe>",
           iconCls: 'bogus',
           animCollapse: false,
           constrainHeader: true,
           listeners: {
           afterrender: function () {
           document
           .getElementById(iframeId).src=obj.src;
           }
           },
           buttons: [
           {
           text: '刷新窗口內容',
           handler: function () {
           document
           .getElementById(iframeId).src=obj.src;
           }
           }, {
           text: '切換窗口大小',
           handler: function () {
           win.toggleMaximize();
           }
           }, {
           text: '關閉',
           handler: function () {
           win.close();
           }
           }]
           });
          }
          win.show();
          return win;
          }
          

          這樣就完成了ExtJs桌面的動態開始菜單生成

          作者 | 張旭乾 責編 | 夢依丹

          出品 | CSDN(id:csdnnews)

          前端和后端開發,哪一個更容易上手?我們時常會在各大技術論壇看到類似的提問。話說興趣是最好的老師,不實踐,你可能很難知道自己更喜歡哪一個?

          從Java開發再到前端工程師,他在轉型路上遇到過哪些困難?本文作者張旭乾分享了他的轉型經歷,以及他在學習前端開發過程中,遇到的問題和總結出來的一些經驗,希望對你有所啟發。

          我的學習經歷


          編程入門


          在 2008 年的時候,我進入大專學習 Java 開發,HTML 和 CSS 只是專業的附屬品。那時,主要還是前后端一體化開發,HTML 和 CSS 只是為了結合 Java 里的 Servlet 生成頁面。JavaScript 則完全沒有講。

          2010 年快畢業的時候,我參加了五個月的 Java EE 培訓,在這期間了解了 HTML、CSS,以及一部分簡單的 JavaScript DOM 操作和 jQuery,能夠編寫一些帶交互的頁面和 Ajax 異步請求。

          在這期間,我沒有太重視 HTML/CSS/JS 基礎。因為本身剛入門,并不知道哪些重要,哪些不重要。在做項目的時候,頁面部分要自己在網上搜索 HTML 標簽和 CSS 屬性的用法。對于 JS 部分,則只會 jQuery,高級的語法(例如閉包、原型鏈)完全沒有概念,只知道該怎么定義變量,處理事件,做一些基本的邏輯處理。



          順利轉正,還加薪10%


          我的第一份工作是 Java 開發,當時公司用的技術很新潮,算是前后端分離的雛形。頁面部分完全使用了 ExtJS 庫,它提供了一組現成的 UI 組件,所有的數據都是通過 Ajax 來從后端獲取,后端則用 Java 的 Servlet 提供JSON 數據。

          這份工作的主要難點是一開始不了解前后端分離的開發模式。由于是第一次嘗試完全在客戶端 JS 去請求數據,所以理解起來需要一點時間,當時閱讀了 ExtJS 相關的文檔,才大體的了解到這種開發模式。基本上是利用 Ajax 請求數據,然后通過它內置的 API 來填充 UI。后面隨著開發的功能變多,對這種模式也適應了。

          努力學習還是有回報的,過了三個月試用期之后,因為工作比較出色,在拿到正式員工薪資的基礎上,又額外加薪了 10%。所以剛進入公司的時候不要怕上不了手,主流的技術遇到不會的地方要善于自行查找資料解決,對于公司內部的技術要勇于向前輩請教。


          自由職業:實踐與進階


          2010 年底從第一家公司離職,回到家里自己充電,學習了 PHP。因為當時建站非常流行,學了 PHP 既可以做個人站長,也可以通過自由職業,為客戶建站來賺取收入。因為部署網站的主機基本上都支持 PHP 和 ASP,而 PHP 更加流行,所以我就自學了 PHP,通過官方文檔,加上實戰并結合搜索引擎搜索問題來學習。學完了之后就在網上發了個廣告,提供個人建站服務,此時的我還是全棧開發。

          2011 年底左右,廣告發完了我就忘了,沒把它太當回事。大年初六突然收到一個客戶的電話,需要做一個網站,這讓我興奮不已。我給這位客戶一共做了兩個網站:

          • 一個是論壇,直接二次開發的,修改了一下樣式。

          • 一個是質量保證查詢系統,從零使用 PHP + MySQL + jQuery + jQuery UI 進行開發。

          真正有挑戰的是第 2 個項目,頁面部分幾乎遇到了前端開發中全部常見的難題:

          JS 代碼管理

          當時 UI 部分選擇了和 jQuery 配套的 jQuery UI。jQuery UI 封裝了一組常見的 UI 組件,例如拖拽、對話框、按鈕等組件,可以少寫一些邏輯代碼。盡管如此,編寫出來的 JavaScript 文件還是亂七八糟,因為頁面上有很多表格組件,需要在獲取數據后,手動去循環展示表格,并在刪除或修改的時候,還要修改 DOM 更新表格;另外還有其它邏輯,例如登錄、查詢等。

          雖然代碼分散在了不同的 JS 里,但是有的頁面因為業務邏輯比較復雜,加上當時我也不太了解 JS 的復用方式和邏輯,導致了很多重復的代碼。我還有當時的源代碼,可以感受一下代碼的長度(兩張圖片為同一 JS 文件的不同部分,這里通過縮略圖展示):

          一個 JS 文件中的代碼

          兼容性調整

          彼時,瀏覽器主流的還是 IE,所以還是需要做一些兼容性調整。不過好在 jQuery 主打的就是兼容全部瀏覽器,所以 JS 方面沒有太大問題,剩下的就是 CSS。這個項目在 IE、Chrome、火狐下顯示的都不一致,后來查了一下,解決方法可以根據瀏覽器特定的語法,編寫只在特定瀏覽器能識別的 CSS 屬性,或者選擇器,也就是所謂的 CSS hacks。另外也可以使用瀏覽器特殊的 HTML 指令,加載不同的 CSS 文件,最終把頁面調成一致就可以了。

          性能調優

          因為項目頁面部分處理數據比較多,加上開發經驗有限,當時也只是在代碼效率上進行了優化,例如減少不必要的循環操作等。

          與客戶溝通需求

          這個是開發的軟技能了,學會如何拒絕不合理的需求。因為當時我是第一次面對客戶,也沒有自信,所以客戶說改什么,我立刻就開始給他改。這期間客戶最常見的話術就是:“這個功能很簡單,你做一下”,或者“這個問題很容易解決,花不了你幾分鐘”。當時我真覺得功能或者問題挺簡單的,但是實際操作起來,發現要比想象的難多了。做了幾次之后,知道無論多簡單的功能或問題,都會涉及很多的細節,所以后面客戶再提要求的時候,我就把這些細節先說清楚,給他一個大概的完工時間,再加上新增的功能需要額外收費,客戶就會自己斟酌要不要做了。

          網頁設計水平

          還有一個意外,讓我學了一部分設計知識。在給這個客戶做質量保證系統的時候,還要求附帶一個產品的官網,客戶給我發了產品資料之后,我參考網上同品類的網站,幫他設計了一版,但是客戶以不夠大氣為由,讓我重新設計,我又設計了一次,客戶還是覺得不夠好,反復幾次,似乎無法滿足他的需求,他就把官網這部分給別人做了。當時我也有點憋氣,于是買了本《寫給大家看的設計書》,專門學習了一些設計原則,努力提高自己的設計能力。后來等客戶的官網上線之后,發現設計的也一般,大概是審美不同吧。

          在自由職業后半段時間學習了其它的框架,那個時候 Bootstrap 3、Foundation 之類的 HTML/CSS 框架開始爆火,因為十分喜歡學習新的技術,我就去看了看它們的介紹,看到 Bootstrap 3 內置了很多組件,并且不怎么需要寫 CSS,就學了一下 Bootstrap 3。Bootstrap 3 內部使用了 LESS 這個 CSS 預編譯工具來生成 CSS,如果要自定義它的樣式,還需要會 LESS。我就又看了一下 LESS 的文檔,發現它提供了很多實用的功能,例如變量、繼承、嵌套等,感覺很有意思也順便學了。

          從這里你就可以知道:前端庫是互相依賴的。如果直接看前端需要哪些庫,那么零零散散的有一堆,但是當你真的開始下手學習一個框架的時候,你會發現好多框架可以從一條線里牽出來,構成一個完整的開發工具庫,這些自然就都掌握了。



          初識 Vue


          前邊所有的經歷,奠定了我轉型前端所需要的技術基礎。而在從事自由職業期間,我發現我還是喜歡看做得見的項目,從 0 設計界面,直至實現出來,很有成就感,并且我也享受在設計過程中,靈感迸發的快樂,心底就有了想轉前端的火苗。不過第 2 份工作,從 2013 年到 2016 年,我仍然做的是 Java 開發。

          真正讓我對前端產生興趣,是 2016 年去留學之后。在 2017 年第一個學期,有同學問我 React 的問題,我不太會,于是就上網幫同學查,查著查著,就發現前端已經獨立作為一個職業了,再接著從 React 文檔找問題的解決方案時,發現之前我用 jQuery 的問題在 React 中全部都解決了,可以不用手動維護數據和 UI 之間的同步了,這讓我感到很欣慰,發誓等這學期放暑假,就深入學習一下。

          很快,暑假就到了,要兌現承諾開始學前端。當時室友學了高級 Web 編程,主要講的是 React,React 在那個時候還非常難用,應該還是 React 15,需要手動配置好多東西:Babel、Bower.js 之類的。看著室友遇到一個組件顯示不出來,經過一天的搜索解決方案,才發現是組件名大小寫不一致導致的,這個讓我有點對 React 好感度降低,不想學了。

          后來我就研究了一下 Vue,發現普遍的說法是:功能和 React 類似,但是國內用 Vue 的多,國外用 React 的多。看了下 Vue 是華人尤雨溪開發的,很佩服,據說上手比較容易,于是就決定先看看 Vue?

          在把 Vue 官方文檔基礎部分看完之后,結合 YouTube 的一些視頻所教授的開發方法,大概一周的時間,覺得可以上手了,就想了一下練習項目。當時了解到 Vue 適合開發單頁應用,看了一下單頁應用的特點,發現似乎就是網頁版 App 的概念? 于是,我就想著把當時我用的最多的網易云音樂模仿一下。花了一周多的時間,實現了首頁 UI、添加歌曲,播放、暫停、快進、快退等功能,期間學會了 CSS flex 布局。

          使用 Vue 仿網易云音樂(左)的最終界面(右)

          后來發現網頁版的功能局限性比較大,想著能不能做成桌面端的。當時室友在學校的課里學 Electron,一個跨平臺的桌面開發框架,只用編寫 HTML? CSS 和 JavaScript ,就可以生成在 Mac、Windows、Linux 操作系統都能運行的應用。于是我又把應用遷到了 Electron 上面。

          從 Electron 這里也了解到了,Node.js 到底和瀏覽器 JS 運行時到底有什么不同:在 Node.js 的環境下,可以訪問更底層的操作系統級 API,例如訪問本地文件,這樣可以方便用戶自行添加音樂。

          做這個項目的時候,也遇到了很多問題:

          • 不知道什么時候需要定義成組件剛剛接受這種組件化開發的方式之后,最大的難題就是怎么才知道該不該把一部分 UI 定義成組件。當時的思路就是,我先把所有的頁面代碼都寫在入口組件里,后面再根據頁面的布局,把這個組件拆分成各個部分,例如側邊欄、播放列表、播放控制器等,這樣的分法似乎很合乎邏輯,不過這也帶來了一個問題。

          • 組件和數據雜糅到了一起。項目當時使用了 Vuex,應用的數據全部交給了它去管理,對于項目的功能邏輯,都是直接在相關的 UI 中實現的,并綁定了 vuex 的數據。例如播放進度條,它和歌曲的播放時間數據綁定了,后面要實現音量進度條的時候,發現這個組件無法復用。因此,我又把 UI 和數據分離了出來,這樣的組件,可以在各處復用,之后再實現對應的邏輯就好了。

          • CSS Flex 布局遇到坑。這個項目使用了當時開始流行的 CSS Flex 布局,本著學習的態度使用它,遇到了很多問題,例如父容器對 flex 縮放的影響,如何讓 flex 元素占滿容器,又或是如何讓 flex 不占滿容器等等,這些在看了 MDN 文檔的介紹,了解了 flex、align-items 和 justify-content 各個屬性值的作用和含義之后,就清楚了元素的縮放邏輯。

          通過這個小項目的開發,對 VUE 算是入門了,還得出了結論:

          學前端,或者任何編程知識,一定要結合實踐才能快速入門并掌握它們。


          受挫轉型前端,嘗試 React


          學完 Vue 之后暑假差不多也快結束了,最后一個學期都在努力學專業課,沒有再看前端相關的東西。2018 年回國之后,開始找工作。因為留學的主要方向是分布式和云計算,所以我還是想以 Java 開發為主。面試的時候遭到了很多不屑,大多是看我剛研究生畢業,而以前的開發經歷也沒什么出彩的地方,就都草草了事了。這些經歷讓我很受打擊,但是讓我清楚的知道了,縱使有一肚子墨水,但是拿不出實際的產品,或者滿足不了面試官的喜好,就不可能面試成功。

          當然我不會否定自己,最后一次面試失敗之后,突然就想要不要改行做一下前端,畢竟留學的時候鉆研了不少,又在自由職業的時候做過一些產品,更是有濃厚的興趣,于是我立刻下了決心轉前端。

          下定決心之后,我一刻也沒閑著,開始看前端的工作要求。在某招聘 App 上搜了一圈,發現 React 在大廠用的多、工資也高一點,我就又開始自學 React,花了一周看了看官方文檔,寫了一個特別小的、只有一個頁面的小例子,之后就開始投簡歷了。期間還看了看 React Router、Redux,以及 ES6 的新特性。

          在閱讀 React 官方文檔的時候,發現有一節是《Thinking in React》,里邊詳細的介紹了 React 組件化開發的步驟,并且解釋了什么時候需要定義組件,文檔提供了一個表格 UI 作為示例,把它拆解成了表格整體、搜索框、表格內容、類別行和產品行組件,說明了為什么這么拆解,有沒有其它拆解的方法,以及拆解過程的方案折中,建議看一看。

          圖片來源:https://reactjs.org/docs/thinking-in-react.html


          面試后端頻繁受挫 正式轉型前端


          覺得準備的差不多了之后,就開始投簡歷了,大約 1 個月的時間,收到 3 家面試,只通過了 1 家。沒過的那兩家同樣也是見我剛畢業,連前端開發經驗都沒有,就草草了事了。通過的這家,面試官是我工作時的技術總監和組長,在面試的時候沒有刻意刁難,只是問了些框架方面的基礎問題,還問了一下我平時是怎么解決問題的。后來,我在工作的時候,問他們為何決定讓我入職,他們告訴我,看中了我的學習能力。

          所以面試如果沒經驗的話,就努力說明自己的學習能力,總會有面試官欣賞你的。我到現在還非常感謝兩位,讓我正式進入了前端開發的行列。

          進了公司就開始了日常做項目,大大小小一共做了 3 個,這期間經歷了邏輯混亂期、嘗到甜頭期和精進技術期,積累了大量的開發經驗。

          邏輯混亂期

          第 1 個項目,是改造一個傳統的項目,按技術總監的建議,使用 React + dva.js 框架。UI 方面,項目之前用的是 Bootstrap,我用了 React Bootstrap 把項目遷移了過來。

          這個項目里遇到的問題是:代碼混亂。這個時期因為剛剛上手 React 開發,對于代碼的管理也沒有太大的概念,加上 dva.js 的項目結構也不同于普通的 React 項目,所以這個項目開發起來有點麻煩,再加上項目的邏輯比較多,導致組件的代碼很長很長,復用起來也很困難(俗稱面條式代碼),不過因為這個項目也不是完全對外公開的,并且使用頻率較低,所以就沒在優化。

          嘗到甜頭期

          第 2 個項目,是做一個公司內部用的運營管理后臺,時間大約是 2018 年底,當時 React alpha 測試版出了 hooks。看了一下官方文檔,感覺很神奇,能夠清晰分離組件 UI 和邏輯,應該能給代碼管理提供不小的幫助。雖然是測試版,但這個項目是完全對內的后臺項目,所以果斷的用上了。

          這個項目的后端比較特殊,一位大佬同事搭建了 GraphQL 服務,之前在留學的時候就已經聽同學提到過很多遍了,現在有機會體驗體驗了。在看 GraphQL 官方文檔學習、以及使用搜素引擎搜索的時候發現,使用 GraphQL 后可以不用 Redux,于是這個項目我只用了 React? React Router 和 Apollo-GraphQL 這幾個主要的庫。

          這套技術加上 React hooks,讓我真正感受到了前端開發的樂趣。組件從類的形式轉換成了函數形式,代碼量減少了很多,公共的邏輯也能抽離成 Hooks,在各個組件使用,組件自身的邏輯也能抽離成 hooks,來讓功能和 UI 展示代碼分開,讓代碼更易讀。這樣,整體的開發效率提高了不少。

          UI 方面則嘗試了 Ant Design,因為純后臺的,沒有設計稿,只有產品原型。

          另外這個項目是基于 Create-React-App 腳手架創建,了解到腳手架提供的功能非常全面,像靜態資源(圖片、字體)管理、插件、打包構建等都包括了,省了很多手工配置。

          精進前端技術期

          第 3 個項目,是一個從 0 開始、面向客戶的應用,UI 是由設計師專門設計,有很多自定義的樣式。這是我積累最多前端開發經驗的項目,從技術選型,到組件規劃,再到代碼復用,對前端開發的架構有了全新的認識。

          樣式管理

          為了研究怎么在 React 項目中管理樣式最方便,我開始研究大型項目中的 CSS 樣式管理,了解到有普通 CSS 和 CSS-in-JS 兩種方案之后,再查資料發現 CSS-in-JS 方案更靈活,能夠在 CSS 里訪問 JS 變量,讓組件樣式可以隨著組件狀態的變化而變化。

          決定用 CSS-in-JS 方案之后,我找到了 GitHub Star 數比較高的 styled-components 庫,它支持 CSS 嵌套、主題等功能,并且能夠訪問組件的屬性,而且它定義的樣式,本身也是一個 React 組件,可以直接在 JSX 中使用。

          UI 庫繼續使用了 Ant Design,不過也就是利用一下它的組件功能邏輯,樣式幾乎全部都修改了。

          全局狀態的取舍

          項目后端這次沒有用 GraphQL,我又發現不用 GraphQL 也沒必要使用 Redux,所以就沒有再添加 Redux,結果也證明我的選擇是對的:項目本身沒太多全局狀態,舍棄 Redux 大概讓開發效率提升了 1 倍,之前像表單這樣的組件大概需要一天才能完成,現在只需要半天。不過項目里有個內嵌的聊天系統,需要用一點全局狀態,我就從網上查找了一些解決方案,發現使用 React Context + useReducer Hooks 的方式實現全局狀態管理就夠了。

          提升學習能力

          這個項目使用的新框架都是一邊看官方文檔一邊學習的,有不好解決的問題,就結合搜索引擎和 GitHub Issues 解決。

          改良前端項目結構

          對于項目的結構,這次使用了就近原則來組織代碼,每個組件放到單獨的文件夾中,組件相關的 styles、圖片、hooks 等都放在同一個文件夾,對于公用的部分,則放到項目頂級的 src 目錄下。API 和其它庫的配置項也都放到單獨的文件夾里,同樣遵循就近原則,這樣管理項目就方便多了。

          鍛煉溝通能力

          這個項目的圖表也比較多,為了和 App 端保持一致,選擇了 Echarts。在使用 Echarts 的時候,雖然能夠實現大部分設計稿中的樣式,但是還是有小部分不能精準還原,在拿著實際效果跟設計師溝通之后,有些樣式就做了些調整,或直接舍棄了。

          項目最后驗收的時候,還需要跟 UI 設計師核對樣式,這期間我和設計師找了單獨的工位,每天都是在溝通哪里的設計需要修改,哪里的設計不好實現,怎樣取一個大家都滿意的折中方案。這些在了解設計基礎原則之后,你也會明白設計師設計的意圖和用意,這樣用理解的心態來溝通,再輔以技術上的難度展示和時間需求,就能夠更好的避免不必要的 UI 改動和代碼重構。


          前端工程師的技能要求


          先看一下前端工程師需要掌握哪些技能。

          綜合大、中、小企業的前端工程師技能需求,實際上前端工程師的職能包含以下職業中的 1 種或多種:

          • 網頁開發工程師

          • 網頁設計師(UI)

          • 用戶體驗工程師(UE)

          最重要的職能是網頁開發,包括小程序、APP 等跨端應用界面的開發,雖然它們實現的技術不同,但本質上還是做頁面。

          前端工程師必備的技能有

          • 使用 HTML + CSS,精準地還原設計稿,制作符合要求的頁面。

          • 使用 JavaScript 給頁面添加交互,懂得 DOM 操作和 Ajax 請求。

          • 掌握 React 或 Vue 等主流框架的一種或幾種,并了解隨著這些框架的工程化,所牽涉的一系列工具(不同工程需要不同的工具,這里列出常見的), 例如:

            • Node.js 與 npm。

            • Webpack、SnowPack、Vite 等打包工具。

            • Create React App、Vue CLI、Vite 等腳手架。(Vite 既包含腳手架,也包含打包工具)

            • Gulp、Grunt 等自動化工具。

            • SASS/LESS 等 CSS 預編譯工具。

            • styled-components、emotion 等 CSS-In-JS 庫。

            • ESLint 語法檢查工具。

            • Jest、mocha 等測試庫。

          • 兼容性調整,利用 CSS hacks,或 JS Polyfill,實現跨瀏覽器頁面表現一致。

          • 性能優化,減少文件體積,減少請求次數,延遲加載圖片和腳本等。

          • SEO 搜索引擎優化,提高網站在搜索引擎的排名。

          其他的一些框架或技能,如果工作要求,也需要掌握:

          • SSR 服務端渲染框架,例如 Next.js(React)、Remix.js (React)、Nuxt.js(Vue)。

          • SSG 靜態網站生成器,例如 Next.js、Gatsby、VuePress 等。

          • TypeScript。

          • GraphQL。

          • PS/Sketch/Figma,能根據需要進行切圖,或者自行設計頁面。

          下面這些技能不是必須的,但是如果能掌握,可以提高工作效率、跟后端或設計師溝通的能力,以提升求職升職的競爭力:

          • 網頁設計,了解設計基本原則。

          • 用戶體驗設計,了解網頁的動效、輔助功能對用戶體驗的影響。輔助功能(可訪問性)在國外比較重視,目的是方便有閱讀障礙的人士,使用屏幕閱讀器進行網站瀏覽。如果你想去外企,這些技能是必須要掌握的。

          • Docker,了解如何把前端項目構建為 docker image,會編寫簡單的 docker file。

          • 后端語言、框架、數據庫,任選一套,例如 Java + Spring + PostgreSQL,Express + Node.js + MongoDB 等,了解 RESTful API 開發過程。

          乍一看要掌握的有很多,但很多庫都是隨著 React、Vue 等最重要的前端庫自然而然地引入進來的,大部分的用法都很簡單,并且我們還會在工作中持續學習,一開始只需要入門就行。下圖展示了 React 前端開發工程師,根據 React 框架所衍生的技術棧(示意):

          React 前端工程師技能圖譜(示意)


          離職,做自己感興趣的事


          2019 年從公司再次離職,不想再打工了,借鑒在國外留學時所學到的經驗,轉型開始做視頻和線上教學,運營著“峰華前端工程師”賬號,同時也在 CSDN 發表博客。在這期間還撰寫了《JavaScript 基礎語法詳解》一書。

          編寫書籍的時候,又是一次學習的過程,在查閱各種資料之后,對 JavaScript 有了更完全的認識。同時也明白了,人只有存在目標的情況下,才會有動力去完成看似不可能的事,避免渾渾噩噩度日。

          如果你像我一樣,也算比較大齡的程序員,有年齡焦慮,可以適當的想想還要不要在公司里繼續工作下去,是不是該拿出勇氣來嘗試做自己真正想做的事,之后利用興趣養活自己。這不是一條容易的路,所以在決定之前一定要做好兩年之內沒有起色的打算,這些如果我能總結出一套經驗之后,再來分享。


          學習建議


          這些大體就是我學習、掌握前端開發的過程,總結了下面這些重點:

          1. 學會獨立學習。前端的框架太多了,并且經常出現新奇特框架,必須要能自己獨立通過官方文檔和搜索引擎進行學習,因為前端框架多數比較小眾,不會有很多相關的教程。如果連文檔都沒有,就要學會讀源碼學習用法。

          2. 基礎打牢。前端庫雖然多,但萬變不離其宗,總是要回歸到 HTML、CSS 和 JavaScript 上面,所以基礎一定要打牢,尤其是在 ES6 以后出現的新特性,在前端用途非常廣泛。

          3. 實戰練習。學完前端庫之后,一定要找個小項目做,把學到的東西真正地掌握。Github 上有很多前端項目靈感的庫,可以搜索 “front-end project ideas" 找到 ,或者你也可以改造模仿市面上的網站、App 等。

          4. 不要把前端只局限在技術層面。向上往設計和產品擴一下,向下從后端和運維鉆一下,你會更能從整體角度觀望整個項目,從而在前端技術選型、開發過程以及和同事溝通的時候,懂得取舍和折衷。

          1. 線上文檔。對于 HTML、CSS 和 JavaScript 最權威的文檔就是 MDN。其它的像 React、Vue 等框架,就是官方文檔。如果遇到了問題,就去搜索引擎搜索,看其他人寫的解決方案。

          2. 書籍。對于體系化的教程,可以購買相關的書籍看,重點看專業、經典的書籍,這些網上有很多推薦。書籍可以幫助你快速入門并深入,不用在網上東找西找了。

          3. 視頻。現在視頻平臺正火爆,不要只用來消遣,上邊也會有很多編程相關的視頻,空余時間可以刷一刷,可能會獲得一些開發靈感、技巧,以及未來工作可能用到的新技能。

          4. 在線課程或培訓。在線課程或者培訓能幫你直接學到和就業相關的技能,積累項目實戰經驗,但是要注意鑒別課程和機構的質量。

          5. 向有經驗的人學習。如果你看到有高級工程師發布的博客、微博、視頻等內容,可以嘗試和他們建立聯系,拿出你學習的誠意,讓他們幫你指點迷津,或許能少走一些彎路。

          END


          成就一億技術人


          主站蜘蛛池模板: 人妻无码一区二区三区四区| 国产在线一区观看| 亚洲国产AV无码一区二区三区| 福利一区二区在线| 中文字幕AV一区二区三区| 极品少妇伦理一区二区| 欧美亚洲精品一区二区| 久久人妻内射无码一区三区| 一区二区三区视频观看| 精品乱人伦一区二区| 亚洲综合一区无码精品| 亚洲熟妇av一区| 秋霞无码一区二区| 一区二区精品在线| 中文字幕一区二区精品区| 久久久久99人妻一区二区三区| 高清国产精品人妻一区二区| 精品国产AⅤ一区二区三区4区| 丝袜美腿高跟呻吟高潮一区| 精品综合一区二区三区| 日韩一区二区三区免费播放| 国产在线精品观看一区| 国产一区二区三区免费看| 国产在线一区二区杨幂| www一区二区三区| 久久毛片免费看一区二区三区| 精品国产免费一区二区三区| 亚洲午夜精品第一区二区8050| 影院无码人妻精品一区二区| 精品人妻一区二区三区毛片| 亚洲色婷婷一区二区三区| 一区二区三区视频在线| 精品熟人妻一区二区三区四区不卡| 亚洲无圣光一区二区 | 久久高清一区二区三区 | 一区二区三区高清视频在线观看| 日韩精品电影一区| 国产伦一区二区三区高清| 中文字幕一区二区三| 久久精品无码一区二区无码| 国产成人午夜精品一区二区三区 |