Omi 很适合大型复杂的 web 页面开发,例如一些 Web 在线工具的开发。但是制作这种简单的 QQ 附近用户列表 Web 页,也不会有大炮哄蚊子的感觉。
项目开始之前,实现选择一个脚手架。这个项目用的就是作为其项目脚手架。主要基于 Gulp + Webpack + Babel + BrowserSync 进行开发和部署。(ps:目前脚手架先上 github 弄下来,pasturn 和 Aresn 正在开发 omi-cli,不久就要发布了)
Gulp 用来串联整个流程,Webpack + Babel 让你可以写 ES6 和打包,BrowserSync 用来帮你刷浏览器,不用 F5 了。
这里需要注意的是,BrowserSync 会启动 localhost:3000 导致你的 AJAX 请求跨域而无法拿到数据。
所以,要使用 Fiddler 并配置 Extention:
目录结构也是和一样。
组件全放在 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 个方法:
其他两个方法的 render 和 style 用来生成组件的 html 和局部 CSS,不再叙述。
render 里面使用了模板引擎;
如果使用 omi.lite.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 让代码真心方便简洁~~~
来源: http://www.cnblogs.com/iamzhanglei/p/6430457.html