Omi實戰-QQ附近用戶列表Web頁

yuyujia 7年前發布 | 9K 次閱讀 前端技術 BrowserSync

寫在前面

Omi很適合大型復雜的Web頁面開發,例如一些Web在線工具的開發。但是制作這種簡單的QQ附近用戶列表Web頁,也不會有大炮哄蚊子的感覺。

項目開始之前,實現選擇一個腳手架。這個項目用的就是 Omi Github上的scaffolding 作為其項目腳手架。主要基于 Gulp + Webpack + Babel + BrowserSync 進行開發和部署。(ps:目前腳手架先上github弄下來,pasturn和Aresn正在開發omi-cli,不久就要發布了)

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 + "http://").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</code></pre>

組件里面有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')</code></pre>

通過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讓代碼真心方便簡潔~~~

 

來自:http://www.cnblogs.com/iamzhanglei/p/6430457.html

 

 本文由用戶 yuyujia 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!