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 2018国产大陆天天弄,欧美三级中文字幕,成人欧美在线

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Java后端應(yīng)該掌握的前端知識Vue入門(上)

          ue初探

          聲明

          本文題材來自于狂神說https://www.bilibili.com/video/BV18E411a7mC

          1、大前端知識體系

          1.1、前端三要素

          • HTML(結(jié)構(gòu)):超文本標(biāo)記語言(Hyper Text Markup Language),決定網(wǎng)頁的結(jié)構(gòu)和內(nèi)容。
          • CSS(表現(xiàn)):層疊樣式表(Cascading Style Sheets),設(shè)定網(wǎng)頁的表現(xiàn)樣式。
          • JavaScript(行為):是一種弱類型腳本語言,其源碼不需經(jīng)過編譯,而是由瀏覽器解釋運(yùn)行,用于控制網(wǎng)頁的行為動作。

          1.2、結(jié)構(gòu)層HTML

          主要涉及網(wǎng)頁的結(jié)構(gòu)和內(nèi)容。

          1.3、表現(xiàn)層CSS

          css主要用來設(shè)置網(wǎng)頁的表現(xiàn)樣式,css的層疊樣式表只是一門標(biāo)記語言,也就是說沒有任何的語法支持,用過的人都知道css應(yīng)該有如下的缺點(diǎn):

          • css選擇完標(biāo)簽后需要反復(fù)寫一些css樣式,重復(fù)工作量大,代碼冗余度高。
          • css樣式無復(fù)用的機(jī)制,所以代碼的可維護(hù)性極差。

          基于如上的缺點(diǎn)誕生了【css預(yù)處理器】

          什么是CSS預(yù)處理器

          CSS預(yù)處理器定義了一種新的語言,其基本思想是,用一種專門的編程語言,為CSS增加了一些編程的特性,將CSS作為目標(biāo)生成文件,然后開發(fā)者就只需要使用這種語言進(jìn)行CSS的編碼工作。轉(zhuǎn)化成通俗易懂的話來說就是用一種專門的編程語言,進(jìn)行Web頁面樣式設(shè)計(jì),再通過編譯器轉(zhuǎn)化為正常的CSS文件,以供項(xiàng)目使用

          市面上常見的CSS預(yù)處理器

          • Sass:基于Ruby ,通過服務(wù)端處理,功能強(qiáng)大。解析效率高。需要學(xué)習(xí)Ruby語言,上手難度高于Less。
          • Less:基于NodeJS,通過客戶端處理,使用簡單。功能比Sass簡單,解析效率也低于Sass,但在實(shí)際開發(fā)中足夠了,所以如果我們后臺人員如果需要的話,建議使用LESS。
          • Stylus:基于nodejs,Stylus比Less更強(qiáng)大,而且基于nodejs比Sass更符合我們的思路,作為比較年輕的新型語言,Stylus 可以以近似腳本的方式去寫css代碼,創(chuàng)建健壯的、動態(tài)的、富有表現(xiàn)力的css。

          1.4、行為層JavaScript

          JavaScript一門弱類型腳本語言,其源代碼在發(fā)往客戶端運(yùn)行之前不需要經(jīng)過編譯,而是將文本格式的字符代碼發(fā)送給瀏覽器,由瀏覽器解釋運(yùn)行。

          原生JS開發(fā)

          我們?nèi)粘i_發(fā)都是按照【ECMAScript】標(biāo)準(zhǔn)的開發(fā)方式,簡稱ES特點(diǎn)是所有瀏覽器都支持此規(guī)范,我們需要知道的是ES5規(guī)范對所有的游覽器都支持,但是ES6是市面上用最多的規(guī)范版本,主流游覽器支持,所以為了兼容某些游覽器,需要將ES6規(guī)范通過webpack降級為ES5。

          TypeScript出現(xiàn)的背景

          TypeScript 起源于使用JavaScript開發(fā)的大型項(xiàng)目 。由于JavaScript語言本身的局限性,難以勝任和維護(hù)大型項(xiàng)目開發(fā)。因此微軟開發(fā)了TypeScript ,使得其能夠勝任開發(fā)大型項(xiàng)目。

          • TypeScript是一種由微軟開發(fā)的自由和開源的編程語言。它是JavaScript的一個超集, 而且本質(zhì)上向這個語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊獭S砂驳滤埂ず査共?C#、Delphi、TypeScript之父; .NET創(chuàng)立者) 主導(dǎo)。
          • 該語言的特點(diǎn)就是除了具備ES的特性之外還納入了許多不在標(biāo)準(zhǔn)范圍內(nèi)的新特性,所以會導(dǎo)致很多瀏覽器不能直接支持TypeScript語法, 需要編譯后(編譯成JS) 才能被瀏覽器正確執(zhí)行。

          1.4.1、JavaScript框架

          • JQuery:大家熟知的JavaScript庫,優(yōu)點(diǎn)就是簡化了DOM操作,缺點(diǎn)就是DOM操作太頻繁,影響前端性能;在前端眼里使用它僅僅是為了兼容IE6,7,8。
          • Angular:Google收購的前端框架,由一群Java程序員開發(fā),其特點(diǎn)是將后臺的MVC模式搬到了前端并增加了模塊化開發(fā)的理念,與微軟合作,采用了TypeScript語法開發(fā);對后臺程序員友好,對前端程序員不太友好;最大的缺點(diǎn)是版本迭代不合理(如1代–>2 代,除了名字,基本就是兩個東西;截止發(fā)表博客時已推出了Angular6)。
          • React:Facebook 出品,一款高性能的JS前端框架;特點(diǎn)是提出了新概念 【虛擬DOM】用于減少真實(shí) DOM 操作,在內(nèi)存中模擬DOM操作,有效的提升了前端渲染效率;缺點(diǎn)是使用復(fù)雜,因?yàn)樾枰~外學(xué)習(xí)一門【JSX】語言。
          • Vue:一款漸進(jìn)式 JavaScript 框架,所謂漸進(jìn)式就是逐步實(shí)現(xiàn)新特性的意思,如實(shí)現(xiàn)模塊化開發(fā)、路由、狀態(tài)管理等新特性。其特點(diǎn)是綜合了 Angular(模塊化)和React(虛擬 DOM) 的優(yōu)點(diǎn)。
          • Axios:前端通信框架;因?yàn)?Vue 的邊界很明確,就是為了處理 DOM,所以并不具備通信能力,此時就需要額外使用一個通信框架與服務(wù)器交互;當(dāng)然也可以直接選擇使用jQuery 提供的AJAX 通信功能。

          對于后端來學(xué)Vue的小伙伴是不是有個疑問,什么叫做DOM呢?有什么用處呢?

          什么叫DOM?

          DOM全稱 Document Object Model,即文檔對象模型,它允許腳本(js)控制Web頁面、窗口和文檔,通俗就是js操作html時的API

          1.4.2、UI框架

          • Ant-Design:阿里巴巴出品,基于React的UI框架。
          • ElementUI、iview、ice:餓了么出品,基于Vue的UI框架。
          • BootStrap:Teitter推出的一個用于前端開發(fā)的開源工具包。
          • AmazeUI:又叫“妹子UI”,一款HTML5跨屏前端框架。

          1.4.3、JavaScript構(gòu)建工具

          • Babel:JS編譯工具,主要用于瀏覽器不支持的ES新特性,比如用于編譯TypeScript。
          • WebPack:模塊打包器,主要作用就是打包、壓縮、合并及按序加載。

          1.5、三端同一

          1.5.1、混合開發(fā)(Hybrid App)

          主要目的是實(shí)現(xiàn)一套代碼三端統(tǒng)一(PC、Android:.apk、iOS:.ipa)并能夠調(diào)用到設(shè)備底層硬件(如:傳感器、GPS、攝像頭等),打包方式主要有以下兩種:

          • 云打包:HBuild -> HBuildX,DCloud 出品;API Cloud。
          • 本地打包: Cordova(前身是 PhoneGap)。

          1.6、微信小程序

          詳見微信官網(wǎng),這里就是介紹一個方便微信小程序UI開發(fā)的框架:WeUI。

          1.7、后端技術(shù)NodeJS

          前端人員為了方便開發(fā)也需要掌握一定的后端技術(shù)但我們Java后臺人員知道后臺知識體系極其龐大復(fù)雜,所以為了方便前端人員開發(fā)后臺應(yīng)用,就出現(xiàn)了Node JS這樣的技術(shù)。

          Node JS的作者已經(jīng)聲稱放棄Node JS(說是架構(gòu)做的不好再加上笨重的node modules,可能讓作者不爽了吧)開始開發(fā)全新架構(gòu)的Deno

          既然是后臺技術(shù),那肯定也需要框架和項(xiàng)目管理工具, Node JS框架及項(xiàng)目管理工具如下:

          • Express:Node JS框架
          • Koa:Express簡化版
          • NPM:項(xiàng)目綜合管理工具,類似于Maven
          • YARN:NPM的替代方案,類似于Maven和Gradle的關(guān)系

          1.8、主流前端框架

          1.8.1、Vue.js

          1.8.2、iView

          iview是一個強(qiáng)大的基于Vue的UI庫, 有很多實(shí)用的基礎(chǔ)組件比element ui的組件更豐富, 主要服務(wù)于PC界面的中后臺產(chǎn)品。使用單文件的Vue組件化開發(fā)模式基于npm+webpack+babel開發(fā), 支持ES 2015高質(zhì)量、功能豐富友好的API, 自由靈活地使用空間。

          • 官網(wǎng)地址
          • Github
          • iview-admin

          備注:屬于前端主流框架,選型時可考慮使用,主要特點(diǎn)是移動端支持較多

          1.8.3、Element UI

          Element是餓了么前端開源維護(hù)的Vue UI組件庫, 組件齊全, 基本涵蓋后臺所需的所有組件,文檔講解詳細(xì), 例子也很豐富。主要用于開發(fā)PC端的頁面, 是一個質(zhì)量比較高的Vue UI組件庫。

          • 官網(wǎng)地址
          • Github
          • vue-element-admin

          備注:屬于前端主流框架,選型時可考慮使用,主要特點(diǎn)是桌面端支持較多

          1.8.4、ICE

          飛冰是阿里巴巴團(tuán)隊(duì)基于React/Angular/Vue的中后臺應(yīng)用解決方案, 在阿里巴巴內(nèi)部, 已經(jīng)有270多個來自幾乎所有BU的項(xiàng)目在使用。飛冰包含了一條從設(shè)計(jì)端到開發(fā)端的完整鏈路,幫助用戶快速搭建屬于自己的中后臺應(yīng)用。

          • 官網(wǎng)地址
          • Github

          備注:主要組件還是以React為主, 截止2019年02月17日更新博客前對Vue的支持還不太完善,目前尚處于觀望階段

          1.8.5、VantUI

          Vant UI是有贊前端團(tuán)隊(duì)基于有贊統(tǒng)一的規(guī)范實(shí)現(xiàn)的Vue組件庫, 提供了-整套UI基礎(chǔ)組件和業(yè)務(wù)組件。通過Vant, 可以快速搭建出風(fēng)格統(tǒng)一的頁面,提升開發(fā)效率。

          • 官網(wǎng)地址
          • Github

          1.8.5、AtUI

          at-ui是一款基于Vue 2.x的前端UI組件庫, 主要用于快速開發(fā)PC網(wǎng)站產(chǎn)品。它提供了一套n pm+web pack+babel前端開發(fā)工作流程, CSS樣式獨(dú)立, 即使采用不同的框架實(shí)現(xiàn)都能保持統(tǒng)一的UI風(fēng)格。

          • 官網(wǎng)地址
          • Github

          1.8.6、Cube Ul

          cube-ui是滴滴團(tuán)隊(duì)開發(fā)的基于Vue js實(shí)現(xiàn)的精致移動端組件庫。支持按需引入和后編譯, 輕量靈活;擴(kuò)展性強(qiáng),可以方便地基于現(xiàn)有組件實(shí)現(xiàn)二次開發(fā)。

          • 官網(wǎng)地址
          • Github

          1.8.7、混合開發(fā)

          1.8.7.1、Flutter

          Flutter是谷歌的移動端UI框架, 可在極短的時間內(nèi)構(gòu)建Android和iOS上高質(zhì)量的原生級應(yīng)用。Flutter可與現(xiàn)有代碼一起工作, 它被世界各地的開發(fā)者和組織使用, 并且Flutter是免費(fèi)和開源的。

          • 官網(wǎng)地址
          • Github

          備注:Google出品, 主要特點(diǎn)是快速構(gòu)建原生APP應(yīng)用程序, 如做混合應(yīng)用該框架為必選框架

          1.8.7.2、lonic

          lonic既是一個CSS框架也是一個Javascript UI庫, lonic是目前最有潛力的一款HTML 5手機(jī)應(yīng)用開發(fā)框架。通過SASS構(gòu)建應(yīng)用程序, 它提供了很多UI組件來幫助開發(fā)者開發(fā)強(qiáng)大的應(yīng)用。它使用JavaScript MV VM框架和Angular JS/Vue來增強(qiáng)應(yīng)用。提供數(shù)據(jù)的雙向綁定, 使用它成為Web和移動開發(fā)者的共同選擇。

          • 官網(wǎng)地址
          • 官網(wǎng)文檔
          • Github

          1.8.8、微信小程序

          1.8.8.1、mpvue

          mpvue是美團(tuán)開發(fā)的一個使用Vue.js開發(fā)小程序的前端框架, 目前支持微信小程序、百度智能小程序,頭條小程序和支付寶小程序。框架基于Vue.js, 修改了的運(yùn)行時框架runtime和代碼編譯器compiler實(shí)現(xiàn), 使其可運(yùn)行在小程序環(huán)境中, 從而為小程序開發(fā)引入了Vue.js開發(fā)體驗(yàn)。

          • 官網(wǎng)地址
          • Git hub

          備注:完備的Vue開發(fā)體驗(yàn), 井且支持多平臺的小程序開發(fā), 推薦使用

          1.8.8.2、WeUI

          WeUI是一套同微信原生視覺體驗(yàn)一致的基礎(chǔ)樣式庫, 由微信官方設(shè)計(jì)團(tuán)隊(duì)為微信內(nèi)網(wǎng)頁和微信小程序量身設(shè)計(jì), 令用戶的使用感知更加統(tǒng)一。包含button、cell、dialog、toast、article、icon等各式元素。

          • 官網(wǎng)地址
          • Github

          2、前后端分離史

          2.1、以后端為主的MVC時代

          為了降低開發(fā)的復(fù)雜度, 以后端為出發(fā)點(diǎn), 比如:Struts、Spring MVC等框架的使用, 就是后端的MVC時代以SpringMVC流程為例:

          優(yōu)點(diǎn)

          • 在這期間(2005年以前) , 包括早期的JSP、PHP可以稱之為Web 1.0時代,MVC是一個非常好的協(xié)作模式, 能夠有效降低代碼的耦合度,為了讓View更純粹, 還可以使用Thymeleaf、Frreemarker等模板引擎,讓前端只關(guān)注模板中的視圖層邏輯。

          缺點(diǎn)

          • 前后端分離不純粹,前端寫好代碼后需要后端去套模板,填充數(shù)據(jù)進(jìn)去,有時因?yàn)樘啄0宓倪^程中操作失誤就會導(dǎo)致樣式錯亂,增加前后端溝通的成本。

          2.2、基于AJAX帶來的SPA時代

          時間回到2005年AJAX(Asynchronous JavaScript And XML, 異步JavaScript和XML,老技術(shù)新用法)被正式提出并開始使用CDN作為靜態(tài)資源存儲, 于是出現(xiàn)了JavaScript王者歸來(在這之前JS都是用來在網(wǎng)頁上貼狗皮膏藥廣告的) 的SPA(Single Page Application) 單頁面應(yīng)用時代。

          優(yōu)點(diǎn)
          這種模式下, **前后端的分工非常清晰, 前后端的關(guān)鍵協(xié)作點(diǎn)是AJAX接口。**看起來是如此美妙, 但回過頭來看看的話, 這與JSP時代區(qū)別不大。復(fù)雜度從服務(wù)端的JSP里移到了瀏覽器的JavaScript,瀏覽器端變得很復(fù)雜。類似Spring MVC,
          這個時代開始出現(xiàn)瀏覽器端的分層架構(gòu)

          缺點(diǎn)

          • 前后端接口的約定:如果后端的接口一塌糊涂或者后端的業(yè)務(wù)模型不夠穩(wěn)定,那么前端的開發(fā)成本會大大增加。
          • 前端開發(fā)的復(fù)雜度控制:SPA應(yīng)用大多以功能交互型為主,JavaScript代碼過十萬行很正常。大量JS代碼的組織,與View層的綁定等,都不是容易的事情。

          2.3、前端為主的MVC時代

          此處的MVC模式如下:

          • MVC(同步通信為主) :Model、View、Controller
          • MVP(異步通信為主) :Model、View、Presenter
          • MVVM(異步通信為主):Model、View、View Model為了降低前端開發(fā)復(fù)雜度,涌現(xiàn)了大量的前端框架,比如:Angular JSReactVue.jsEmber JS等, 這些框架總的原則是先按類型分層, 比如Templates、Controllers、Models, 然后再在層內(nèi)做切分,如下圖:

          優(yōu)點(diǎn)

          • 前后端職責(zé)很清晰:前端工作在瀏覽器端,后端工作在服務(wù)端。清晰的分工可以讓開發(fā)并行,前端可以依靠模擬數(shù)據(jù)在本地開發(fā)。后端則可以專注于業(yè)務(wù)邏輯的處理, 輸出RESTful等接口。
          • 前端開發(fā)的復(fù)雜度可控:前端代碼很重,但合理的分層,讓前端代碼能各司其職。
          • 部署相對獨(dú)立:可以快速迭代開發(fā)。

          缺點(diǎn)

          • 代碼不能復(fù)用。比如后端依舊需要對數(shù)據(jù)做各種校驗(yàn),校驗(yàn)邏輯無法復(fù)用瀏覽器端的代碼。如果可以復(fù)用,那么后端的數(shù)據(jù)校驗(yàn)可以相對簡單化。
          • 全異步, 對SEO(搜索引擎優(yōu)化)不利。往往還需要服務(wù)端做同步渲染的降級方案。
          • 性能并非最佳,特別是移動互聯(lián)網(wǎng)環(huán)境下。
          • SPA不能滿足所有需求, 依舊存在大量多頁面應(yīng)用。URL Design需要后端配合, 前端無法完全掌控。

          2.4、Node JS帶來的全棧時代

          前端為主的MVC模式解決了很多很多問題, 但如上所述, 依舊存在不少不足之處。隨著Node JS的興起, JavaScript開始有能力運(yùn)行在服務(wù)端。這意味著可以有一種新的研發(fā)模式:

          在這種研發(fā)模式下,前后端的職責(zé)很清晰。對前端來說,兩個UI層各司其職:

          • Front-end Ul layer處理瀏覽器層的展現(xiàn)邏輯。通過CSS渲染樣式, 通過JavaScript添加交互功能, HTML的生成也可以放在這層, 具體看應(yīng)用場景。
          • Back-end Ul layer處理路由、模板、數(shù)據(jù)獲取、Cookie等。通過路由, 前端終于可以自主把控URL Design, 這樣無論是單頁面應(yīng)用還是多頁面應(yīng)用, 前端都可以自由調(diào)控。后端也終于可以擺脫對展現(xiàn)的強(qiáng)關(guān)注,轉(zhuǎn)而可以專心于業(yè)務(wù)邏輯層的開發(fā)。

          通過Node, WebServer層也是JavaScript代碼, 這意味著部分代碼可前后復(fù)用, 需要SEO的場景可以在服務(wù)端同步渲染,由于異步請求太多導(dǎo)致的性能問題也可以通過服務(wù)端來緩解。前一種模式的不足,通過這種模式幾乎都能完美解決掉。

          與JSP模式相比, 全棧模式看起來是一種回歸, 也的確是一種向原始開發(fā)模式的回歸, 不過是一種螺旋上升式的回歸。

          3、MVVM

          3.1、什么是MVVM

          MVVM(Model-View-ViewModel)是一種軟件設(shè)計(jì)模式,由微軟WPF(用于替代WinForm,以前就是用這個技術(shù)開發(fā)桌面應(yīng)用程序的)和Silverlight(類似于Java Applet,簡單點(diǎn)說就是在瀏覽器上運(yùn)行WPF)的架構(gòu)師Ken Cooper和Ted Peters開發(fā),是一種簡化用戶界面的事件驅(qū)動編程方式。由John Gossman(同樣也是WPF和Sliverlight的架構(gòu)師)與2005年在他的博客上發(fā)表。

          MVVM源自于經(jīng)典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel層,負(fù)責(zé)轉(zhuǎn)換Model中的數(shù)據(jù)對象來讓數(shù)據(jù)變得更容易管理和使用。其作用如下:

          • 該層向上與視圖層進(jìn)行雙向數(shù)據(jù)綁定
          • 向下與Model層通過接口請求進(jìn)行數(shù)據(jù)交互

          MVVM已經(jīng)相當(dāng)成熟了,主要運(yùn)用但不僅僅在網(wǎng)絡(luò)應(yīng)用程序開發(fā)中。當(dāng)下流行的MVVM框架有Vue.jsAnfular JS

          3.2、為什么要使用MVVM

          MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model),有幾大好處

          • 低耦合:視圖(View)可以獨(dú)立于Model變化和修改,一個ViewModel可以綁定到不同的View上,當(dāng)View變化的時候Model可以不變,當(dāng)Model變化的時候View也可以不變。
          • 可復(fù)用:你可以把一些視圖邏輯放在一個ViewModel里面,讓很多View重用這段視圖邏輯。
          • 獨(dú)立開發(fā):開發(fā)人員可以專注于業(yè)務(wù)邏輯和數(shù)據(jù)的開發(fā)(ViewMode),設(shè)計(jì)人員可以專注于頁面設(shè)計(jì)。
          • 可測試:界面素來是比較難以測試的,而現(xiàn)在測試可以針對ViewModel來寫。

          View

          View是視圖層, 也就是用戶界面。前端主要由HTH L和csS來構(gòu)建, 為了更方便地展現(xiàn)viewModel或者model層的數(shù)據(jù), 已經(jīng)產(chǎn)生了各種各樣的前后端模板語言, 比如FreeMarker,Thyme leaf等等, 各大MVVM框架如Vue.js.Angular JS, EJS等也都有自己用來構(gòu)建用戶界面的內(nèi)置模板語言。

          Model

          Model是指數(shù)據(jù)模型, 泛指后端進(jìn)行的各種業(yè)務(wù)邏輯處理和數(shù)據(jù)操控, 主要圍繞數(shù)據(jù)庫系統(tǒng)展開。這里的難點(diǎn)主要在于需要和前端約定統(tǒng)一的接口規(guī)則

          ViewModel

          ViewModel是由前端開發(fā)人員組織生成和維護(hù)的視圖數(shù)據(jù)層。在這一層, 前端開發(fā)者對從后端獲取的Model數(shù)據(jù)進(jìn)行轉(zhuǎn)換處理, 做二次封裝, 以生成符合View層使用預(yù)期的視圖數(shù)據(jù)模型。
          ??需要注意的是View Model所封裝出來的數(shù)據(jù)模型包括視圖的狀態(tài)和行為兩部分, 而Model層的數(shù)據(jù)模型是只包含狀態(tài)的

          • 比如頁面的這一塊展示什么,那一塊展示什么這些都屬于視圖狀態(tài)(展示)
          • 頁面加載進(jìn)來時發(fā)生什么,點(diǎn)擊這一塊發(fā)生什么,這一塊滾動時發(fā)生什么這些都屬于視圖行為(交互)

          視圖狀態(tài)和行為都封裝在了ViewModel里。這樣的封裝使得ViewModel可以完整地去描述View層。由于實(shí)現(xiàn)了雙向綁定, ViewModel的內(nèi)容會實(shí)時展現(xiàn)在View層, 這是激動人心的, 因?yàn)榍岸碎_發(fā)者再也不必低效又麻煩地通過操縱DOM去更新視圖
          ??MVVM框架已經(jīng)把最臟最累的一塊做好了, 我們開發(fā)者只需要處理和維護(hù)ViewModel, 更新數(shù)據(jù)視圖就會自動得到相應(yīng)更新,真正實(shí)現(xiàn)
          事件驅(qū)動編程
          ??View層展現(xiàn)的不是
          Model層的數(shù)據(jù), 而是ViewModel的數(shù)據(jù), 由ViewModel負(fù)責(zé)與Model層交互, 這就完全解耦了View層和Model層, 這個解耦是至關(guān)重要的, 它是前后端分離方案實(shí)施的重要一環(huán)。

          4、Vue

          4.1、什么是Vue

          Vue(讀音/vju/, 類似于view)是一套用于構(gòu)建用戶界面的漸進(jìn)式框架, 發(fā)布于2014年2月。與其它大型框架不同的是, Vue被設(shè)計(jì)為可以自底向上逐層應(yīng)用。Vue的核心庫只關(guān)注視圖層, 不僅易于上手, 還便于與第三方庫(如:vue-router,vue-resource,vue x) 或既有項(xiàng)目整合。

          4.2、MVVM模式的實(shí)現(xiàn)者

          • Model:模型層, 在這里表示JavaScript對象
          • View:視圖層, 在這里表示DOM(HTML操作的元素)
          • ViewModel:連接視圖和數(shù)據(jù)的中間件, Vue.js就是MVVM中的View Model層的實(shí)現(xiàn)者

          在MVVM架構(gòu)中, 是不允許數(shù)據(jù)Model和視圖View直接通信的, 只能通過ViewModel來通信, 而ViewModel就是定義了一個Observer觀察者(俗稱雙向綁定)

          • ViewModel能夠觀察到數(shù)據(jù)的變化,并對視圖對應(yīng)的內(nèi)容進(jìn)行更新
          • ViewModel能夠監(jiān)聽到視圖的變化,并能夠通知數(shù)據(jù)發(fā)生改變

          至此, 我們就明白了, Vue.js就是一個MVVM的實(shí)現(xiàn)者, 他的核心就是實(shí)現(xiàn)了DOM監(jiān)聽與數(shù)據(jù)綁定

          4.3、為什么要使用Vue.js

          • 輕量級, 體積小是一個重要指標(biāo)。Vue.js壓縮后有只有20多kb(Angular壓縮后56kb+,React壓縮后44kb+)
          • 移動優(yōu)先。更適合移動端, 比如移動端的Touch事件
          • 易上手,學(xué)習(xí)曲線平穩(wěn),文檔齊全
          • 吸取了Angular(模塊化) 和React(虛擬DOM) 的長處, 并擁有自己獨(dú)特的功能,如:計(jì)算屬性
          • 開源,社區(qū)活躍度高

          5、第一個Vue程序

          5.1、注意點(diǎn)

          Vue不支持IE 8及以下版本, 因?yàn)閂ue使用了IE 8無法模擬的ECMAScript 5特性。但它支持所有兼容ECMAScript 5的瀏覽器

          5.2、開發(fā)環(huán)境配置

          如果是Java開發(fā)的小伙伴喜歡用idea的那么可以直接安裝vue的插件即可。

          **可能出現(xiàn)的問題:**安裝完插件右鍵新建文件發(fā)現(xiàn)沒有vue的模板。

          解決辦法:

          5.3、代碼編寫

          5.3.1、新建html文件

          略!

          5.3.2、導(dǎo)入cdn

          • <script src=“https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js”></script>
          • <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

          5.3.3、創(chuàng)建vue實(shí)例

          <script type="text/javascript">
              var vm = new Vue({
                  el:"#app",
                  data:{
                      message:"hello,vue!"
                  }
              });
          </script>
          

          5.3.4、完整代碼

          <!doctype html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Document</title>
          </head>
          <body>
          
          <!--引用參數(shù)-->
          <div id="app">{{message}}</div>
          
          <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
          
          <script>
              // 定義一個vue實(shí)例對象
              var vue = new Vue({
                  // 綁定元素
                  el:'#app',
                  // 定義參數(shù)并且賦值
                  data:{
                      message:"hello vue"
                  }
              });
          </script>
          </body>
          </html>
          

          5.4、測試

          為了能夠更直觀的體驗(yàn)Vue帶來的數(shù)據(jù)綁定功能, 我們需要在瀏覽器測試一番, 操作流程如下:

          1. 在瀏覽器上運(yùn)行第一個Vue應(yīng)用程序, F12進(jìn)入開發(fā)者工具。
          2. 在控制臺輸入vue.message=‘HelloWorld’, 然后回車, 你會發(fā)現(xiàn)瀏覽器中顯示的內(nèi)容會直接變成HelloWorld。
          3. 此時就可以在控制臺直接輸入vue.message來修改值, 中間是可以省略data的, 在這個操作中, 我并沒有主動操作DOM, 就讓頁面的內(nèi)容發(fā)生了變化, 這就是借助了Vue的數(shù)據(jù)綁定功能實(shí)現(xiàn)的; MVVM模式中要求ViewModel層就是使用觀察者模式來實(shí)現(xiàn)數(shù)據(jù)的監(jiān)聽與綁定, 以做到數(shù)據(jù)與視圖的快速響應(yīng)。

          合實(shí)戰(zhàn)

          關(guān)于 Web 方面的配置比較多,值得慶幸的是,Spring Boot 已經(jīng)幫我們預(yù)置初始化了很多基礎(chǔ)組件。但在實(shí)踐的過程中,某些基礎(chǔ)的組件并不能滿足我們的實(shí)際需求,這時就需要我們重新初始化相應(yīng)組件,甚至在某些極端的情況下需要完全接管 Spring Boot 的默認(rèn)配置。

          本節(jié)將基于對前端模板框架 Thymeleaf 的集成,逐步向大家演示如何自定義 ViewResolver以及如何進(jìn)一步 擴(kuò)展 Spring MVC 配置。本實(shí)例涉及集成 Thymeleaf、自定義初始化ThymeleafViewResolver 以及擴(kuò)展 Spring MVC。

          Thymeleaf 是一個 Java 類庫,能夠處理 HTML/HTML5、XML、JavaScript、CSS, 甚至純文本類型的文件。通常可以用作MVC中的View層,它可以完全替代 JSP。該框架是SpringBoot 首推的前端展示框架。

          首先我們創(chuàng)建一個集成 Thymeleaf 的 SpringBootWeb 項(xiàng)目。集成 Thymeleaf 的核心操作就是引入對應(yīng)的 starter,對應(yīng)項(xiàng)目中 pom.xml 的依賴如下。

          <dependency>
          <groupId>org. springframework. boot</groupId>
          <artifactId>spring- boot- starter-thymeleaf</ artifactId>
          < /dependency>
          <groupId>org. springframework . boot</groupId>
          <artifactId>spring- boot - starter - web</artifactId>
          </ dependency>

          通過前面的學(xué)習(xí)我們已經(jīng)得知引入該 starter 之后,Spring Boot 便會進(jìn)行一個初始化的基本配置,因此針對 Thymeleaf 的最簡單集成便完成了,關(guān)于頁面展示和基礎(chǔ)配置我們暫時先不考慮。當(dāng)集成 Thymeleaf 之后,Thymeleaf 對應(yīng)的自動配置類 ThymeleafAutoConfiguration 中會初始化一個 ThymeleafViewResolver, 用來對 Thymeleaf 的頁面進(jìn)行解析和渲染。這一操作本質(zhì)上同默認(rèn)的 BeanNameViewResolver 作用-樣,都實(shí)現(xiàn)了 ViewResolver 接口。

          此時,如果官方提供的 ThymeleafViewResolver 的默認(rèn)設(shè) 置無法滿足我們的需求,可以通過 兩 種 途 徑 進(jìn) 行 自 定 義 設(shè) 置 : 通 過 application 配 置 文 件 配 置 和 自 行 創(chuàng) 建ThymeleafViewResolver 對象。

          通過 application 配置對應(yīng)的屬性定義位于 ThymeleafProperties 類中,我們已經(jīng)做過多次類似的配置,不再贅述。

          我們可以通過以下方式自行創(chuàng)建 ThymeleafViewResolver 對象。先定義一個配置類ViewResolverConfig,并在類內(nèi)部通過@Bean 注解對實(shí)例化的 ThymeleafViewResolver對象進(jìn)行注入容器的操作。

          @Configuration
          public class ViewResolverConfig {
          @Bean
          public ThymeleafViewResolver thymeleafViewResolver() {
          Thyme leafViewResolver resolver = new ThymeleafViewResolver();
          //設(shè)置 ViewResolver 對應(yīng)的屬性 值
          resolver. setCharacterEncoding("UTF-8");
          resolver. setCache(false);
          return resolver;
          }
          }

          @Bean 默 認(rèn) 會 將 方 法 thymeleafViewResolver 作 為 Bean 的 key, 將 返 回 的Thymeleaf-ViewResolver 對 象 作 為 Value 存 入 容 器 當(dāng) 中 。 在 方 法 內(nèi) 部 , 可 通 過ThymeleafViewResolver 對應(yīng)的方法進(jìn)行屬性的初始化設(shè)置。通過以上代碼我們便完成了自定義 Thymeleaf-ViewResolver 的注入。

          那么,原來默認(rèn)的 ThymeleafViewResolver 會怎么處理呢? 我們知道幾乎所有的自動配置類都是通過注解設(shè)置初始化條件的,比如 ThymeleafViewResolver 默認(rèn)實(shí)例化的條件是當(dāng)容器中不存在名稱為 thymeleafViewResolver 時才會使用默認(rèn)的初始化。當(dāng)自定義的ThymeleafViewResolver 類完成初始化之后,默認(rèn)配置的初始化條件便不再滿足了。

          上面針對 SpringMVC 中 Thymeleaf 的 ViewResolver 的自定義進(jìn)行了講解。

          其實(shí)在 Spring Boot 中,大多數(shù)組件都可以采用同樣的方式對默認(rèn)配置進(jìn)行覆蓋。除了上述方法,在 Spring Boot 項(xiàng)目中還可以通過實(shí)現(xiàn) WebMvcConfigurer 接口來進(jìn)行更靈活地自定義配置。

          通過 WebMvcConfigurer 接口實(shí)現(xiàn)自定義配置是 Spring 內(nèi)部的一-種配置方式,它替代了傳統(tǒng)的 XML 形式的配置。通過對該接口具體方法的實(shí)現(xiàn),可以自定義一些 Handler、Interceptor 、ViewResolver 、MessageConverter 等參 數(shù) 。 以 上 面 配 置ThymeleafViewResolver 為例,我們也可以通過實(shí)現(xiàn)該接口的 configureViewResolvers 方法來進(jìn)行配置,達(dá)到同樣的效果,具體示例代碼如下:

          @Configuration
          public class MyMvcConfig implements WebMvcConfigurer {
          @Override
          public void configureViewResolvers (ViewResolverRegistry registry) {
          Thyme leafViewResolver resolver = new ThymeleafViewResolver();
          //設(shè)置 ViewResolver 對應(yīng)的屬 性值
          resolver. setCharacterEncoding("UTF-8");
          resolver . setCache(false);
          registry . viewResolver(resolver);
          }
          }

          使用 WebMvcConfigurer 接口時需注意 Spring Boot 版本,以上代碼是基于 Spring Boot 2.0以后的版本。WebMvcConfigurer 接口還提供 了其他關(guān)于擴(kuò)展 SpringMVC 配置的接口,使用方法與上述示例基本一樣,大家可以查閱對應(yīng)的代碼進(jìn)一步了解, 這里就不再逐一舉例了。

          最后,關(guān)于 SpringMVC 自定義配置的最徹底操作就是完全接管 SpringBoot 關(guān)于 SpringMVC的默認(rèn)配置,具體操作就是在 WebMvcConfigurer 的實(shí)現(xiàn)類上使用@EnableWebMvc 注解,示例如下。

          @EnableWebMvc

          @Configuration

          public class MyMvcConfig implements WebMvcConfigurer {

          使用該注解等于擴(kuò)展了 WebMvcConfigurationSupport,但是沒有重寫任何方法,因此所需的功能都需要開發(fā)人員自行實(shí)現(xiàn)。-般情況下不推薦使用這種方式,該方式更適合基于 SpringBoot 提供的默認(rèn)配置,針對特別需求進(jìn)行有針對性拓展的場景。

          其實(shí),本節(jié)內(nèi)容的重點(diǎn)并不只是讓大家學(xué)會簡單的 Web 自定義配置,更深的用意是希望大家了解在 Spring Boot 默認(rèn)自動配置的基礎(chǔ)上,我們可以通過什么方式以及如何進(jìn)行自定義的拓展。本節(jié)中提到但未列出實(shí)例的內(nèi)容,大家可以根據(jù)已經(jīng)學(xué)習(xí)到的思路相應(yīng)練習(xí)。

          小結(jié)

          本章重點(diǎn)針對 Spring Boot 中 Web 應(yīng)用的自動配置和 Spring MVC 的自動配置展開,并以Spring MVC 中的一些典型配置為例進(jìn)行了源碼講解。

          其 實(shí) 圍 繞 Web 應(yīng) 用 還 有 一 系 列 的 自 動 配 置 比 如HttpEncodingAutoConfigurationMultipartAutoConfiguration和HttpMessageConvertersAutoConfiguration 等。我們只需領(lǐng)悟自動配置的精髓:這些相關(guān)配置只不過是將之前通過 xml 來配置 Bean,轉(zhuǎn)換成了基于類的形式來配置而已。讀者可按照以上方法對其他 Web 相關(guān)的配置項(xiàng)進(jìn)行相應(yīng)的閱讀和分析。

          本文給大家講解的內(nèi)容是SpringBootWeb應(yīng)用源碼解析:綜合實(shí)戰(zhàn)

          1. 下篇文章給大家講解的是SpringBoot內(nèi)置Servlet容器源碼解析;
          2. 覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
          3. 感謝大家的支持!
          • 1. Thymeleaf 簡介
          • 2. 整合 Spring Boot2.1 基本用法2.2 手動渲染
          • 3. Thymeleaf 細(xì)節(jié)3.1 標(biāo)準(zhǔn)表達(dá)式語法3.2 設(shè)置屬性值3.3 遍歷3.4 分支語句3.5 本地變量3.6 內(nèi)聯(lián)
          • 4. 小結(jié)

          雖然現(xiàn)在流行前后端分離,但是后端模版在一些關(guān)鍵地方還是非常有用的,例如郵件模版、代碼模版等。當(dāng)然也不排除一些古老的項(xiàng)目后端依然使用動態(tài)模版。


          Thymeleaf 簡潔漂亮、容易理解,并且完美支持 HTML5,可以直接打開靜態(tài)頁面,同時不新增標(biāo)簽,只需增強(qiáng)屬性,這樣也降低了學(xué)習(xí)成本。

          因此松哥今天花點(diǎn)時間和大家仔細(xì)分享一下 Thymeleaf。

          1. Thymeleaf 簡介

          Thymeleaf 是新一代 Java 模板引擎,它類似于 Velocity、FreeMarker 等傳統(tǒng) Java 模板引擎,但是與傳統(tǒng) Java 模板引擎不同的是,Thymeleaf 支持 HTML 原型。

          它既可以讓前端工程師在瀏覽器中直接打開查看樣式,也可以讓后端工程師結(jié)合真實(shí)數(shù)據(jù)查看顯示效果,同時,SpringBoot 提供了 Thymeleaf 自動化配置解決方案,因此在 SpringBoot 中使用 Thymeleaf 非常方便。

          事實(shí)上, Thymeleaf 除了展示基本的 HTML ,進(jìn)行頁面渲染之外,也可以作為一個 HTML 片段進(jìn)行渲染,例如我們在做郵件發(fā)送時,可以使用 Thymeleaf 作為郵件發(fā)送模板。

          另外,由于 Thymeleaf 模板后綴為 .html,可以直接被瀏覽器打開,因此,預(yù)覽時非常方便。

          2. 整合 Spring Boot

          2.1 基本用法

          Spring Boot 中整合 Thymeleaf 非常容易,只需要創(chuàng)建項(xiàng)目時添加 Thymeleaf 即可:

          創(chuàng)建完成后,pom.xml 依賴如下:

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-thymeleaf</artifactId>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          

          當(dāng)然,Thymeleaf 不僅僅能在 Spring Boot 中使用,也可以使用在其他地方,只不過 Spring Boot 針對 Thymeleaf 提供了一整套的自動化配置方案,這一套配置類的屬性在 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties 中,部分源碼如下:

          @ConfigurationProperties(prefix = "spring.thymeleaf")
          public class ThymeleafProperties {
                  private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
                  public static final String DEFAULT_PREFIX = "classpath:/templates/";
                  public static final String DEFAULT_SUFFIX = ".html";
                  private boolean checkTemplate = true;
                  private boolean checkTemplateLocation = true;
                  private String prefix = DEFAULT_PREFIX;
                  private String suffix = DEFAULT_SUFFIX;
                  private String mode = "HTML";
                  private Charset encoding = DEFAULT_ENCODING;
                  private boolean cache = true;
                  //...
          }
          
          1. 首先通過 @ConfigurationProperties 注解,將 application.properties 前綴為 spring.thymeleaf 的配置和這個類中的屬性綁定。
          2. 前三個 static 變量定義了默認(rèn)的編碼格式、視圖解析器的前綴、后綴等。
          3. 從前三行配置中,可以看出來,Thymeleaf 模板的默認(rèn)位置在 resources/templates 目錄下,默認(rèn)的后綴是 html
          4. 這些配置,如果開發(fā)者不自己提供,則使用 默認(rèn)的,如果自己提供,則在 application.properties 中以 spring.thymeleaf 開始相關(guān)的配置。

          而我們剛剛提到的,Spring Boot 為 Thymeleaf 提供的自動化配置類,則是 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration ,部分源碼如下:

          @Configuration
          @EnableConfigurationProperties(ThymeleafProperties.class)
          @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
          @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
          public class ThymeleafAutoConfiguration {
          }
          

          可以看到,在這個自動化配置類中,首先導(dǎo)入 ThymeleafProperties ,然后 @ConditionalOnClass 注解表示當(dāng)當(dāng)前系統(tǒng)中存在 TemplateModeSpringTemplateEngine 類時,當(dāng)前的自動化配置類才會生效,即只要項(xiàng)目中引入了 Thymeleaf 相關(guān)的依賴,這個配置就會生效。

          這些默認(rèn)的配置我們幾乎不需要做任何更改就可以直接使用了。如果開發(fā)者有特殊需求,則可以在 application.properties 中配置以 spring.thymeleaf 開頭的屬性即可。

          接下來我們就可以創(chuàng)建 Controller 了,實(shí)際上引入 Thymeleaf 依賴之后,我們可以不做任何配置。新建的 IndexController 如下:

          @Controller
          public class IndexController {
              @GetMapping("/index")
              public String index(Model model) {
                  List<User> users = new ArrayList<>();
                  for (int i = 0; i < 10; i++) {
                      User u = new User();
                      u.setId((long) i);
                      u.setName("javaboy:" + i);
                      u.setAddress("深圳:" + i);
                      users.add(u);
                  }
                  model.addAttribute("users", users);
                  return "index";
              }
          }
          public class User {
              private Long id;
              private String name;
              private String address;
              //省略 getter/setter
          }
          

          IndexController 中返回邏輯視圖名+數(shù)據(jù),邏輯視圖名為 index ,意思我們需要在 resources/templates 目錄下提供一個名為 index.htmlThymeleaf 模板文件。

          • 創(chuàng)建 Thymeleaf
          <!DOCTYPE html>
          <html lang="en" xmlns:th="http://www.thymeleaf.org">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
          <table border="1">
              <tr>
                  <td>編號</td>
                  <td>用戶名</td>
                  <td>地址</td>
              </tr>
              <tr th:each="user : ${users}">
                  <td th:text="${user.id}"></td>
                  <td th:text="${user.name}"></td>
                  <td th:text="${user.address}"></td>
              </tr>
          </table>
          </body>
          </html>
          

          Thymeleaf 中,通過 th:each 指令來遍歷一個集合,數(shù)據(jù)的展示通過 th:text 指令來實(shí)現(xiàn),

          注意 index.html 最上面引入 thymeleaf 名稱空間(最新版并無強(qiáng)制要求)。

          配置完成后,就可以啟動項(xiàng)目了,訪問 /index 接口,就能看到集合中的數(shù)據(jù)了:

          2.2 手動渲染

          前面我們說的是返回一個 Thymeleaf 模板,我們也可以手動渲染 Thymeleaf 模板,這個一般在郵件發(fā)送時候有用,例如我在 resources/templates 目錄下新建一個郵件模板,如下:

          <!DOCTYPE html>
          <html lang="en" xmlns:th="http://www.thymeleaf.org">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
          <p>hello 歡迎 <span th:text="${username}"></span>加入 XXX 集團(tuán),您的入職信息如下:</p>
          <table border="1">
              <tr>
                  <td>職位</td>
                  <td th:text="${position}"></td>
              </tr>
              <tr>
                  <td>薪水</td>
                  <td th:text="${salary}"></td>
              </tr>
          </table>
          <img src="http://www.javaboy.org/images/sb/javaboy.jpg" alt="">
          </body>
          </html>
          

          這一個 HTML 模板中,有幾個變量,我們要將這個 HTML 模板渲染成一個 String 字符串,再把這個字符串通過郵件發(fā)送出去,那么如何手動渲染呢?

          @Autowired
          TemplateEngine templateEngine;
          @Test
          public void test1() throws MessagingException {
              Context context = new Context();
              context.setVariable("username", "javaboy");
              context.setVariable("position", "Java工程師");
              context.setVariable("salary", 99999);
              String mail = templateEngine.process("mail", context);
              //省略郵件發(fā)送
          }
          
          1. 渲染時,我們需要首先注入一個 TemplateEngine 對象,這個對象就是在 Thymeleaf 的自動化配置類中配置的(即當(dāng)我們引入 Thymeleaf 的依賴之后,這個實(shí)例就有了)。
          2. 然后構(gòu)造一個 Context 對象用來存放變量。
          3. 調(diào)用 process 方法進(jìn)行渲染,該方法的返回值就是渲染后的 HTML 字符串,然后我們將這個字符串發(fā)送出去。

          3. Thymeleaf 細(xì)節(jié)

          前面兩個案例讓小伙伴們大致上理解了在 Spring Boot 中要如何使用 Thymeleaf,接下來,松哥將詳細(xì)介紹 Thymeleaf 本身的一些具體用法。

          3.1 標(biāo)準(zhǔn)表達(dá)式語法

          3.1.1 簡單表達(dá)式

          ${...}

          直接使用 th:xx = "${}" 獲取對象屬性。這個在前面的案例中已經(jīng)演示過了,不再贅述。

          *{...}

          可以像 ${...} 一樣使用,也可以通過 th:object 獲取對象,然后使用 th:xx = "*{}" 獲取對象屬性,這種簡寫風(fēng)格極為清爽,推薦大家在實(shí)際項(xiàng)目中使用。

          <table border="1" th:object="${user}">
          <tr>
              <td>用戶名</td>
              <td th:text="*{username}"></td>
          </tr>
          <tr>
              <td>地址</td>
              <td th:text="*{address}"></td>
          </tr>
          </table>
          

          #{...}

          通常的國際化屬性:#{...} 用于獲取國際化語言翻譯值。

          在 resources 目錄下新建兩個文件:messages.properties 和 messages_zh_CN.properties,內(nèi)容如下:

          messages.properties:

          message = javaboy
          

          messages_zh_CN.properties:

          message = 江南一點(diǎn)雨
          

          然后在 thymeleaf 中引用 message,系統(tǒng)會根據(jù)瀏覽器的語言環(huán)境顯示不同的值:

          <div th:text="#{message}"></div>
          

          @{...}

          • 引用絕對 URL:
          <script type="text/javascript" th:src="@{http://localhost:8080/hello.js}"></script>
          

          等價于:

          <script type="text/javascript" src="http://localhost:8080/hello.js"></script>
          
          • 上下文相關(guān)的 URL:

          首先在 application.properties 中配置 Spring Boot 的上下文,以便于測試:

          server.servlet.context-path=/myapp
          

          引用路徑:

          <script type="text/javascript" th:src="@{/hello.js}"></script>
          

          等價于:

          <script type="text/javascript" src="/myapp/hello.js"></script>
          
          • 相對 URL:

          這個相對是指相對于服務(wù)器的 URL,例如如下引用:

          <script type="text/javascript" th:src="@{~/hello.js}"></script>
          

          等價于:

          <script type="text/javascript" src="/hello.js"></script>
          

          應(yīng)用程序的上下文 /myapp 將被忽略。

          • 協(xié)議相對 URL:
          <script type="text/javascript" th:src="@{//localhost:8080/hello.js}"></script>
          

          等價于:

          <script type="text/javascript" src="//localhost:8080/hello.js"></script>
          
          • 帶參數(shù)的 URL:
          <script type="text/javascript" th:src="@{//localhost:8080/hello.js(name='javaboy',age=99)}"></script>
          

          等價于:

          <script type="text/javascript" th:src="//localhost:8080/hello.js?name=javaboy&age=99"></script>
          

          ~{...}

          片段表達(dá)式是 Thymeleaf 的特色之一,細(xì)粒度可以達(dá)到標(biāo)簽級別,這是 JSP 無法做到的。片段表達(dá)式擁有三種語法:

          • ~{ viewName }:表示引入完整頁面
          • ~{ viewName ::selector}:表示在指定頁面尋找片段,其中 selector 可為片段名、jquery選擇器等
          • ~{ ::selector}: 表示在當(dāng)前頁尋找

          舉個簡單例子。

          在 resources/templates 目錄下新建 my_fragment.html 文件,內(nèi)容如下:

          <div th:fragment="javaboy_link"><a href="http://www.javaboy.org">www.javaboy</a></div>
          <div th:fragment="itboyhub_link"><a href="http://www.itboyhub.com">www.itboyhub.com</a></div>
          

          這里有兩個 div,通過 th:fragment 來定義片段,兩個 div 分別具有不同的名字。

          然后在另外一個頁面中引用該片段:

          <table border="1" th:object="${user}" th:fragment="aaa">
          <tr>
              <td>用戶名</td>
              <td th:text="*{username}"></td>
          </tr>
          <tr>
              <td>地址</td>
              <td th:text="*{address}"></td>
          </tr>
          </table>
          <hr>
          <div th:replace="my_fragment.html"></div>
          <hr>
          <div th:replace="~{my_fragment.html::javaboy_link}"></div>
          <hr>
          <div th:replace="~{::aaa}"></div>
          

          通過 th:replace 來引用片段。第一個表示引用完整的 my_fragment.html 頁面;第二個表示引用 my_fragment.html 中的名為 javaboy_link 的片段;第三個表示引用當(dāng)前頁面名為 aaa 的片段,也就是上面那個 table。

          3.1.2 字面量

          這些是一些可以直接寫在表達(dá)式中的字符,主要有如下幾種:

          • 文本字面量: 'one text', 'Another one!',…
          • 數(shù)字字面量: 0, 34, 3.0, 12.3,…
          • 布爾字面量: true, false
          • Null字面量: null
          • 字面量標(biāo)記:one, sometext, main,…

          案例:

          <div th:text="'這是 文本字面量(有空格)'"></div>
          <div th:text="javaboy"></div>
          <div th:text="99"></div>
          <div th:text="true"></div>
          

          如果文本是英文,并且不包含空格、逗號等字符,可以不用加單引號。

          3.1.3 文本運(yùn)算

          文本可以使用 + 進(jìn)行拼接。

          <div th:text="'hello '+'javaboy'"></div>
          <div th:text="'hello '+${user.username}"></div>
          

          如果字符串中包含變量,也可以使用另一種簡單的方式,叫做字面量置換,用 | 代替 '...' + '...',如下:

          <div th:text="|hello ${user.username}|"></div>
          <div th:text="'hello '+${user.username}+' '+|Go ${user.address}|"></div>
          

          3.1.4 算術(shù)運(yùn)算

          算術(shù)運(yùn)算有:+, -, *, /%

          <div th:with="age=(99*99/99+99-1)">
              <div th:text="${age}"></div>
          </div>
          

          th:with 定義了一個局部變量 age,在其所在的 div 中可以使用該局部變量。

          3.1.5 布爾運(yùn)算

          • 二元運(yùn)算符:and, or
          • 布爾非(一元運(yùn)算符):!, not

          案例:

          <div th:with="age=(99*99/99+99-1)">
              <div th:text="9 eq 9 or 8 ne 8"></div>
              <div th:text="!(9 eq 9 or 8 ne 8)"></div>
              <div th:text="not(9 eq 9 or 8 ne 8)"></div>
          </div>
          

          3.1.6 比較和相等

          表達(dá)式里的值可以使用 >, <, >=<= 符號比較。==!= 運(yùn)算符用于檢查相等(或者不相等)。注意 XML規(guī)定 <> 標(biāo)簽不能用于屬性值,所以應(yīng)當(dāng)把它們轉(zhuǎn)義為 <>

          如果不想轉(zhuǎn)義,也可以使用別名:gt (>);lt (<);ge (>=);le (<=);not (!)。還有 eq (==), neq/ne (!=)。

          舉例:

          <div th:with="age=(99*99/99+99-1)">
              <div th:text="${age} eq 197"></div>
              <div th:text="${age} ne 197"></div>
              <div th:text="${age} ge 197"></div>
              <div th:text="${age} gt 197"></div>
              <div th:text="${age} le 197"></div>
              <div th:text="${age} lt 197"></div>
          </div>
          

          3.1.7 條件運(yùn)算符

          類似于我們 Java 中的三目運(yùn)算符。

          <div th:with="age=(99*99/99+99-1)">
              <div th:text="(${age} ne 197)?'yes':'no'"></div>
          </div>
          

          其中,: 后面的部分可以省略,如果省略了,又同時計(jì)算結(jié)果為 false 時,將返回 null。

          3.1.8 內(nèi)置對象

          基本內(nèi)置對象:

          • #ctx:上下文對象。
          • #vars: 上下文變量。
          • #locale:上下文區(qū)域設(shè)置。
          • #request:(僅在 Web 上下文中)HttpServletRequest 對象。
          • #response:(僅在 Web 上下文中)HttpServletResponse 對象。
          • #session:(僅在 Web 上下文中)HttpSession 對象。
          • #servletContext:(僅在 Web 上下文中)ServletContext 對象。

          在頁面可以訪問到上面這些內(nèi)置對象,舉個簡單例子:

          <div th:text='${#session.getAttribute("name")}'></div>
          

          實(shí)用內(nèi)置對象:

          • #execInfo:有關(guān)正在處理的模板的信息。
          • #messages:在變量表達(dá)式中獲取外部化消息的方法,與使用#{...}語法獲得的方式相同。
          • #uris:轉(zhuǎn)義URL / URI部分的方法
          • #conversions:執(zhí)行配置的轉(zhuǎn)換服務(wù)(如果有)的方法。
          • #dates:java.util.Date對象的方法:格式化,組件提取等
          • #calendars:類似于#dates但是java.util.Calendar對象。
          • #numbers:用于格式化數(shù)字對象的方法。
          • #strings:String對象的方法:contains,startsWith,prepending / appending等
          • #objects:一般對象的方法。
          • #bools:布爾評估的方法。
          • #arrays:數(shù)組方法。
          • #lists:列表的方法。
          • #sets:集合的方法。
          • #maps:地圖方法。
          • #aggregates:在數(shù)組或集合上創(chuàng)建聚合的方法。
          • #ids:處理可能重復(fù)的id屬性的方法(例如,作為迭代的結(jié)果)。

          這是一些內(nèi)置對象以及工具方法,使用方式也都比較容易,如果使用的是 IntelliJ IDEA,都會自動提示對象中的方法,很方便。

          舉例:

          <div th:text="${#execInfo.getProcessedTemplateName()}"></div>
          <div th:text="${#arrays.length(#request.getAttribute('names'))}"></div>
          

          3.2 設(shè)置屬性值

          這個是給 HTML 元素設(shè)置屬性值。可以一次設(shè)置多個,多個之間用 , 分隔開。

          例如:

          <img th:attr="src=@{/1.png},title=${user.username},alt=${user.username}">
          

          會被渲染成:

          <img src="/myapp/1.png" title="javaboy" alt="javaboy">
          

          當(dāng)然這種設(shè)置方法不太美觀,可讀性也不好。Thymeleaf 還支持在每一個原生的 HTML 屬性前加上 th: 前綴的方式來使用動態(tài)值,像下面這樣:

          <img th:src="@{/1.png}" th:alt="${user.username}" th:title="${user.username}">
          

          這種寫法看起來更清晰一些,渲染效果和前面一致。

          上面案例中的 alt 和 title 則是兩個特殊的屬性,可以一次性設(shè)置,像下面這樣:

          <img th:src="@{/1.png}" th:alt-title="${user.username}">
          

          這個等價于前文的設(shè)置。

          3.3 遍歷

          數(shù)組/集合/Map/Enumeration/Iterator 等的遍歷也算是一個非常常見的需求,Thymeleaf 中通過 th:each 來實(shí)現(xiàn)遍歷,像下面這樣:

          <table border="1">
              <tr th:each="u : ${users}">
                  <td th:text="${u.username}"></td>
                  <td th:text="${u.address}"></td>
              </tr>
          </table>
          

          users 是要遍歷的集合/數(shù)組,u 則是集合中的單個元素。

          遍歷的時候,我們可能需要獲取遍歷的狀態(tài),Thymeleaf 也對此提供了支持:

          • index:當(dāng)前的遍歷索引,從0開始。
          • count:當(dāng)前的遍歷索引,從1開始。
          • size:被遍歷變量里的元素?cái)?shù)量。
          • current:每次遍歷的遍歷變量。
          • even/odd:當(dāng)前的遍歷是偶數(shù)次還是奇數(shù)次。
          • first:當(dāng)前是否為首次遍歷。
          • last:當(dāng)前是否為最后一次遍歷。

          u 后面的 state 表示遍歷狀態(tài),通過遍歷狀態(tài)可以引用上面的屬性。

          <table border="1">
              <tr th:each="u,state : ${users}">
                  <td th:text="${u.username}"></td>
                  <td th:text="${u.address}"></td>
                  <td th:text="${state.index}"></td>
                  <td th:text="${state.count}"></td>
                  <td th:text="${state.size}"></td>
                  <td th:text="${state.current}"></td>
                  <td th:text="${state.even}"></td>
                  <td th:text="${state.odd}"></td>
                  <td th:text="${state.first}"></td>
                  <td th:text="${state.last}"></td>
              </tr>
          </table>
          

          3.4 分支語句

          只顯示奇數(shù)次的遍歷,可以使用 th:if,如下:

          <table border="1">
              <tr th:each="u,state : ${users}" th:if="${state.odd}">
                  <td th:text="${u.username}"></td>
                  <td th:text="${u.address}"></td>
                  <td th:text="${state.index}"></td>
                  <td th:text="${state.count}"></td>
                  <td th:text="${state.size}"></td>
                  <td th:text="${state.current}"></td>
                  <td th:text="${state.even}"></td>
                  <td th:text="${state.odd}"></td>
                  <td th:text="${state.first}"></td>
                  <td th:text="${state.last}"></td>
              </tr>
          </table>
          

          th:if 不僅僅只接受布爾值,也接受其他類型的值,例如如下值都會判定為 true:

          • 如果值是布爾值,并且為 true。
          • 如果值是數(shù)字,并且不為 0。
          • 如果值是字符,并且不為 0。
          • 如果值是字符串,并且不為 “false”, “off” 或者 “no”。
          • 如果值不是布爾值,數(shù)字,字符或者字符串。

          但是如果值為 null,th:if 會求值為 false。

          th:unless 的判定條件則與 th:if 完全相反。

          <table border="1">
              <tr th:each="u,state : ${users}" th:unless="${state.odd}">
                  <td th:text="${u.username}"></td>
                  <td th:text="${u.address}"></td>
                  <td th:text="${state.index}"></td>
                  <td th:text="${state.count}"></td>
                  <td th:text="${state.size}"></td>
                  <td th:text="${state.current}"></td>
                  <td th:text="${state.even}"></td>
                  <td th:text="${state.odd}"></td>
                  <td th:text="${state.first}"></td>
                  <td th:text="${state.last}"></td>
              </tr>
          </table>
          

          這個顯示效果則與上面的完全相反。

          當(dāng)可能性比較多的時候,也可以使用 switch:

          <table border="1">
              <tr th:each="u,state : ${users}">
                  <td th:text="${u.username}"></td>
                  <td th:text="${u.address}"></td>
                  <td th:text="${state.index}"></td>
                  <td th:text="${state.count}"></td>
                  <td th:text="${state.size}"></td>
                  <td th:text="${state.current}"></td>
                  <td th:text="${state.even}"></td>
                  <td th:text="${state.odd}"></td>
                  <td th:text="${state.first}"></td>
                  <td th:text="${state.last}"></td>
                  <td th:switch="${state.odd}">
                      <span th:case="true">odd</span>
                      <span th:case="*">even</span>
                  </td>
              </tr>
          </table>
          

          th:case="*" 則表示默認(rèn)選項(xiàng)。

          3.5 本地變量

          這個我們前面已經(jīng)涉及到了,使用 th:with 可以定義一個本地變量。

          3.6 內(nèi)聯(lián)

          我們可以使用屬性將數(shù)據(jù)放入頁面模版中,但是很多時候,內(nèi)聯(lián)的方式看起來更加直觀一些,像下面這樣:

          <div>hello [[${user.username}]]</div>
          

          用內(nèi)聯(lián)的方式去做拼接也顯得更加自然。

          [[...]] 對應(yīng)于 th:text (結(jié)果會是轉(zhuǎn)義的 HTML),[(...)]對應(yīng)于 th:utext,它不會執(zhí)行任何的 HTML 轉(zhuǎn)義。

          像下面這樣:

          <div th:with="str='hello <strong>javaboy</strong>'">
              <div>[[${str}]]</div>
              <div>[(${str})]</div>
          </div>
          

          最終的顯示效果如下:

          不過內(nèi)聯(lián)方式有一個問題。我們使用 Thymeleaf 的一大優(yōu)勢在于不用動態(tài)渲染就可以直接在瀏覽器中看到顯示效果,當(dāng)我們使用屬性配置的時候確實(shí)是這樣,但是如果我們使用內(nèi)聯(lián)的方式,各種表達(dá)式就會直接展示在靜態(tài)網(wǎng)頁中。

          也可以在 js 或者 css 中使用內(nèi)聯(lián),以 js 為例,使用方式如下:

          <script th:inline="javascript">
              var username=[[${user.username}]]
              console.log(username)
          </script>
          

          js 中需要通過 th:inline="javascript" 開啟內(nèi)聯(lián)。

          4. 小結(jié)

          好啦,Thymeleaf 跟大家也介紹的差不多了,應(yīng)付日常的工作應(yīng)該是可以了。對 Thymeleaf 感興趣的小伙伴,也可以看看它的官方文檔: https://www.thymeleaf.org。

          最后,松哥還搜集了 50+ 個項(xiàng)目需求文檔,想做個項(xiàng)目練練手的小伙伴不妨看看哦~

          需求文檔地址:https://gitee.com/lenve/javadoc


          主站蜘蛛池模板: 一区二区三区午夜| 精品国产福利第一区二区三区| 日韩视频一区二区| 国产一区在线视频| 国产高清在线精品一区小说| 超清无码一区二区三区| 无码人妻一区二区三区在线视频| 国产成人精品亚洲一区| 久久精品免费一区二区喷潮| 日本免费一区二区三区四区五六区| 美女视频一区二区| 高清一区二区三区日本久| 国产综合一区二区在线观看 | 久久久久国产一区二区| 国产伦理一区二区三区| 午夜视频一区二区| 成人精品一区久久久久| 精品久久久中文字幕一区 | 国产色情一区二区三区在线播放| 武侠古典一区二区三区中文| 在线观看国产一区二区三区| 国产天堂在线一区二区三区| 国产一区二区精品久久岳√| 日本一区二区三区中文字幕| 精品国产香蕉伊思人在线在线亚洲一区二区 | 91久久精品国产免费一区| 一区二区三区日韩| 中文字幕日韩一区二区不卡| 日韩视频一区二区在线观看 | 久久国产免费一区二区三区| 日韩免费观看一区| 精品人妻系列无码一区二区三区 | 日韩在线一区视频| 国产成人精品一区二三区| 亚洲AV日韩精品一区二区三区| 中文字幕一区二区视频| 无码国产精品一区二区免费模式 | 熟女大屁股白浆一区二区| 无码人妻精品一区二区在线视频| 亚洲AV成人一区二区三区在线看| 国产一区二区好的精华液|