寫在前面
Omi很適合大型複雜的Web頁面開發,例如一些Web線上工具的開發。但是製作這種簡單的QQ附近使用者列表Web頁,也不會有大炮哄蚊子的感覺。
專案開始之前,實現選擇一個腳手架。可以使用omi-cli快速建立專案腳手架。腳手架主要基於 Gulp + Webpack + Babel + BrowserSync 進行開發和部署。
Gulp用來串聯整個流程,Webpack + Babel讓你可以寫ES6和打包,BrowserSync用來幫你刷瀏覽器,不用F5了。
這裡需要注意的是,BrowserSync會啟動localhost:3000導致你的AJAX請求跨域而無法拿到資料。
所以,要使用Fiddler並配置Extention:
目錄
目錄結構也是和Omi Github上的scaffolding一樣。
元件全放在component目錄,公共的工具庫放在common,其他資原始檔放在asset裡。
命令
開發
npm run dev
釋出
npm run dist
開始寫碼
萬事具備,開始寫碼。先寫元件:
import Omi from 'omi'
class UserList extends Omi.Component {
constructor(data) {
super(data)
}
install() {
this.data.uin_info || (this.data.uin_info = [])
this.data.uin_info.forEach(user => {
this.prepareData(user)
})
}
prepareData(user){
user.desc_d = user.desc.split(" ")[0]
user.desc_t = user.desc.split(" ")[1]
user.isBoy = user.sex === "男"
user.qlogo = user.url.replace("http://", location.protocol + "//").replace(/&/g, "&")
if (user.profession_desc) {
user.hasProfession_desc = true
}
}
appendUsers (users) {
users.uin_info && users.uin_info.forEach(user =>{
this.prepareData(user)
this.data.uin_info.push(user)
})
this.update()
}
sendGift(uin, nick, qlogo) {
//送禮物並關閉webview,此處省略
//..
//..
}
render() {
return `
<div class="user_list">
{{#uin_info}}
<div class="item" onclick="sendGift('{{uin}}','{{nick}}','{{qlogo}}')">
<div class="qlogo">
<img style="width: 70px;" src="{{qlogo}}" />
</div>
<div class="main b1 bb">
<div class="nick">{{{nick}}}</div>
<div class="icons">
{{#isBoy}}<span class="boy_age"><img src="component/user_list/boy.png" alt="" /><span>{{age}}</span></span> {{/isBoy}}
{{^isBoy}}<span class="girl_age"><img src="component/user_list/girl.png" alt="" /><span>{{age}}</span></span> {{/isBoy}}
{{#hasProfession_desc}} <span class="profession"><span>{{profession_desc}}</span></span> {{/hasProfession_desc}}
</div>
<div class="action">{{{intro}}}</div>
</div>
<div class="distance_info">{{desc_d}} · {{desc_t}}</div>
</div>
{{/uin_info}}
<div style="text-align:center;font-size:13px;line-height:30px;height:30px;"><span class="loading"></span> 載入中...</div>
</div>
`
}
style() {
return `
.qlogo {
overflow: hidden;
width: 70px;
height: 70px;
-webkit-border-radius: 50%;
border-radius: 50%;
position: absolute;
top: 10px;
left: 12px;
}
...
...
..這裡省略大量.....
...
...
.distance_info {
position: absolute;
top: 15px;
right: 9px;
color: #7B7B84;
font-size: 10px;
}
`
}
}
export default UserList
元件裡面有5個方法:
- constructor 元件的建構函式,生命週期的一部分,其實在super上面和super呼叫下面可以對data做一些處理。super之上不能拿到this
- install 元件的初始化安裝,生命週期的一部分,這裡也可以拿到使用者傳進的data進行處理
- prepareData 對資料進行一些處理來滿足模板的渲染
- appendUsers 新增資料,用來處理使用者向下滾動的load more 的行為的時候呼叫
- sendGift 送禮物,點選每一項的時候會有送禮物的行為,業務相關,可以無視..
其他兩個方法的render和style用來生成元件的HTML和區域性CSS,不再敘述。
render裡面使用了mustache.js模板引擎;
如果使用omi.lite.js版本(不包含mustache.js模板引擎)的話,你也可以使用ES6 map去遍歷資料生成HTML,或者重寫 Omi.template去使用任意你喜歡的模板引擎,非常靈活方便。
這裡友情提醒一下,如果使用webstorm的話,可以把js version設定成JSX Harmony或者ECMAScript 6,這樣才是寫ES6+的姿勢。
下面來看index.js:
import Root from './config.js'
import Omi from 'omi'
import UserList from '../component/user_list/index.js'
Omi.makeHTML('UserList', UserList)
class Main extends Omi.Component {
constructor(data) {
super(data)
}
installed() {
window.onscroll = () => this.loadMore()
this.requestData(data => this.list.appendUsers(data))
}
loadMore() {
const body = document.body,
html = document.documentElement,
height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
vp_height = window.innerHeight
if (height - document.body.scrollTop - vp_height < 200) {
this.requestData(data => this.list.appendUsers(data))
}
}
requestData(callback) {
if (Root.isDev) {
require.ensure([], ()=> {
callback(require('./mock_data.js').default)
})
}else{
//ajax 請求資料,這裡省略
}
}
render() {
return `
<div class="main">
<UserList name="list" />
</div>`
}
}
Omi.render(new Main(),'body')
通過Omi.makeHTML('UserList', UserList)這句程式碼,UserList變成了可以巢狀至render方法中的標籤。如:
render() {
return `
<div class="main">
<UserList name="list" />
</div>`
}
下面這行程式碼,是監聽滾動,快滾動到底部的時候在loadMore裡面會去請求。
window.onscroll = () => this.loadMore()
通過height - document.body.scrollTop - vp_height < 200判斷使用者快要滾動底部,滾動到底部有個載入更多的行為,即:
if (height - document.body.scrollTop - vp_height < 200) {
this.requestData(data => this.list.appendUsers(data))
}
requestData是去伺服器請求分頁的資料,請求成功,會去呼叫this.list.appendUsers進行資料的新增。
慢著?this.list哪裡來的?appendUsers又是哪裡定義的方法?且看下面:
<UserList name="list" />
上面標記的name,讓你可以直接通過this.list訪問到UserList物件的例項,所以也就可以呼叫它的appendUsers方法!
再來看下資料模擬:
if (Root.isDev) {
require.ensure([], ()=> {
callback(require('./mock_data.js').default)
})
}
這裡在dev環境下是mock資料,使用了require.ensure,這樣當你npm run dist的時候,mock的資料就不會被打包進js裡了!!
最後
好了,就這麼多,Omi讓程式碼真心方便簡潔~~~
相關地址
招募計劃
- Omi的Github地址https://github.com/AlloyTeam/omi
- 如果想體驗一下Omi框架,請點選Omi Playground
- 如果想使用Omi框架,請閱讀 Omi使用文件
- 如果想一起開發完善Omi框架,有更好的解決方案或者思路,請閱讀 從零一步步打造web元件化框架Omi
- 關於上面的兩類文件,如果你想獲得更佳的閱讀體驗,可以訪問Docs Website
- 如果你懶得搭建專案腳手架,可以試試Scaffolding for Omi
- 如果你有Omi相關的問題可以New issue
- 如果想更加方便的交流關於Omi的一切可以加入QQ的Omi交流群(256426170)