小程序是一種新的開放能力,開發者能夠快速地開發一個小程序。小程序能夠在微信內被便捷地獲取和傳播,同時具備出色的使用體驗。css
本人是一名忠實的Android研發,沒有出過軌,對於css html js等僅僅是隻知其一;不知其二,這是在業餘之際以爲想接觸一下web,其實剛出來小程序那時候就嘗試過,不過因爲工做較忙,中途放棄了,現在小程序發展的仍是挺快的,仍是特別想學下前端知識.一是總結,二是分享給有須要的人,節省時間,少百度一些.html
不說廢話,直接說有用的,開始吧.前端
註冊:小程序註冊(不能是微信開放平臺的郵箱)android
登陸後, 咱們能夠在菜單 「設置」-「開發設置」 看到小程序的 AppID 。git
前往 開發者工具下載頁面 ,根據本身的操做系統下載對應的安裝包進行安裝.github
打開小程序開發者工具,用微信掃碼登陸開發者工具web
選擇小程序項目類型json
填入你申請的APPID 會自動生成一個QuickStart Project 直接進入便可看到一個簡單的小程序小程序
看看項目結構 挺清晰的.微信小程序
至此,第一個小程序已經呈如今你面前,開發工具頂部欄有預覽,你能夠用手機掃描體驗一下.
通過一頓百度和前端的朋友諮詢,發現了目前網上流行的幾款: 微信開發工具、VSCode、Subline、webstom......說多無益,咱們就選朋友推薦的VSCode 其餘的沒用過,暫時不進行對比了.
這裏說明下爲何要有使用這個,正所謂站在前人的肩膀上,可以看的更遠,看到的東西更多,省去了你在造輪子了,
爲了更快更好的開放一款本身的小程序,對於UI有強烈要求的就要用到別人寫好的組件庫了,不爲何,由於我不懂前端,讓我本身寫要學基礎好幾天,不過話說回來,基礎仍是要學的,這裏只是想最快速度瞭解前端和小程序開發總體
若是你有其餘語言的開發基礎,那麼能夠直接進行開發,別怕,咱們邊作邊學,我用了一個星期搞定,你也能夠3天或者1天.下面拿個人練習項目爲例 《學安卓》數據來源 鴻洋大神的網站API 《玩安卓》用於蒐集安卓技術文章及衆多實用工具的,很方便,詳細API能夠查看玩安卓的API文檔
下面咱們就開始第一個頁面的開發 這是效果圖 功能很簡單,banner+列表
##
Page({
/**
* 頁面的初始數據
*/
data: {},
/**
* 生命週期函數--監聽頁面加載
*/
onLoad: function (options) {},
/**
* 生命週期函數--監聽頁面初次渲染完成
*/
onReady: function () {},
/**
* 生命週期函數--監聽頁面顯示
*/
onShow: function () {},
/**
* 生命週期函數--監聽頁面隱藏
*/
onHide: function () {},
/**
* 生命週期函數--監聽頁面卸載
*/
onUnload: function () {},
/**
* 頁面相關事件處理函數--監聽用戶下拉動做
*/
onPullDownRefresh: function () {},
/**
* 頁面上拉觸底事件的處理函數
*/
onReachBottom: function () {},
/**
* 用戶點擊右上角分享
*/
onShareAppMessage: function () {}
})
複製代碼
http://www.wanandroid.com/banner/json
方法:GET
參數:無
複製代碼
可直接點擊查看示例:www.wanandroid.com/banner/json
http://www.wanandroid.com/article/list/0/json
方法:GET
參數:頁碼,拼接在鏈接中,從0開始。
複製代碼
可直接點擊查看示例:www.wanandroid.com/article/lis…。
注意:頁碼從0開始,拼接在連接上。
其中有兩個易混淆的字段:
"superChapterId": 153,
"superChapterName": "framework", // 一級分類的名稱
複製代碼
superChapterId其實不是一級分類id,由於要拼接跳轉url,內容實際都掛在二級分類下,因此該id其實是一級分類的第一個子類目的id,拼接後故可正常跳轉。
附上index.wxml參考代碼:
<view class="swiper-container">
<!--banner輪播組件-->
<swiper class="swiper" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{imgUrls}}" wx:key="*this">
<swiper-item>
<image src="{{item.imagePath}}" mode="{{item.mode}}" class="slide-image" />
</swiper-item>
</block>
</swiper>
</view>
<!--banner文章列表組件-->
<view class="container artical-list">
<block wx:for-items="{{articals}}" wx:for-item="artical" wx:key="*this">
<view class="artical-item" bindtap='goToArticalDetail' data-index="{{index}}">
<text class='artical-item-title'>{{artical.title}}</text>
<wxc-flex class="warp" main="{{item_content_dir}}">
<wxc-flex class="wrap" dir="{{dir}}">
<view>
<text class='artical-item-desc'>做者: </text>
<text class='artical-item-desc_content'>{{artical.author}}</text>
</view>
<view class='category'>
<text class='artical-item-desc'>分類: </text>
<text class='artical-item-desc_content'>{{artical.superChapterName}}/{{artical.chapterName}}</text>
</view>
<view class='category'>
<text class='artical-item-desc'>時間: </text>
<text class='artical-item-desc'>{{artical.niceDate}}</text>
</view>
</wxc-flex>
<image src="{{likesrc}}" style="width: 28px; height: 28px;" mode="{{mode}}" bindtap='onClickAddLike' ></image>
</wxc-flex>
</view>
</block>
</view>
<!--上拉加載更多loading組件-->
<view class="weui-loadmore" hidden="{{isHideLoadMore}}">
<view class="weui-loading"></view>
<view class="weui-loadmore__tips">正在加載</view>
</view>
<!--上拉加載更多無數據提示-->
<view hidden="{{loadingMoreHidden ? true : false}}" class="no-more-photos">沒有更多啦</view>
複製代碼
附上index.js參考代碼:
data裏是數據綁定的關鍵,即佈局中定義的變量和這裏都是對應的,當這裏的值被賦值或變動,影響頁面更新.
使用方法 變量名:默認值 如:imgUrls: []
imgUrls:[] 爲banner的數組來源,在佈局wxml中能夠找到 在wxml中必定是{{}}雙層大括號才能夠.
block爲塊 具體查看文檔介紹
wx:for爲循環列表對應的數據源 在小程序中即爲數組對象
wx:key 爲每一個item的惟一標識
item變量代指爲循環列表默認的其中的元素對象 也能夠指定名稱 如:wx:for-item="{{banner_item}}"
//獲取應用實例
var app = getApp()
Page({
data: {
imgUrls: [],
mode: 'aspectFill',
indicatorDots: true,
autoplay: true,
interval: 3000,
duration: 1000,
articals: [],
curPage: 1,
perPageSize: 20,
pageCount: 59,
isHideLoadMore: false,
loadingMoreHidden: true,
dir:'top',
item_content_dir:'between',
likesrc:'../images/index/like_normal.png'
},
//進入文章詳細頁面
goToArticalDetail: function (e) {
var that = this
var item_index = parseInt(e.currentTarget.dataset.index)
console.log("item_index = " + item_index)
wx.navigateTo({
url: '../index-detail/index-detail?title=' + that.data.articals[item_index].title + '&link=' + that.data.articals[item_index].link
})
},
onLoad: function () {
console.log('onLoad')
//顯示標題菊花
wx.showNavigationBarLoading()
//獲取輪播圖
this.getBanners()
//默認加載第0頁
var curPage = 0
//獲取文章列表
this.getArticals(curPage)
},
onPullDownRefresh: function () {
this.data.curPage = 0
this.getArticals(0)
console.log('下拉刷新')
},
onReachBottom: function () {
console.log('加載更多')
if (!this.data.loadingMoreHidden) {
} else {
this.getArticals(this.data.curPage)
}
this.setData({
loadingMoreHidden: true
})
},
showAddItem: function () {
this.setData({
addVlue: !this.data.addVlue
})
},
getArticals: function (artical_pageindex) {
var that = this
wx.request({
url: 'http://www.wanandroid.com/article/list/' + artical_pageindex + '/json',
data: {
},
method: 'GET',
header: {
'content-type': 'application/json'
},
success: function (res) {
wx.hideNavigationBarLoading()
that.setData({
perPageSize: res.data.data.size,
curPage: res.data.data.curPage,
pageCount: res.data.data.pageCount
})
var articalsTemp = that.data.articals
if (that.data.curPage == 1) {
articalsTemp = []
}
var articals = res.data.data.datas
if (articals.length < that.data.perPageSize) {
console.log('沒有更多了')
that.setData({
articals: articalsTemp.concat(articals),
loadingMoreHidden: false
})
} else {
console.log('有更多可加載')
that.setData({
articals: articalsTemp.concat(articals),
loadingMoreHidden: true,
curPage: that.data.curPage + 1
})
}
}
})
},
getBanners: function () {
var that = this
wx.request({
url: 'http://www.wanandroid.com/banner/json',
data: {
},
method: 'GET',
header: {
'content-type': 'application/json'
},
success: function (res) {
wx.stopPullDownRefresh()
that.setData({
imgUrls: res.data.data
})
}
})
},
//添加文章到個人收藏
onClickAddLike: function(){
}
})
複製代碼
附上index.wcss參考代碼:
/**index.wxss**/
.container {
background-color: #fff;
min-height: 100%;
}
.swiper {
width: 100%;
height: 416rpx;
background-color: #F2f2f2;
}
.swiper-item image{
width: 100%;
height: 416rpx;
}
.slide-image{
width: 100%;
height: 416rpx;
}
.no-more-photos {
text-align: center;
font-size: 24rpx;
padding-bottom: 48rpx;
color: #999;
}
.artical-list {
display: flex;
flex-direction: column;
padding: 40rpx;
}
.artical-item{
border: lightgrey;
border-style: solid;
border-width: 1px;
font-size: 14px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
min-height: 48px;
width: 100%;
padding: 10px;
margin: 10rpx;
}
.artical-subtitle{
display: flex;
flex-wrap: wrap row;
margin-top: 30rpx;
}
.label {
margin-right: 20rpx;
}
.artical-item-title{
font-size: 28rpx;
color: #333333;
font-weight:bold;
}
.artical-item-desc{
font-size: 10px;
color: #ADADAD;
}
.artical-item-desc_content{
font-size: 22rpx;
color: #666666;
}
/* .category{
margin-left: 8px;
} */
/* 加載更多 */
.weui-loading {
margin: 0 5px;
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
-webkit-animation: weuiLoading 1s steps(12, end) infinite;
animation: weuiLoading 1s steps(12, end) infinite;
background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;
background-size: 100%;
}
.weui-loadmore {
width: 65%;
margin: 1.5em auto;
line-height: 1.6em;
font-size: 14px;
text-align: center;
}
.weui-loadmore__tips {
display: inline-block;
vertical-align: middle;
}
複製代碼
附上index.json參考代碼:
說明: 我項目中的UI組件庫引用了MinUI和WeUI,具體使用參照
{
"navigationBarTitleText": "玩安卓",
"usingComponents": {
"wxc-toast": "../../dist/packages/@minui/wxc-toast/dist/index",
"wxc-icon": "../../dist/packages/@minui/wxc-icon/dist/index",
"wxc-label": "../../dist/packages/@minui/wxc-label/dist/index",
"wxc-flex": "../../dist/packages/@minui/wxc-flex/dist/index"
}
}
複製代碼
將下載的weui.wxss文件放至項目的根目錄下 在app.wxss文件中 @import 'weui.wxss'便可使用了.
在app.json中配置便可
"tabBar": {
"selectedColor": "#69C3AA",
"list": [
{
"pagePath": "pages/index/index",
"text": "首頁",
"iconPath": "pages/images/nav/home_normal.png",
"selectedIconPath": "pages/images/nav/home_select.png"
},
{
"pagePath": "pages/nav/nav",
"text": "導航",
"iconPath": "pages/images/nav/nav_normal.png",
"selectedIconPath": "pages/images/nav/nav_select.png"
},
{
"pagePath": "pages/project/project",
"text": "項目",
"iconPath": "pages/images/nav/project_normal.png",
"selectedIconPath": "pages/images/nav/project_select.png"
},
{
"pagePath": "pages/hierarchy/hierarchy",
"text": "體系",
"iconPath": "pages/images/nav/tool_normal.png",
"selectedIconPath": "pages/images/nav/tool_select.png"
},
{
"pagePath": "pages/mine/mine",
"text": "我",
"iconPath": "pages/images/nav/mine_normal.png",
"selectedIconPath": "pages/images/nav/mine_select.png"
}
]
}
複製代碼
示例代碼
說明:
wx.request({
url: 'http://www.wanandroid.com/banner/json',
data: {
},
method: 'GET',
header: {
'content-type': 'application/json'
},
success: function (res) {
wx.stopPullDownRefresh()
that.setData({
imgUrls: res.data.data
})
}
})
複製代碼
示例代碼
說明:
item_index:e.currentTarget.dataset.index 獲取item下標索引 對應wxml中 data-index="{{index}}"
wx.navigateTo({})頁面跳轉
url:'path?xxx=xxx&xxx=xxx....' 頁面路徑+參數拼接
options.xxx 參數接收 在onload中
//進入文章詳細頁面
goToArticalDetail: function (e) {
var that = this
var item_index = parseInt(e.currentTarget.dataset.index)
console.log("item_index = " + item_index)
wx.navigateTo({
url: '../index-detail/index-detail?title=' + that.data.articals[item_index].title + '&link=' + that.data.articals[item_index].link
})
},
複製代碼
/**
* 生命週期函數--監聽頁面加載
*/
onLoad: function (options) {
var that = this
var title = options.title
var link = options.link
that.setData({
artical_title: title,
artical_link : link
})
//動態設置頁面標題---文章標題
wx.setNavigationBarTitle({
title: that.data.artical_title
})
},
複製代碼
1.在app.json中加入開關 只有打開開關 生命週期函數纔會被調用
在這裏說明一個容易犯錯的就是建立page的時候會自動生成四個文件,js文件中也會自動生成模板代碼 生命週期函數都會自動生成,千萬不要本身去在寫一個 不然不報錯 也不觸發.
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#69C3AA",
"navigationBarTitleText": "玩安卓",
"navigationBarTextStyle": "white",
<!--打開下拉刷新-->
"enablePullDownRefresh": true,
<!--打開上拉加載更多-->
"onReachBottomDistance": true,
"backgroundColor": "#69C3AA"
},
複製代碼
onPullDownRefresh: function () {
this.data.curPage = 0
this.getArticals(0)
console.log('下拉刷新')
},
複製代碼
onReachBottom: function () {
console.log('上拉加載更多')
if (!this.data.loadingMoreHidden) {
} else {
this.getArticals(this.data.curPage)
}
this.setData({
loadingMoreHidden: true
})
},
複製代碼
2.主要的上拉加載邏輯控制在getArticals()f方法裏處理的 咱們慢慢分析
getArticals: function (artical_pageindex) {
var that = this
<!--請求文章列表數據-->
wx.request({
url: 'http://www.wanandroid.com/article/list/' + artical_pageindex + '/json',
data: {
},
method: 'GET',
header: {
'content-type': 'application/json'
},
success: function (res) {
wx.hideNavigationBarLoading()
that.setData({
perPageSize: res.data.data.size,
curPage: res.data.data.curPage,
pageCount: res.data.data.pageCount
})
<!--上拉加載更多的關鍵處理-->
<!--定義一個新的文章對象數組 用於裝載拼接全部頁的數據-->
var articalsTemp = that.data.articals
<!--當前若是處於第一頁 那麼清空這個對象數組 只裝載第一頁數據便可-->
if (that.data.curPage == 1) {
articalsTemp = []
}
<!--定義一個新的文章對象數組 賦值於請求返回對應頁碼的文章數據-->
var articals = res.data.data.datas
<!--判斷,若是返回的某頁的數據長度小於每頁的數據長度 說明當前加載的頁是最後一頁了-->
if (articals.length < that.data.perPageSize) {
console.log('沒有更多了')
that.setData({
<!--contcat 意思是向articalsTemp數組中添加數組 -->
articals: articalsTemp.concat(articals),
loadingMoreHidden: false
})
} else {
<!-不然 當前不是最後一頁,向articalsTemp數組中添加數組 -->
console.log('有更多可加載')
that.setData({
articals: articalsTemp.concat(articals),
loadingMoreHidden: true,
<!--當前頁碼增長1 依次類推-->
curPage: that.data.curPage + 1
})
}
}
})
},
複製代碼
{
"component": true,
"usingComponents": {}
}
複製代碼
// dist/wantab.js
Component({
/**
* 組件的屬性列表
*/
properties: {
//標題列表
tablist: {
type: Array,
value: []
},
currentTab: {
type: Number,
value: 0,
observer: function (newVale, oldVal) {
this.setData({
currentTab: newVale
})
}
},
tabname: {
type: String,
value: ''
},
tabtype: {
type: Number,
value: ''
}
},
/**
* 組件的初始數據
*/
data: {
},
/**
* 組件的方法列表
*/
methods: {
onClickNavBar: function (e) {
this.triggerEvent('changeTab', {
currentNum: e.currentTarget.dataset.current
})
}
}
})
複製代碼
<!--dist/wantab.wxml-->
<!-- 自定義tab標籤組件-->
<!-- 標題列表-->
<scroll-view scroll-x="true" class="scroll-view-x" wx:if="{{!tabtype || tabtype==2}}">
<view class="scroll-view-item" wx:for="{{tablist}}" wx:key="*this">
<view class="{{currentTab==(index) ? 'on' : ''}}" bindtap="onClickNavBar" data-current="{{index}}">{{ !tabname ? item.name : item[tabname].name }}</view>
</view>
</scroll-view>
<!--內容列表-->
<slot>
</slot>
複製代碼
/* dist/wantab.wxss */
.scroll-view-x{
background-color: #fff;
white-space: nowrap;
position:fixed;
z-index:10;
top:0
}
.scroll-view-x .scroll-view-item{
display:inline-block;
margin:0 35rpx;
line-height: 33px;
cursor: pointer;
}
.on{
border-bottom: 2px solid #69C3AA;
color: #69C3AA
}
複製代碼
以上就能夠完成一個組件的定義了,下面貼出使用方法
{
"navigationBarTitleText": "項目",
"usingComponents": {
"wantab":"../../dist/component/wantab/wantab"
}
}
複製代碼
使用方式與其餘第三方的組件引入一致,在頁面的.json文件中加入以上代碼便可 注意路徑根據項目而改變
最後放上其餘頁面的效果圖 實現過程基本差很少 剛接觸web 因此多作了些重複的工做,爲了更熟悉使用這些組件和交互
感謝閱讀,若有不對地方請見諒.