CSS相關知識(如選擇器、如何編寫CSS rule等) css
HTML相關知識(元素、class屬性、DOM層級結構等) html
Vaadin相關知識(如怎樣建立、運行Vaadin項目,怎樣建立一個vaadin頁面) 前端
習慣了SSH的小夥伴們遇到vaadin這樣的技術時,確定會一臉懵逼。我當初看到這個東西時眼前飄過的絕對不是6666666666,而是一大堆????????????。 java
有人說Vaadin就像swing,果然如此嗎?No!形似而已。真要上手去用去寫,你就會發現——這TM就是一坨屎。 ide
好啦,不抱怨了。因爲公司大部分產品都是基於Vaadin建立的,爲了提升代碼質量,再屎的東西也要硬着頭皮去學。 學習
在學習Vaadin的時候,有一個坎,那就是theming。Vaadin真不像Swing,再怎麼說swing的LAF尚未跳脫Java的範疇,能夠說他們仍是在同一個體系中的。而Vaadin的style(或者說theming)則與你寫的Java代碼沒有關係,哦,這樣說並不確切。確切的說,絕大多數靈活的theming工做都要用到CSS(SCSS)。在Java代碼中僅能對一些組件作最基礎的尺寸等樣式調整,至於什麼margin、space、padding啥的,不能作(space僅有一個開關,表明「有space」和「沒有space」)。若是你想對vaadin的組件進行更大尺度的樣式化,請使用SCSS。 ui
一、用java語言編寫頁面,添加頁面元素。 spa
二、給頁面元素指定一個特定的class name。
htm
三、在SCSS中針對特定的class name編寫樣式規則。 blog
四、編譯,試運行,看結果。
接下來我就以Label組件爲例,詳細講述如何爲vaadin組件修改樣式。在例子中,我將建立一個Label用來顯示某人的姓名和年齡。而後針對姓名和年齡兩個部分分別樣式化。若是建立Label部分不熟悉,你能夠參考個人另外一篇文章《Vaadin組件筆記——Label》。另:如何建立Vaadin項目,怎樣編譯運行,不在本文範疇以內,你能夠參考其餘相關資料。
組件的Caption中填寫「Mr. Wangbagaozi」,value中填寫「1000 year-old」。
List-1
Label label = new Label(); label.setCaption("Mr. Wangbagaozi"); label.setValue("1000 year-old");
先讓咱們運行一下,看看界面上的效果。
這是Vaadin根據咱們的Java代碼自動生成的前端代碼:
List-2
<div class="v-widget v-has-caption v-caption-on-top v-has-width" style="width: 100%;"> <div class="v-caption" id="gwt-uid-2" for="gwt-uid-3"> <span class="v-captiontext">Mr. Wangbagaozi</span> </div> <div class="v-label v-widget v-has-width" id="gwt-uid-3" aria-labelledby="gwt-uid-2" style="width: 100%;">1000 year-old</div> </div>
如今,我但願caption中的內容字號24px而且加粗,value中的內容字號16px,灰色,斜體。以前說過,vaadin的組件樣式是經過CSS來調整的,那麼,做爲CSS編寫規則的最重要的選擇器就那麼幾種,class、id、element name等。vaadin推薦使用class name。Okay,咱們看一下生成的前端HTML代碼,就清楚該怎樣編寫咱們的CSS規則了。注:在CSS和SCSS中,有些需求可使用多種方式來實現,本文介紹其中一種方式。方式無好壞,你以爲好用就好。
經過分析,咱們看到,帶有Caption的label被解析成了一個div包裹着兩個同級div。提煉一下:
List-3
<div class="v-widget v-has-caption v-caption-on-top v-has-width"> <div class="v-caption"> <span class="v-captiontext">Mr. Wangbagaozi</span> <!--這裏是caption--> </div> <div class="v-label v-widget v-has-width">1000 year-old</div> <!--這裏是value--> </div>
咱們嘗試寫一下SCSS(vaadin中使用SCSS,你須要先編寫SCSS,編譯時vaadin會自動將SCSS編譯爲CSS)。
List-4
.v-captiontext { font-size: 24px; font-weight: bold; } .v-label { font-size: 16px; color: gray; font-style: italic; }
運行一下看看結果:
樣式改變了,貌似這樣就能夠了?等等!這樣寫有問題,讓我再增長一個label組件到頁面上,大家就知道問題在哪兒了。下面我增長一個label,用來顯示這位Wangbagaozi先生的地址還有電話號碼。
List-5
Label label2 = new Label(); label2.setCaption("South China sea."); label2.setValue("13399988888.");
運行一下看看結果:
Whaaat!! 這是什麼鬼東西?沒錯,被放入label2的caption的內容也隨之改變,而這並非咱們想要的結果。咱們但願label2的caption和value都按照普通方式顯示,不要加樣式。
咱們來看一下vaadin幫咱們自動生成的前端代碼,找一下有什麼辦法將兩個Label進行區分。
List-6
<div class="v-slot"> <!--下面是label生成的代碼--> <div class="v-widget v-has-caption v-caption-on-top v-has-width" style="width: 100%;"> <div class="v-caption" id="gwt-uid-2" for="gwt-uid-3"> <span class="v-captiontext">Mr. Wangbagaozi</span> </div> <div class="v-label v-widget v-has-width" id="gwt-uid-3" aria-labelledby="gwt-uid-2" style="width: 100%;">1000 year-old</div> </div> </div> <div class="v-slot"> <!--下面是label2生成的代碼--> <div class="v-widget v-has-caption v-caption-on-top v-has-width" style="width: 100%;"> <div class="v-caption" id="gwt-uid-4" for="gwt-uid-5"> <span class="v-captiontext">South China sea.</span> </div> <div class="v-label v-widget v-has-width" id="gwt-uid-5" aria-labelledby="gwt-uid-4" style="width: 100%;">13399988888.</div> </div> </div>
呃……label和label2生成的前端代碼中用於區別的class name如出一轍,除了進行噁心的相對定位選擇就沒有別的辦法了嗎?固然不是,Vaadin不會這麼蠢!既然沒法利用自動生成的class name,咱們還能夠利用咱們自定義的class name來對這兩個label進行區別。咱們只須要針對第一個label進行樣式化,其餘的不用加載樣式。Okay,稍加修改List-1的代碼:
List-7
Label label = new Label(); label.setCaption("Mr. Wangbagaozi"); label.setValue("1000 year-old"); label.addStyleName("special-label"); <--- Look here!
方法addStyleName其實就是給指定的組件添加一個class name。如今讓咱們再看一下vaadin生成的前端代碼有什麼變化。
List-8
<div class="v-slot v-slot-special-label"> <!--下面是爲label生成的代碼--> <div class="v-widget v-has-caption v-caption-on-top v-has-width" style="width: 100%;"> <div class="v-caption v-caption-special-label" id="gwt-uid-2" for="gwt-uid-3"> <span class="v-captiontext">Mr. Wangbagaozi</span> </div> <div class="v-label v-widget special-label v-label-special-label v-has-width" id="gwt-uid-3" aria-labelledby="gwt-uid-2" style="width: 100%;">1000 year-old</div> </div> </div> <div class="v-slot"> <!--下面是爲label2生成的代碼--> <div class="v-widget v-has-caption v-caption-on-top v-has-width" style="width: 100%;"> <div class="v-caption" id="gwt-uid-4" for="gwt-uid-5"> <span class="v-captiontext">South China sea.</span> </div> <div class="v-label v-widget v-has-width" id="gwt-uid-5" aria-labelledby="gwt-uid-4" style="width: 100%;">13399988888.</div> </div> </div>
注意看List-8中的代碼,相比較沒有用addStyleName方法添加額外class name的label2生成的代碼List-6,第4行的div元素class屬性中多了「v-caption-special-label」,還有第7行的div元素中多了「special-label」和"v-label-special-label"。
有了這些不一樣,咱們就好區別對待了。修改SCSS以下:
List-9
.v-caption-special-label .v-captiontext { font-size: 24px; font-weight: bold; } .v-label-special-label { font-size: 16px; color: gray; font-style: italic; }
運行看看效果:
Bingo!就是我想要的效果。