大家週日愉快~
歡迎繼續來優化我們的Reagent專案
昨天用clojure語法讓貓貓emoji
可以顯示在專案首頁裡
今天的自我練習題來啦:
我想要把貓貓kiss的emoji
變成component元件
然後放在每一個專案頁面裡當作裝飾
要怎麼做呢?
當我們做好一個component simple-component
之後
(defn simple-component []
[:div
[:p "I am a component!"]
[:p.someclass
"I have " [:strong "bold"]
[:span {:style {:color "red"}} " and red "] "text."]])
就可以在另一個component嵌套simple-component
(defn simple-parent []
[:div
[:p "I include simple-component."]
[simple-component]])
看起來蠻簡單易用的!
那我們來把這一頁的cljs code做點小小的修改吧~
home-page
function引入 greet-cpt
(defn greet-cpt []
[:div
[:h4 "I am Ironman."]
[:p
"I have a " [:strong "bold"]
[:span {:style {:color "red"}} " heart!"]]])
(defn home-page []
(fn []
[:span.main
[:h1 "Welcome to Ting's"]
[:h1 "2022 IT Ironman project "]
[greet-cpt]
{:hello "? Good morning my love" :cat (map #(repeat % '?) (range 1 5))}
[:ul
[:li [:a {:href (path-for :items)} "My IronProject"]]
[:li [:a {:href "/broken/link"} "Articles link "]]]]))
看起來是畫面一樣,但code變得有結構多了!
另外,昨天def
兩隻貓kiss的binding,
(def cats (constantly '??))
[:h4 "I am Ironman."]
[:p
[:h3 (cats 1)]
[:h3 (cats 100)]
"I have a " [:strong "bold"]
[:span {:style {:color "red"}} " heart!"]]]
我覺得不是很有架構,想要來改造一下寫法
讓它也變成一組component
kiss component
畫面一樣,但code好看多了(自己覺得XD)
然後我體感上也覺得,clojurescript component的設計與使用好像有比之前研究的Vue component還要簡單
首頁的code整理完之後
通常一般網站在設計時,
都會有關於我(們)
的頁面,如下圖紅色框處
因此我們來進去編輯about的funtion吧!
原本預設的code長這樣,非常單純
(defn about-page []
(fn [] [:span.main
[:h1 "About ironproject"]
]))
我們來把kiss cat的component也在這個頁面顯示,
並且再附上歷年來參加IT邦鐵人賽的連結,展現微微的resume的效果
(defn about-page []
(fn [] [:span.main
[:h1 "About ironproject"]
[:h2 "貓貓工程師的鐵人檔案"]
[kiss-cpt]
[:p [:a {:href "https://ithelp.ithome.com.tw/users/20111177/ironman/1613"} "2018 iThome 鐵人賽: 30天修煉Ruby面試精選30題"]]
[:p [:a {:href "https://ithelp.ithome.com.tw/users/20111177/ironman/2960"} "2020 iThome 鐵人賽: 「VR 」前端後端交響曲 - 30天開發 Vue.js feat. Ruby on Rails即時互動網站"]]
[:p [:a {:href "https://ithelp.ithome.com.tw/users/20111177/ironman/5153"} "2022 iThome 鐵人賽: 後端Developer實戰ClojureScript: Reagent與前端框架 Reframe"]]
]))
看起來還蠻有一個樣子的~
emoji component好用!可以為目前是文字文主的網站,增加一點俏皮感:)
雖然我們已經知道了component只要完成之後,就可以隨意放在各個頁面
但如果每一頁都想要加入同樣component,總不能到處複製貼上吧?
我們注意到Reagent template每一頁都有開頭的,如以下紅框處:
來研究一下包含header和footer的page mounting component
是怎麼實作出來的
;; Page mounting component
(defn current-page []
(fn []
(let [page (:current-page (session/get :route))]
[:div
[:header
[:p [:a {:href (path-for :index)} "Home"] " | "
[:a {:href (path-for :about)} "About ironproject"]]]
[page]
[:footer
[:p "ironproject was generated by the "
[:a {:href "https://github.com/reagent-project/reagent-template"} "Reagent Template"] "."]]])))
可以看得出來 current-page
這個function,會有個local binding page
,route會決定好現在要渲染的頁面是什麼(Home page / About page),並且透過 [page]
vector顯示在前端。
由於我們知道,reagent app是用clojure當interface寫react,因此有特地搜尋一下React的route,
拜讀了IT邦大大寫的React網頁好朋友Router(1)-基本用法篇
覺得reagent幫我們處理了好多事呀~改code變得簡單許多!
這時候可以很容易地再增加我們在本文一開始製作好的kiss component,
放在 Page mounting component
的程式區塊裡,當作是footer上方的分隔線:
(defn current-page []
(fn []
(let [page (:current-page (session/get :route))]
[:div
[:header
[:p [:a {:href (path-for :index)} "Home"] " | "
[:a {:href (path-for :about)} "About ironproject"]]]
[page]
[kiss-cpt] ;; when page mounting, 加入新的component
[:footer
[:p "ironproject was generated by the "
[:a {:href "https://github.com/reagent-project/reagent-template"} "Reagent Template"] "."]]])))
大功告成,今天完成兩個頁面囉~!
小妹想推薦這篇文章ClojureScript + Reagent Tutorial with Code Examples很清楚地解釋Reagent components are functions
Reagent using functions to create React components, using Hiccup to generate HTML, and storing state in Reagent Atoms.
三種形式的reagent component:
Just define a function that returns Hiccup. 等同於 React render() method
functions that return their render function. The outer function will be called once to get the render function.
Then the render function will be called each time the component needs to render.
Form-3 components are functions that return a value created by reagent/create-class.
atom也會在後面的章節提到!