若是以爲事情太複雜無從下手,就分紅許多許多個小步進行好了 ---尼古斯拉
小程序下載地址html
安裝過程很是簡單直接下一步就好了。git
app.json 文件以下:github
{ "pages":[ "pages/index/index", "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle":"black" }, "tabBar": { "color": "#858585", "selectedColor": "#000000", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/index/index", "text": "首頁", "iconPath": "/img/tab_home.png", "selectedIconPath": "/img/tab_home-active.png" }, { "pagePath": "pages/logs/logs", "text": "日誌", "iconPath": "/img/tab_category.png", "selectedIconPath": "/img/tab_category-active.png" } ] } }
先看效果:web
點擊
json
發生了什麼?咱們發現首頁有一個搜索欄,其實這至關於一個導航的圖標,點擊之後才跳轉到了真正的搜索頁面。因爲他們的樣式是同樣的,咱們打算要開發一個組件,而後在各自的頁面引用這個組件,就能夠達到代碼複用的目的。這個很重要,由於小程序主打的就是"輕型應用",整個程序不超過2M,因此代碼能省則省。兩個頁面除了樣式大致差很少,可是又有不同的地方,這就涉及了邏輯判斷,如何作呢?且看我慢慢道來。小程序
開發searchbar組件備用api
首頁有了,導航的這個圖標得咱們本身開發吧,如何作呢?
點擊小加號->新建目錄->右鍵新建component,填上值就能夠了。
小加號在哪呢?數組
而後就是這個組件內容的開發啦,這裏只貼出核心部分,樣式什麼的的我稍後上傳到github,本身看。網絡
<view class="searchbar"> <navigator url='/pages/search/search' class='search-navigator'></navigator> </view>
咱們使用<navigator>
標籤告訴小程序跳轉到url
所指的頁面組件作好了,接下來咱們應用它。app
首頁應用searchbar組件
在index.json
文件中告訴小程序咱們要使用這個組件
{ "usingComponents": { "searchbar": "/components/searchbar/searchbar" } }
接下來打標籤直接使用,爲了區分使用view
做個標記
<searchbar></searchbar> <view>這是首頁</view>
而後咱們還須要新建一個search.wxml
頁面及其組件,如何新建呢?
還記得以前咱們說過的app.json
文件嗎,這個文件有個pages
屬性管理全部的頁面,如今咱們增長一條pages/search/search
保存刷新,頁面就自動建好了。search.wxml
引用組件的過程和首頁相同,這裏不過多敘述。
"pages":[ "pages/index/index", "pages/search/search", "pages/logs/logs" ]
最後咱們要實現的是在首頁只顯示導航的圖標,在搜索欄顯示一個輸入框,如何作呢?
找到searchbar.wxml
頁面,多加一個view
、它裏面是一個輸入框,輸入框樣式什麼的本身看,不是本文的重點。
<view class="searchbar"> <navigator url='/pages/search/search' class='search-navigator'></navigator> <view class="search-input-group"> <input class='search-input' placeholder='搜索' bindinput='onInputEvent'></input> </view> </view>
接下來咱們作的事情就是,若是是首頁引用這個組件就顯示圖標,搜索頁引用就顯示輸入框。
找到searchbar.js
文件,在組件的屬性列表properties
這一項新增一個屬性isnavigator
,它的類型是 Boolean
,初始值爲false
。
properties: { isnavigator: { type: Boolean, value: false } }
接下來在searchbar.wxml
應用這個屬性
<view class="searchbar"> <navigator wx:if="{{isnavigator}}" url='/pages/search/search' class='search-navigator'></navigator> <view wx:else class="search-input-group"> <input class='search-input' placeholder='搜索' bindinput='onInputEvent'></input> </view> </view>
表示屬性值爲ture
的時候就顯示圖標,false
的時候就顯示輸入框。
接下來咱們要去index.wxml改下插件的屬性值
<searchbar isnavigator="{{true}}"></searchbar>
因爲默認值爲false、search.wxml就不用改了。這樣,首頁加載就顯示圖標,搜索頁加載就顯示輸入框。別看簡單,初次開發思路不清晰也挺費勁,容易亂。就這樣咱們就學會了組件化思想和使用邏輯判斷,是否是很厲害呢。
完成效果以下
分析:首頁的主要部分爲紅色大框部分,其中包括了標題、主體、星星三個小框框,只要把這個大框開發好了,其他的都是這個大框的重複。咱們打算把這個大框開發成一個獨立的組件,因爲星星在後面其餘地方有複用,星星這個部分咱們也開發成一個獨立的組件。
首頁組件的開發
在components目錄下新建目錄indexmodule
,再新建component
接下進行indexmodule.wxml
頁面的編寫。
<view class='module-group'> <view class='module-top'> <view class='module-title'>電影</view> <navigator class='module-more'>更多</navigator> </view> <scroll-view class='module-scroll-view'> <navigator class='item-navigator' url=""> <view class='item-group'> <view class='thumbnail-group'> <image class='thumbnail' src='https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544987866.webp'></image> </view> <view class='item-title'>阿麗塔</view> </view> </navigator> </scroll-view> </view>
在`index.json告訴小程序咱們要使用這個組件
{ "usingComponents": { "searchbar": "/components/searchbar/searchbar", "indexmodule": "/components/indexmodule/indexmodule" } }
在index.wxml
引入
<indexmodule></indexmodule>
效果以下:
頁面包括了標題和滾動條,還差星星,下面咱們開發星星組件,並在這個頁面引入。
代碼以下:
<view class='rate-group'> <image wx:for="{{[1,2,3]}}" src="/images/rate_light.png"></image> <image src='/images/rate_half.png'></image> <image src='/images/rate_gray.png'></image> <text>7.0</text> </view>
接下來在indexmodule.json
告訴小程序咱們要引用這個組件。
{ "component": true, "usingComponents": { "stars": "/components/stars/stars"} }
最後在indexmodule.json
直接引用就行了
<navigator class='item-navigator' url=""> <view class='item-group'> <view class='thumbnail-group'> <image class='thumbnail' src='https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544987866.webp'></image> </view> <view class='item-title'>阿麗塔</view> </view> <stars></stars> </navigator>
效果以下:
<stars rate="9"></stars>
打開stars.js
文件,添加一個屬性rate
,類型爲Number
,默認值爲0
properties: { rate: { type: Number, value: 0 } }
處理邏輯:
lifetimes: { attached: function () { var that = this; var rate = that.properties.rate; var intRate = parseInt(rate); var light = parseInt(intRate / 2); var half = intRate % 2; var gray = 5 - light - half; var lights = []; var halfs = []; var grays = []; for (var index = 1; index <= light; index++) { lights.push(index); } for (var index = 1; index <= half; index++) { halfs.push(index); } for (var index = 1; index <= gray; index++) { grays.push(index); } var ratetext = rate && rate > 0 ? rate.toFixed(1) : "未評分" that.setData({ lights: lights, halfs: halfs, grays: grays, ratetext: ratetext }); } }
動態渲染出來:
<image wx:for="{{lights}}" src="/images/rate_light.png"></image> <image wx:for="{{halfs}}"src='/images/rate_half.png'></image> <image wx:for="{{grays}}"src='/images/rate_gray.png'></image>
在index.js
中使用wx.request
請求數據:
onLoad: function () { var that=this; wx.request({ url: 'https://m.douban.com/rexxar/api/v2/subject_collection/movie_showing/items?count=7', success: function (res) { var movies = res.data.subject_collection_items; that.setData({ movies: movies }); console.log(movies); } }) }
在indexmodule.js
添加屬性,它的類型爲數組類型:
items:{ type:Array, value:[] }
在index.wxml
給這個屬性賦值:
<indexmodule items="{{movies}}"></indexmodule>
而後在indexmoduel.wxml
就可使用啦:
<navigator class='item-navigator' url="" wx:for="{{items}}" wx:key="{{item.title}}"> <view class='item-group'> <view class='thumbnail-group'> <image class='thumbnail' src='{{item.cover.url}}'></image> </view> <view class='item-title'>{{item.title}}</view> </view> <stars rate="{{item.rating.value}}"></stars> </navigator>
效果以下:
框架會確保他們被從新排序,而不是從新建立,以確保使組件保持自身的狀態,而且提升列表渲染時的效率。
結論:for 循環的時候必需要有wx:key以保持本身的特徵和狀態,key 的值能夠是字符串或者數字,並且須要在列表中是惟一的。在寫的時候,直接寫這個 property 的名字就能夠了,若是循環中的 item 自己,好比說循環的是一個數組,使用*this指代自己就能夠了。
若是在個點邏輯轉不過來、或是效果沒出來,先放下好了,回過頭來再看忽然就明白了 --尼古斯拉
點擊更多,效果以下:
分析:因爲列表中每一項和首頁滑動欄的每一項是同樣的,所以咱們抽取出來,單獨做爲一個itemview
組件。而後在首頁和列表頁均可以調用,達到複用的目的。
頁面佈局很簡單,把以前在indexmodule.wxml寫過的複製過來就好了
<navigator class='item-navigator' url=""> <view class='item-group'> <view class='thumbnail-group'> <image class='thumbnail' src='{{item.cover.url}}'></image> </view> <view class='item-title'>{{item.title}}</view> <stars rate="{{item.rating.value}}"></stars> </view> </navigator>
記得在itemview.json告訴小程序咱們要使用星星組件哦
"usingComponents": { "stars": "/components/stars/stars" }
最後在indexmodule.wxml使用這個組件
"usingComponents": { "itemview": "/components/itemview/itemview" }
<scroll-view class='module-scroll-view' scroll-x="{{true}}"> <itemview wx:for="{{items}}" wx:key="{{item.title}}" item="{{item}}"></itemview> </scroll-view>
<searchbar isnavigator="{{true}}"></searchbar> <view class='container'> <itemview wx:for="{{items}}" wx:key="{{item.title}}" item="{{item}}"></itemview> </view>
"usingComponents": { "searchbar": "/components/searchbar/searchbar", "itemview": "/components/itemview/itemview" }
頁面構成很是簡單,不過多敘述。
咱們要作的事情很簡單,把全部的網絡請求放在一個文件統一完成,而後根據不一樣的參數在不一樣的頁面完成渲染。
一、在utils目錄新建urls.js
文件統一存放因此url,記得導出。
const globalUrls = { movieList: "https://m.douban.com/rexxar/api/v2/subject_collection/movie_showing/items", tvList: "https://m.douban.com/rexxar/api/v2/subject_collection/tv_hot/items", showList: "https://m.douban.com/rexxar/api/v2/subject_collection/tv_variety_show/items" } export { globalUrls }
在utils目錄新建network.js
完成全部的請求,須要導入urls.js
的globalUrls
,完成業務處理後記得導出。
import { globalUrls } from "urls.js"; const network = { // 獲取電影列表 getMovieList: function (params) { params.url = globalUrls.movieList; this.getItemList(params); }, //獲取電視劇列表 getTVList: function (params) { params.url = globalUrls.tvList; this.getItemList(params); }, // 獲取綜藝列表 getShowList: function (params) { params.url = globalUrls.showList; this.getItemList(params); }, getItemList: function (params) { var count = params.count ? params.count : 7; wx.request({ url: params.url, data: { count: count }, success: function (res) { var items = res.data.subject_collection_items; if (params && params.success) { params.success(items); } } }); } } export { network }
定義了四個方法,其中getItemList
是幹活的方法,其餘的根據不一樣的url
來引用這個方法,即可以獲取不一樣的數據。
首頁引用數據:
首頁引用數據是在index.js
中的onLoad
中寫代碼,記得要引用network.js
的network
。
import { network } from "../../utils/network.js"; //獲取應用實例 Page({ data: { }, onLoad: function (options) { var that = this; // 電影 network.getMovieList({ success: function (movies) { that.setData({ movies: movies }); } }); // 電視劇 network.getTVList({ success: function (tvs) { that.setData({ tvs: tvs }); } }); // 綜藝 network.getShowList({ success: function (shows) { that.setData({ shows: shows }); } }); } })
數據渲染很簡單,參照前面就好了,就是把變量的值傳過去而已,不羅嗦。
列表頁引用數據:
<!-- 電影 --> <indexmodule title="電影" items="{{movies}}" moreurl="/pages/list/list?type=movie"></indexmodule> <!-- 電視劇 --> <indexmodule title="電視劇" items="{{tvs}}" moreurl="/pages/list/list?type=tv" ></indexmodule> <!-- 綜藝 --> <indexmodule title="綜藝" items="{{shows}}" moreurl="/pages/list/list?type=show"></indexmodule>
咱們在首頁index.wxml
給moreurl
屬性賦值時添加了一個一個參數type
做爲區分,稍候既能夠在請求數據的list.js
拿到type
的值,而後就能夠根據type
的值不一樣從而請求不一樣的數據。
在list.js
請求數據的代碼以下:
onLoad: function (options) { var that = this; var type = options.type; var title = ""; wx.showLoading({ title: '正在加載中...', }) if (type === "movie") { // 請求電影的數據 network.getMovieList({ success: function (items) { that.setData({ items: items }); wx.hideLoading(); }, count: 1000 }); title = "電影"; } else if (type === 'tv') { // 請求電視劇的數據 network.getTVList({ success: function (items) { that.setData({ items: items }); wx.hideLoading(); }, count: 1000 }); title = "電視劇"; } else { // 請求綜藝的數據 network.getShowList({ success: function (items) { that.setData({ items: items }); wx.hideLoading(); }, count: 1000 }); title = "綜藝"; } wx.setNavigationBarTitle({ title: title, }) }
記得要引入network
,怎麼引不用囉嗦了吧。
這樣,列表頁以及網絡重構就所有完成了,剛開始作可能有些陌生,不要緊,慢慢來。
小插曲:
點開更多發現怎麼這樣子的?
查資料發現是flex-wrap:wrap
控制水平折行排列的,可我也寫了呀,哪確定是什麼地方影響了。
後來發現
這裏也定義了一個container
樣式,刪掉就行了。這個教訓告訴咱們知識必定要全面呀,知識全面思路才清晰。