微信小程序基礎

簡介

它是什麼

  • 一套用來開發在微信中運行的手機app框架

組成結構

  • 視圖層wxml、樣式文件wxss、邏輯層js
  • 數據的雙向綁定

用戶在視圖上的修改會自動同步到數據模型中去,一樣若是數據模型中的數據發生改變,也會同步到視圖層中。css

獲取AppID

  • 網址:https://mp.weixin.qq.com/
  • 註冊登陸後,在 設置->開發設置->開發者ID 中,可找到AppID(在 微信開發者工具 新建小程序項目時須要)

獲取微信開發者工具

微信開發者工具

  • 左上角模擬器 編輯器 調試器控制編輯器視圖,iphone6 100% WIFI分別爲機型選擇、縮放比例、網絡選擇
  • 編輯區域上面的編譯模式中,普通編輯模式下,每次刷新都是從新載入index刷新,能夠經過添加編譯模式,自定義刷新指定頁面,這樣方便調試
  • 預覽 能夠在手機上預覽小程序
  • 遠程調試 手機能夠訪問小程序,同時編輯器提供控制檯一系列工具用於調試

入門

一套頁面文件

index.js index.json index.wxss index.wxmlhtml

程序配置

即app.json,app.json記錄了一些全局配置:react

{
  "pages": [
    "pages/index/index", //第一項就是進入小程序的首頁
    "pages/calldetail/calldetail",
    "pages/finishcheck/finishcheck",
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#000",
    "navigationBarTitleText": "Hello",
    "navigationBarTextStyle": "white"
  },
  "debug": true
}

pages 頁面路徑
window 頁面的窗口表現
tabBar 底部tab切換
networkTimeout 網絡超時時間
debug 是否開啓debug模式,debug模式下控制檯會打印出詳細調試信息
更多關於app.json,詳細見官方文檔css3

頁面配置

window 頁面的窗口表現es6

  • window配置項中有一項enablePullDownRefresh是否開啓下拉刷新,當設置爲true開啓下拉刷新,backgroundColor頁面背景色在下拉的時候的「縫隙」中才會顯示出來

設置tabBar時要和pages一一對應:json

"pages": [
    "pages/index/index",
    "pages/movie/movie",
    "pages/logs/logs"
],
"tabBar": {
    "color": "#707070",
    "selectedColor": "#129763",
    "list": [
        {
            "text": "首頁",
            "pagePath": "pages/index/index",
            "iconPath": "common/img/main.png"
        },
        {
            "text": "日誌",
            "pagePath": "pages/logs/logs",
            "iconPath": "common/img/logs.png"
        },
        {
            "text": "視頻",
            "pagePath": "pages/movie/movie",
            "iconPath": "common/img/audio.png"
        }
    ]
}

程序實例和頁面實例

app.js中註冊App,會獲得一個程序實例,能夠被其餘頁面訪問小程序

App({ //程序實例
    gldData: {
        a: 1
    }
})

頁面js中註冊Page:數組

Page({ //頁面實例
    //在頁面中獲取應用實例
    //經過getApp全局函數獲取應用實例
    const app = getApp() 
    pageData: { //自定義的頁面數據
        b: 2
    }
    onLoad: function(){
        //在本頁面實例中訪問pageData
        console.log(this.pageData)
    }
})

生命週期

App生命週期

onLaunch onLaunch在小程序運行期間,只會運行一次;程序銷燬(過了一段時間沒有運行,或手動刪除了小程序,再次添加運行)以後,再次啓動就會執行
onShow 每次在後臺切換過來,就會執行
onHide 每次切換到後臺,就會執行緩存

頁面生命週期

onLoad 頁面加載的時候執行,只會執行一次
onReady 頁面第一次渲染完成以後,只會執行一次
onShow 頁面顯示的時候就會執行,能夠執行屢次
onHide 頁面隱藏就會執行,能夠執行屢次
onUnload 頁面卸載的時候執行,只會執行一次
進入小程序首頁,會依次執行onLoad onShow onReady,經過tabBar首頁切換到視頻頁,index不會被卸載,因此不會執行onUnload,可是會執行onHide,進入視頻頁,視頻頁會執行視頻頁的onLoad、onShow、onReady,而後再經過tabBar從視頻頁切換回首頁,視頻頁執行onHide,首頁執行onShow微信

  • tab之間的切換,不會讓頁面從新加載,也就不會卸載,只會隱藏起來

在首頁中加入導航navigator,經過navigator的方式跳轉到視頻頁,首頁仍是會執行隱藏方法onHide,視頻頁左上角出現返回的返回方式,用這種返回方式返回到首頁,視頻頁會發生銷燬執行onUnload

  • 在進行NavigatorTo,跳轉到的那個目標頁面會進行加載(load),跳轉以前的頁面會被隱藏(hide)
  • 回退(NavigatorBack),目標頁面會show(不是加載),回退以前的頁面會被卸載(unload)

頁面渲染

循環渲染

let arr1 = [
    'Matt', 'Moly', 'Joe', 'Hurley'
]
let arr2 = [
    {id: Math.random(), name: 'Matt'},
    {id: Math.random(), name: 'Moly'},
    {id: Math.random(), name: 'Joe'},
    {id: Math.random(), name: 'Hurley'}
]
Page({
    data: {
        arrNames: arr1
        arr2Names: arr2
    }
})

<view wx:for="{{arrNames}}" wx:key="*this">{{item}}</view>
<view wx:for="{{arr2Names}}" wx:key="id">{{item.name}}</view>

均可以循環渲染出name

條件渲染

Page({
    data: {
        score: 80
    }
})
<view wx:if="{{score>70 && score<90}}">等級B</view>
<view wx:elif="{{score<70 && score>30}}">等級C</view>
<view wx:elif="{{score<30}}">等級D</view>
<view wx:else>等級A</view>

block

block並非真正的元素,用來輔助渲染一些平級的元素

<block wx:if="{{score===80}}">
    <view>{{name}}</view>
    <view>{{score}}</view>
    <view>等級A</view>
</block>
<block wx:else>學生不符合要求</block>

使用template

//定義好template,指定name
<template name="hello">
    <view>這是hello行</view>
</template>  
//在頁面中須要用到template的地方使用template,is和name要對應起來,這樣頁面上就能渲染出template中的內容
<template is="hello"></template>
//gender爲動態內容
<template name="hello">
    <view>{{gender}}</view>
</template>
//相似react,這裏傳入變量gender,對象的形式
<template is="hello" data="{{gender: 'female'}}"></template>
<template name="renderList"> //渲染這個模板時就須要names這樣一個數組
    <text>分數:{{score}}</text>
    <block wx:for="{{names}}" wx:key="id">
        <view>{{item.name}}</view>
        <view>哈哈哈</view>
    </block>
</template>
<template is="renderList" data="{{names, score}}"></template>
//js的data中已經定義了names和score
  • 若是template的內容不少,能夠將模板裏的內容單獨出來一個文件(template.wxml),放置的位置視狀況而定;
  • 頁面中引入模板wxml的方式:<import src="template.wxml"/>(這裏template.wxml和頁面wxml在同一目錄下)
  • 若是有公共的頭部(header.wxml),在頁面中的引入方式:<include src="header.wxml"/>

事件

<view bind:tap="onTap">
    <text>點按我能夠打印信息</text>
</view>
onTap(){
    console.log("我是誰")
}

其中,bind:tap中的冒號能夠不寫bindtap
事件函數中額外自帶事件對象參數:

onTap(e){
    console.log(e)
}

clipboard.png

<view bind:tap="onTap" id='view' data-name="容器">
    <text id="text" data-name="文字">點按我能夠打印信息</text>
</view>
onTap(e){
    console.log(e)
}

點擊view空白部分:
clipboard.png

點擊text文字:
clipboard.png

bindtap 不阻止事件冒泡
catchtap 阻止事件冒泡

<view catch:tap="onTap" id='view' data-name="容器">
    <text id="text" data-name="文字">點按我能夠打印信息</text>
</view>

wxss

rpx

rpx規定屏幕寬爲750px
clipboard.png

支持的選擇器

.class #id element element, element :after :before
(好比不支持css3的屬性選擇器)

wxss引入其餘wxss文件

clipboard.png

style和data

<text style='color: {{color}}'>點按我能夠打印信息</text>
data: {
    color: 'red'
}

wxs輔助渲染

<!--index.wxml-->
<view class="container">
  <wxs module="tool">
    function createName(names) {
      return names.split(',')
    }
    module.exports = createName
  </wxs>
  <!-- tool就是wxs導出的函數 -->
  <!-- names爲js中data定義的 -->
  <view wx:for="{{tool(names)}}">{{item}}</view>
</view>
<!--index.js-->
data: {
    names: "Alice,John,Sara,Dave"
}

clipboard.png

wxs也能夠獨立出來:

<!--tool.wxs-->
function createName(names) {
  return names.split(',')
}
module.exports = createName
<!--index.wxml-->
<view class="container">
  <!--tool.wxs和index.wxml在同一目錄下-->
  <wxs src="tool.wxs" module="tool"></wxs>
  <view wx:for="{{tool(names)}}">{{item}}</view>
</view>

wxs不支持es6

setData更新數據與頁面

<view>{{magicNumber}}</view>
<button bindtap='onTap'>點擊</button>
data: {
    magicNumber: Math.random()
},
onTap(){
    //this.data.magicNumber = 8999 //這種更新方式是沒用的
    this.setData({
      magicNumber: Math.random() //相似react更新方式
    })
}

clipboard.png
data變化,視圖不必定更新,這是一個異步的過程。

組件

小程序內置組件

<input type="text" value="hello" bindinput='onInputChange'></input>
onInputChange(e){
    console.log(e)
    //return Math.random()
    //還能夠return出去一個值,控制輸入框東西的顯示
}

在輸入框輸入的時候,控制檯不斷打印事件對象,e.detail.value即爲輸入框內容

自定義組件

自定義組件,能夠單獨出來:
clipboard.png

  • 組件js中使用Component註冊組件
  • Component註冊的是組件,Page註冊的是頁面

clipboard.png
clipboard.png
而後在頁面的json文件中註冊自定義組件:
clipboard.png
在頁面中使用自定義組件:

<!--index.wxml-->
<magic-number></magic-number>

其中,在magicNumber.wxml中

<text>magicNumber自定義組件</text>

因此在index頁面中顯示的就是文字「magicNumber自定義組件」。

  • 自定義組件定義事件要寫在methods中:
<!-- mnum.wxml -->
<text bindtap="onTap">{{magicNumber}}</text>
// mnum.js
Component({
  data: {
    magicNumber: Math.random()
  },
  methods: { //組件裏事件的回調函數要統一寫在methods裏
    onTap(e) {
      this.setData({
        magicNumber: Math.random()
      })
    }
  }
})
  • 自定義組件和父組件通訊
<!-- mnum.wxml -->
<text bindtap="onTap">{{magicNumber}}</text>
// mnum.js
Component({
  data: {
    magicNumber: Math.random()
  },
  methods: { //組件裏事件的回調函數要統一寫在methods裏
    onTap(e) {
      this.setData({
        magicNumber: Math.random()
      })
      // 在自定義組件的事件回調函數中,還能夠另外再觸發事件,名稱自定義,用於頁面中使用
      // 另外能夠攜帶一些參數到頁面(這裏data中的magicNumber)
      this.triggerEvent('getMagicNumber', this.data.magicNumber)
    }
  }
})
// mnum.json
{
  "component": true
}
<!--index.wxml-->
<magic-number bind:getMagicNumber="onGetMagicNumber"></magic-number>
// index.js
onGetMagicNumber(e){
    console.log(e)
}

點擊index中顯示的自定義組件文字,控制檯打印處相關信息:
clipboard.png

點擊文字頁面取整顯示:

<!-- mnum.wxml -->
<text bindtap="onTap">{{magicNumber}}</text>
<!--mnum.js-->
Component({
  data: {
    magicNumber: Math.random()
  },
  methods: { //組件裏事件的回調函數要統一寫在methods裏
    onTap(e) {
      this.setData({
        magicNumber: Math.random()
      })
      // 在自定義組件的事件回調函數中,還能夠另外再觸發事件,名稱自定義,用於頁面中使用
      // 另外能夠攜帶一些參數到頁面(這裏data中的magicNumber)
      this.triggerEvent('getMagicNumber', this.data.magicNumber)
    }
  }
})
 <!--mnum.json-->
{
  "component": true
}
<!--index.wxml-->
<magic-number bind:getMagicNumber="onGetMagicNumber"></magic-number>
<view>{{num}}</view>
// index.js
Page({
  data: {
    num: null
  },
  onGetMagicNumber(e){
    this.setData({
      //e.detail即爲那個值
      num: Math.floor(e.detail*1000)
    })
  }
})

點擊文字,index頁面中的{{num}}也跟着變化,可是在頁面初始狀態,{{num}}顯示的是null,爲了讓{{num}}與自定義組件中的隨機數一致,在自定義組件的生命週期函數中:
clipboard.png

自定義組件的自定義屬性要小寫,並用烤串形式:

<!-- mnum.wxml -->
<text>{{nowIn}} is here!</text>
// mnum.js
Component({
  properties: {
    // js爲駝峯式,頁面中爲烤串式
    nowIn: String
  },
  attached(){
    //組件中經過this.data獲取到properties進而獲取到nowIn
    console.log(this.data)
  }
})
<!--mnum.json-->
{
  "component": true
}
<!--index.wxml-->
<magic-number now-in="Index"
  bind:getMagicNumber="onGetMagicNumber">
</magic-number>

頁面顯示爲Index is here!,控制檯打印信息爲{nowIn: "Index"}

路由

小程序裏兩種方式實現導航:navigator 使用API進行導航

navigator

具體參數可在官網查閱 關於navigator

open-type的屬性值——
navigate 跳轉到
switchTab 以tab方式切換頁面
navigateBack 頁面回退
redirect 重定向
reLaunch 從新加載url頁面,頂部不會出現回退按鈕

<navigator url='/pages/movie/movie'
          open-type='navigate'
>到movie</navigator>
<!-- open-type的默認值爲navigate -->
<navigator url='/pages/about/about'>到about</navigator>

navigate(跳轉到)navigator方式,頂部會出現回退的樣式:
clipboard.png

<navigator url='/pages/movie/movie' open-type='switchTab'>以tab方式切換到movie頁</navigator>

<!-- 要實現以tab方式切換頁面,在app.json中要配合寫上tab的配置項 -->

<navigator open-type='navigateBack'>回退</navigator>
<!--index.wxml-->
<view>首頁</view>
<navigator url='/pages/about/about'>到about</navigator>
<!--pages/about/about.wxml-->
<view>about頁</view>
<navigator url='/pages/movie/movie' open-type='redirect'>重定向到movie頁</navigator>
<!--pages/movie/movie.wxml-->
<view>movie頁</view>
<navigator url="/pages/about/about">去about</navigator>

從首頁進入about頁,在about頁重定向到movie頁,點擊頂部的回退,直接回退到首頁,而不是about頁 index-about-在about頁重定向到movie頁-到movie頁後點擊頂部回退-直接回到index頁
clipboard.png
clipboard.png
clipboard.png
clipboard.png

<!--index.wxml-->
<view>首頁</view>
<navigator url='/pages/about/about'>到about</navigator>
<!--pages/about/about.wxml-->
<view>about頁</view>
<navigator url='/pages/movie/movie' open-type='reLaunch'>reLaunch movie頁</navigator>
<!--pages/movie/movie.wxml-->
<view>movie頁</view>
<navigator url="/pages/about/about">去about</navigator>

在首頁進入about頁,在about頁以reLaunch的方式進入movie頁,movie頁就是小程序當前加載的惟一頁面 index-about-在about頁以reLaunch方式進入movie頁-movie頁,當前小程序加載的惟一頁面,頂部沒有返回按鈕
clipboard.png
clipboard.png
clipboard.png

使用API進行導航

navigate wx.navigateTo(OBJECT) 跳轉到
redirect wx.redirectTo(OBJECT) 重定向
switchTab wx.switchTab(OBJECT) 跳轉到某個tab
navigateBack wx.navigateBack(OBJECT) 回退
reLaunch wx.reLaunch(OBJECT) 重加載

<!--index.wxml-->
<view>首頁</view>
<view bindtap='onGotoMovie'>使用API方式跳轉到movie</view>
// index.js
Page({
  onGotoMovie(){
    wx.navigateTo({
      url: '/pages/movie/movie',
    })
  }
})

點擊便可以navigate的方式跳轉到movie頁

受權相關API

受權方式:
用戶信息 (受權button)
其餘信息受權 (wx.authorize(OBJECT)先進行受權直接獲取信息,未受權會先進行受權)

<!--index.wxml-->
<!-- 點擊出現用戶受權彈框,點擊取消或者肯定會執行回調函數 -->
<!-- onGetUserInfo即爲執行的回調 -->
<button open-type='getUserInfo' bindgetuserinfo='onGetUserInfo'>獲取用戶信息</button>
// index.js
Page({
  onGetUserInfo(e){ //接收一個事件對象,將其打印出來
    console.log(e)
  }
})

點擊按鈕,用戶出現受權彈窗:(以前進行過受權操做可先清除受權數據)
clipboard.png
clipboard.png
clipboard.png
e.detail.userInfo爲用戶的一些基本信息

小程序與小遊戲獲取用戶信息接口調整

<!--index.wxml-->
<button bindtap='onAuthLocation'>受權位置</button> 
// index.js
Page({
  onAuthLocation(){
    wx.authorize({ //只是進行受權
      scope: 'scope.userLocation',
      success: msg=>console.log(msg, 'location success'),
      fail: e=>console.log(e, 'location fail')
    })
  }
})

點擊按鈕,出現受權彈窗,根據用戶的選擇,會執行success或者fail的回調:
clipboard.png
以點擊容許爲例,控制檯打印爲:
clipboard.png

<!--index.wxml-->
<button bindtap='onGetLocation'>獲取位置</button> 
// index.js
Page({
  onGetLocation(){
    wx.getLocation({ //獲取到受權後的信息
      success: msg=>console.log(msg, "位置"),
      fail: e=>console.log(e, "沒獲取到位置")
    })
  }
})

點擊按鈕:
clipboard.png
選擇肯定,控制檯就會打印出地理信息相關信息:
clipboard.png

<!--index.wxml-->
<button bindtap='onGetSetting'>獲取受權信息</button> 
// index.js
Page({
  onGetSetting(){
    wx.getSetting({ //微信提供這樣一個API用於告訴哪些信息受權了哪些信息沒有受權
      success: msg => console.log(msg, "受權相關信息"),
    })
  }
})

clipboard.png
clipboard.png
clipboard.png
clipboard.png
clipboard.png

<!--index.wxml-->
<button bindtap='onGotoSetting'>打開受權信息面板</button> 
// index.js
Page({
  onGotoSetting(){
    wx.openSetting({
      success: msg=>console.log(msg, "設置完成")
    })
  }
})

點擊能夠進入受權面板:
clipboard.png

使用緩存

微信裏能夠同步或者異步地緩存數據

<!--index.wxml-->
<button bindtap='onCache'>緩存數據</button>
// index.js
Page({
  onCache(){
    wx.setStorage({
      key: 'name',
      data: {p1: 'Matt'}, //data能夠指定字符串,也能夠指定對象
      success: ()=>{
        wx.getStorage({
          key: 'name',
          success: data=>{
            console.log(data)
          }
        })
      }
    })
  }
})

點擊按鈕,便可實現緩存:
clipboard.png
同時能夠取到緩存中name爲key的緩存數據,在控制檯打印出來:
clipboard.png
以上設置緩存的方式是異步的。
如下爲同步設置緩存的方式:

<!--index.wxml-->
<button bindtap='onCache'>緩存數據</button>
// index.js
Page({
  onCache(){
    wx.setStorageSync('names', 'Hurley')
    let ns = wx.getStorageInfoSync('names')
    console.log(ns)
  }
})

點擊按鈕,緩存中寫入names:
clipboard.png
並在控制檯打印出:
clipboard.png

<!--index.wxml-->
<view>{{name}}</view>
<button bindtap='onSet'>設置緩存數據</button>
<button bindtap='onGetName'>獲取name</button>
<button bindtap='onRemoveName'>移除name</button>
// index.js
Page({
  data: {
    name: 'hello'
  },
  onSet(){
    wx.setStorageSync('name', 'Hurley')
  },
  onGetName(){
    let n = wx.getStorageSync("name")
    console.log(n)
    if(n){
      this.setData({
        name: n
      })
    }
  },
  onRemoveName(){
    //緩存中key爲「name」的緩存被移除
    wx.removeStorageSync('name') 
  }
})

點擊「設置緩存數據」,緩存中寫入key爲「name」的緩存;
而後點擊「獲取name」,從緩存中獲取到key爲「name」的value值,並更新到data中的name,在視圖中{{name}}也會更新;
而後點擊「移除name」,緩存中key爲「name」的緩存數據被移除。

請求與反饋

設置不校驗域名

<!--index.wxml-->
<button bindtap='onReq'>請求服務</button>
// index.js
Page({
  onReq(){
    wx.request({
      url: 'http://localhost:3000/hello',
      data: {
        name: 'Joe'
      },
      method: 'POST',
      success: data=>{
        console.log(data)
      }
    })
  }
})

點擊按鈕,控制檯出現報錯:
clipboard.png
所以,在小程序裏進行請求須要進行相應配置:
clipboard.png
這樣就能夠經過接口請求到數據,快速調試時設置不校驗域名,能夠請求到數據

請求過程當中的反饋

clipboard.png
clipboard.png

相關文章
相關標籤/搜索