基於wexplus開發app是來新公司才接觸的,以前只是用過weex體驗過寫demo,當時就被用vue技術棧來開發app的開發體驗驚豔到了,這個開發體驗比react native要好不少,對於我這個純web前端來講簡直不要太好!html
weexplus是基於weex官方的二次開發版本,旨在解決weex官方配置麻煩、性能很差、開發體驗很差等問題。weexplus框架是這邊同事根據實際的項目抽離出來的開源框架,已經幫咱們趟過不少坑了,具體組件用法在此再也不贅述,link-放出文檔。本文僅爲本人視角開發一個吉他學習app的踩坑之路記錄,記下以避免後面再踩坑。前端
文章可能會很長,在此分幾篇文章來寫,先佔個坑:vue
app的ui界面與h五、小程序公用一套,因此作出來的界面也是基本同樣,這裏感謝如下楊伯伯提供的設計稿。node
$ npm install weex-toolkit -g // -g表示全局安裝,下同
$ npm install weexplus -g
$ 瀏覽器訪問 https://github.com/weexplus/boilerplate,下載壓縮包獲得文件boilerplate-master.zip; $ 解壓boilerplate-master.zip獲得文件夾boilerplate-master; $ cd到跟boilerplate-master平級的目錄; $ weexplus rename loveguitar com.loveguitar.23jt loveguitar; $ cd loveguitar $ npm install //安裝依賴包 $ npm run dev $ weexplus start //運行改命令須要另外開一個終端,運行成功後谷歌瀏覽器會跳出一個新頁面,必須安裝谷歌瀏覽器 $ 下載安卓apk調試包(真機掃碼調試)地址 https://pan.baidu.com/s/16kJfMuyXX-Y_yhm5fHt79Q
至此,weexplus開發環境基本搭建完畢,若是須要打包安卓、ios的話,與原生開發同樣,自行百度便可解決。react
如圖爲weexplus腳手架項目目錄結構圖,咱們日常開發主要在src
目錄裏寫代碼,能夠看到該目錄與vue項目目錄結構基本差很少。ios
在寫代碼前能夠把腳手架裏無用的代碼刪除掉,留下component
文件夾便可。先作的第一件事我的建議是依照原型或者設計稿的業務邏輯在src/busi
文件夾中按照業務模塊建好文件夾(以愛尚吉他爲例):git
map:琴行地圖功能模塊,裏面分爲琴行地圖首頁、琴行詳情、琴行導航 news:文章模塊,裏面分爲文章列表、文章詳情、標籤列表 search:文章搜索模塊 video:視頻教程模塊,裏面分爲視頻模塊首頁,視頻列表、視頻詳情
子曰:「工欲善其事,必先利其器。」在寫首頁的代碼前在此安利一款切圖標註工具--藍湖, 大大提升設計師和開發的工做效率,具體使用參見官網介紹便可http://sos.lanhuapp.com/#/。github
以上爲首頁的設計圖,先來分析一下頁面結構,看看哪些能夠復而且能夠封裝爲公共組件。如圖所示能夠分爲以下幾個模塊:web
1(banner模塊),在componet文件夾下新建my-banner.vue文件 2(模塊標題),在componet文件夾下新建my-title.vue文件 3(菜單模塊),在componet文件夾下新建my-nav.vue文件 4(文章列表模塊兩個類型)在componet文件夾下新建news-item.vue文件
按照vue的規範分別在componet文件夾下新建my-banner.vue
、my-title.vue
·my-nav.vue
、news-item.vue
四個文件。數據庫
//src/component/my-banner.vue <template> <div class="banner-box"> <slider class="slider" :style="{'height':height,'width':width}" interval="1500" @change="onchange"> <div class="frame" :style="{'height':height,'width':width}" v-for="(item,index) in bannerList" :key="index"> <image :style="{'height':height,'width':width}" class="image" resize="cover" :src="item.pic" /> </div> <indicator class="indicator"></indicator> </slider> </div> </template>
這裏用到了weex官方的slider
和indicator
組件,具體的屬性用法參見weex文檔slider用法。考慮到輪播圖的尺寸不固定,在組件中暴露height(圖片高度)
和width(圖片寬度)
兩個屬性提供給父組件傳入。
在此注意幾個問題: 1.注意圖片標籤的寫法與web中使用vue稍有不一樣,web中是img,在weex中用image; 2.weex中不支持padding、margin、border屬性值的簡寫,如不支持padding:10px 和border:1px solid #dcdcdc這樣的寫法。
//component/my-title.vue <template> <div class="about-title"> <text class="title-text">{{title}}</text> <div v-if="url!=null&&url!=''" @click="goto(url)" class="more"> <text>更多</text> <image src="http://hurely.u.qiniudn.com/20180601152782173548498.png" class="form-icon-r"/> </div> </div> </template>
樣式方面沒什麼好說的,考慮到有些標題是沒有跳轉更多的,須要作一下判斷爲空的狀況。
在此注意幾個問題: 1.注意在weex中文字須要使用text標籤,考慮到後續可能會移植爲web或者小程序, text標籤最好用class來控制樣式; 2.weex默認支持flex佈局,考慮到後續可能會移植爲web或者小程序,在須要 用到flex佈局的地方寫上display:flex屬性。
//componet/my-nav.vue <template> <div class="nav"> <div class="nav-item" @click="goto(item.url)" v-for="(item,index) in navList" :key="index"> <image class="nav-icon" :style="{'width':width,'height':height}" :src="item.src" /> <text class="nav-text">{{item.text}}</text> </div> </div> </template>
樣式方面沒什麼說的,考慮到會跳轉不一樣的頁面,注意在跳轉方法裏作判斷便可。
//componet/news-item.vue <template> <div v-if="type==1"> <div class="item-box" @click="click"> <div class="item-left"> <text class="left-text">{{item.title}}</text> <div class="left-line"></div> <text class="left-time">{{item.pubdate}}</text> </div> <div class="item-right"> <image :src="item.pic.src" mode="aspectFill" class="litpic" /> </div> </div> </div> <div class="item-box2" v-else-if="type==2" @click="click"> <image :src="item.pic.src" mode="aspectFill" class="litpic2" /> <text class="box2-text">{{item.title}}</text> </div> </template>
能夠看到我標記4的地方有兩處,在組件里加一個type
做爲判斷便可,列表點擊事件經過this.$emit
傳遞到父組件調用。至此首頁四個公共組件封裝完畢,下面開始編寫首頁代碼。
//busi/home.vue <template> <div class="app"> <scroller> <banner-item :bannerList=bannerList></banner-item> <div class="home-nav border"> <title-item title="熱門欄目" url=""></title-item> <div class="nav-items"> <div class="nav-item" v-for="(item,index) in navList" :key="index" @click="goto(item.url)"> <image mode="aspectFit" :src="item.pic" class="nav-icon"/> <text class="nav-text">{{item.title}}</text> </div> </div> </div> <div class="home-news border"> <title-item title="熱門文章" url="../news/list"></title-item> <div v-for="(item,index) in newsItems" :key="index"> <homenews-item type=1 @click="gotonews(item.id)" :item="item" ></homenews-item> </div> </div> <title-item title="熱門專輯" more="../video/index"></title-item> <div class="hot-box"> <video-item v-for="(ite,index) in videoitems" :key="index" @click="gotovideo(ite)" :item="ite" type=2 ></video-item> </div> <support-item></support-item> </scroller> </div> </template>
樣式方面無需說明,這裏說一下數據請求的封裝。分別在busi/util文件夾新建文件request.js
和api.js
(非必須),其中request.js基於fly庫封裝(考慮到weex官方的數據請求庫有點坑,在此棄用),便於管理後端接口建議在api.js
文件中統一管理。
如下爲fly.js
庫的封裝,具體使用參照fly.js
官方文檔,若是須要增長登陸攔截什麼的,能夠在fly.interceptors.request.use
中增長便可。
//request.js var Fly = require("flyio/dist/npm/weex"); var fly = new Fly; //bmob雲數據庫的配置,非必須 const bmobConfig = { applicationId:'applicationId', restApiKey:'restApiKey', secretKey:'secretKey', masterKey:'masterKey' } var progress = weex.requireModule("progress") var modal = weex.requireModule("modal") //添加請求攔截器 fly.interceptors.request.use((request)=>{ progress.show(); //給全部請求添加自定義header request.headers["X-Tag"]="flyio"; request.headers['X-Bmob-Application-Id'] = bmobConfig.applicationId; request.headers['X-Bmob-REST-API-Key'] = bmobConfig.restApiKey; request.headers['Content-Type'] = 'application/json'; //能夠顯式返回request, 也能夠不返回,沒有返回值時攔截器中默認返回request return request; }) //添加響應攔截器,響應攔截器會在then/catch處理以前執行 fly.interceptors.response.use( (response) => { //只將請求結果的data字段返回 progress.dismiss(); return response.data }, (err) => { //發生網絡錯誤後會走到這裏 progress.dismiss(); //return Promise.resolve("ssss") } ) module.exports = fly;
如下爲後端接口統一管理文件api.js
/** * @description 請求地址 */ const baseUrl = 'http://baidu.com/'; const urls = { videoList:'videoList', videoContent:'videoContent', amapGetaddress:'amapGetaddress',//高德地圖經緯度轉地址 home: baseUrl + 'home',//首頁 categoryIndex:baseUrl+'categoryIndex',//菜單分類 type=list顯示 categoryList:baseUrl+'categoryList',//參數cid經過categoryIndex得到 page爲分頁 tagList:baseUrl+'tagList',//標籤列表&id=7656&page=1 articleDetails:baseUrl+'articleDetails',//文章詳情 about:'about',//關於 search:baseUrl+'search',//&q=周杰倫&page=1 }; export default urls
數據請求實例,用過axios庫的應該很熟悉這種寫法
getData() { const that = this; fly.get(apis.home, {}) .then(res => { let bannerList = []; JSON.parse(res).article_hot.data.map((item,index)=>{ item.pic = item.pic.src; bannerList.push(item) }) that.bannerList = bannerList; that.newsItems = JSON.parse(res).article_list; }) .catch(error => {}); }
基於同一套ui開發出來的愛尚吉他微信小程序版已經上線喜歡彈吉他的小夥伴能夠關注一波