国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

這篇具有很好參考價(jià)值的文章主要介紹了原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

小程序的基本使用

小程序文件類型

小程序主要提供了 4 種文件類型:

類型名稱 作用 是否必須存在
.wxml 用于頁面的布局結(jié)構(gòu),相當(dāng)于網(wǎng)頁中 .html 文件
.wxss 用于頁面的樣式,相當(dāng)于網(wǎng)頁中的 .css 文件
.js 用于頁面的邏輯
.json 用于頁面的配置

文件作用

文件名 作用 是否必須存在
app.js 小程序入口(首先執(zhí)行的文件)
app.json 小程序的全局配置
app.wxss 小程序的全局樣式
project.config.json 小程序開發(fā)者工具配置 是(會(huì)自動(dòng)創(chuàng)建)
sitemap.json 小程序搜索優(yōu)化

要點(diǎn)

  • data 初始化頁面中的數(shù)據(jù)
  • setData 更新數(shù)據(jù)
  • {{}} 插值語法可以實(shí)現(xiàn)數(shù)據(jù)的渲染
  • bind:事件類型=事件回調(diào)
Page({  //index.js
  // 約定格式,使用data定義數(shù)據(jù)
  data: {
    message: 'nihao!'
  },
  changeMessage() {
    // this.setData修改數(shù)據(jù)
    this.setData({
      message: 'new!'
    })
  }
})

index.wxml

<view>{{message}}</view>
<button bind:tap="changeMessage" type="primary" size="mini">點(diǎn)我試試</button>

如何注冊(cè)小程序事件監(jiān)聽?

Page({
處理函數(shù)() {}

})

<button bind:事件名=“處理函數(shù)”>

配置文件

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

分類:

全局 app.json

頁面 page.json

全局配置

app.json 是當(dāng)前小程序的全局配置,包括了:

  • 小程序首頁
  • 界面表現(xiàn)
  • 網(wǎng)絡(luò)超時(shí)時(shí)間
  • 底部 tab
  • …等配置
全局配置pages

用于指定小程序由哪些頁面組成。

  1. 每一項(xiàng)都對(duì)應(yīng)一個(gè)頁面的 路徑(含文件名) 信息。
  2. 小程序中的每一個(gè)頁面都必須在pages下登記一下。
  3. 文件名不需要寫文件后綴,框架會(huì)自動(dòng)去尋找對(duì)應(yīng)位置的 .json, .js, .wxml, .wxss 四個(gè)文件進(jìn)行處理。

是一個(gè)數(shù)組,每一項(xiàng)表示一個(gè)頁面

{
  pages:[
    "pages/index/index",
    "pages/logs/logs"
  ]
}

數(shù)組中的第一個(gè)元素表示小程序啟動(dòng)時(shí)默認(rèn)打開的頁面-主頁

頁面跳轉(zhuǎn)
<navigator url="/pages/logs/logs">跳轉(zhuǎn)到log頁面</navigator>
新建頁面(自動(dòng)優(yōu)先)
新建頁面-手動(dòng)

共三步:

  1. 新建空目錄
  2. 新建頁面(4個(gè)文件)
  3. 在pages下手動(dòng)補(bǔ)充頁面地址

要點(diǎn):

  1. 頁面都放在pages下,一個(gè)頁面一個(gè)文件夾。
  2. 新建page時(shí),不需要寫文件后綴名。
新建頁面-自動(dòng)

在pages下補(bǔ)充一項(xiàng) pages/page1/page1 ,然后保存,則會(huì)自動(dòng)添加一個(gè)頁面。

app.json

{
  pages:[
    "pages/index/index",
    "pages/logs/logs",
    "pages/page1/page1"
  ]
}
小程序配置-全局配置—window

用于設(shè)置小程序的狀態(tài)欄、導(dǎo)航條、標(biāo)題、窗口背景色。

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#window

常見配置:

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

小程序配置-全局配置—tabBar

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

tabBar

tabBar 定義小程序 tab 欄的表現(xiàn),如下圖即所謂的 tab 欄:

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

常見配置屬性

屬性 類型 默認(rèn)值 是否必須 說明
list array tab 的列表,詳見 list 屬性說明,最少 2 個(gè)、最多 5 個(gè) tab
color 16 進(jìn)制顏色 tab 上的文字默認(rèn)顏色,僅支持十六進(jìn)制顏色
selectedColor 16 進(jìn)制顏色 tab 上的文字選中時(shí)的顏色,僅支持十六進(jìn)制顏色
backgroundColor 16 進(jìn)制顏色 tab 的背景色,僅只持 16 進(jìn)制顏色
borderStyle string black tabbar 上邊框的顏色, 僅支持 black / white
position string bottom tabBar 的位置,僅支持 bottom / top

上述配置中 list 具體又包含以下內(nèi)容:

屬性 類型 默認(rèn)值 是否必須 說明
pagePath string 頁面路徑,必須在 pages 中先定義
text string tab 上按鈕文字
iconPath string 圖片路徑,icon 大小限制為 40kb,建議尺寸為 81px * 81px,不支持網(wǎng)絡(luò)圖片,當(dāng) position 為 top 時(shí),不顯示 icon
selectedIconPath string 選中時(shí)的圖片路徑,icon 大小限制為 40kb,建議尺寸為 81px * 81px,不支持網(wǎng)絡(luò)圖片,當(dāng) position 為 top 時(shí),不顯示 icon

參考代碼(app.josn)

{
  ......
  "tabBar": {
    "color": "#999",
    "selectedColor": "#e93b3d",
    "backgroundColor": "#fff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首頁",
        "iconPath": "static/tabbar/home-default.png",
        "selectedIconPath": "static/tabbar/home-active.png"
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志",
        "iconPath": "static/tabbar/video-default.png",
        "selectedIconPath": "static/tabbar/video-active.png"
      },
      {
        "pagePath": "pages/index/demo",
        "text": "示例",
        "iconPath": "static/tabbar/face-default.png",
        "selectedIconPath": "static/tabbar/face-active.png"
      }
    ]
  }
}
小程序配置-頁面配置
  • 頁面配置只針對(duì)某個(gè)頁面生效
    • 如 index.json 是針對(duì) index 頁面生效,demo.json 只針對(duì)頁面 demo 生效
  • 不用寫window字段
  • 優(yōu)先級(jí)比全局配置高

常用配置:

屬性 類型 默認(rèn)值 是否必須 說明
navigationBarTitleText string 空白 導(dǎo)航欄標(biāo)題文字內(nèi)容
navigationBarTextStyle string black 導(dǎo)航欄標(biāo)題顏色,僅支持 black / white
navigationBarBackgroundColor 16 進(jìn)制顏色 #00000 導(dǎo)航欄背景顏色,如 #000000
navigationStyle string default 導(dǎo)航欄樣式,僅支持 default / custom
enablePullDownRefresh boolean false 是否開啟全局的下拉刷新
小程序適配-響應(yīng)式單位rpx

rpx ,responsive pixel:

在小程序中的單位rpx,它的特點(diǎn)是能夠自動(dòng)地適配置不同尺寸的手機(jī)屏幕。

原理:不管手機(jī)屏幕具體多寬,100%的屏幕寬度就是750rpx

100%屏幕的寬度 = 750rpx

  1. 所有的設(shè)備寬度都是750rpx
  2. 在實(shí)際使用中只需要將設(shè)計(jì)稿調(diào)整為 750px 寬,然后 1:1 的比例來寫長(zhǎng)度(單位使用 rpx),如:設(shè)計(jì)稿中某個(gè)區(qū)域(盒子)的大小為 18090px ,寫成小程序的尺寸為 18090rpx。

注:上述的規(guī)則僅適用于設(shè)計(jì)稿寬度為 750px

rpx (responsive pixel):規(guī)定不管屏幕為多少px,100%的屏幕寬度就是750rpx
100%屏幕的寬度 = 750rpx

內(nèi)置組件—navigator(跳轉(zhuǎn))

navigator 是小程序中的導(dǎo)航標(biāo)簽,類似以前web中的a標(biāo)簽。通過 url 來指定跳轉(zhuǎn)的頁面

  • url: 頁面路徑
    • 支持相對(duì)和絕對(duì)路徑
    • 路徑為空會(huì)報(bào)錯(cuò)
    • 還可以跳到其他小程序
  • hover-class:點(diǎn)擊態(tài)的樣式
    • none 禁用點(diǎn)擊效果
  • open-type:跳轉(zhuǎn)方式
    • navigate。默認(rèn)值
    • switchTab。跳轉(zhuǎn)到tabbar頁
屬性名 類型 默認(rèn)值 說明
url string 當(dāng)前小程序內(nèi)的跳轉(zhuǎn)鏈接
open-type string navigate 跳轉(zhuǎn)方式
target String self 在哪個(gè)目標(biāo)上發(fā)生跳轉(zhuǎn),默認(rèn)當(dāng)前小程序
內(nèi)置組件-image(圖片)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

<image 
src="圖片資源地址" 
mode="圖片裁剪,縮放方式"></image> 

image組件是一個(gè)有默認(rèn)大小(320*240)的盒子。

  • src: 圖片資源地址。相對(duì)地址,絕對(duì)地址(外網(wǎng)地址)。
  • mode: 默認(rèn)值為scaleToFill,用來設(shè)置圖片裁剪、縮放的模式。
    • scaleToFill。不保證縮放比,圖片拉伸填滿容器
    • aspectFit。保證縮放比,使圖片的長(zhǎng)邊顯示出來
    • aspectFill。保證縮放比,使圖片的短邊顯示出啦
  • lazy-load:默認(rèn)為false,是否開啟懶加載模式。(3屏)
內(nèi)置組件—swiper(輪播圖)

swiper可以理解為小程序內(nèi)置的輪播圖標(biāo)簽,可以讓方便快速地實(shí)現(xiàn)輪播功能。

<swiper>
  <swiper-item>1屏的內(nèi)容 </swiper-item>
  <swiper-item>2屏的內(nèi)容 </swiper-item>
  <swiper-item>3屏的內(nèi)容 </swiper-item>
  <swiper-item>4屏的內(nèi)容 </swiper-item>
</swiper>
  1. swiper:滑塊容器。內(nèi)只能寫swiper-item。它的默認(rèn)高度是150px;
  2. swiper-item:滑塊單元。它的大小是: 寬度 和 高度 為 100% * 100%;
表單相關(guān)
  1. 輸入框:input
    1. password密碼類型,placeholder占位文字
  2. 單選框:radio-group和radio
    1. value指定表單數(shù)據(jù),checked選中狀態(tài)
  3. 復(fù)選框:checked-group和checkbox
    1. value指定表單數(shù)據(jù),checked選中狀態(tài)
  4. 選擇框:picker
    1. mode:指定不同類型的選擇框
scroll-view(滾動(dòng))

``scroll-view 在頁面中指定一個(gè)**可以滾動(dòng)**的區(qū)域,并且這個(gè)可滾動(dòng)的區(qū)域能夠?qū)崿F(xiàn)一些高級(jí)的交互,比如:下拉刷新`等。

scroll-view 中嵌套任意需要滾動(dòng)的內(nèi)容,要求內(nèi)容必須有溢出(scroll-view有固定的尺寸),垂直滾動(dòng)時(shí) scroll-view 必須要指定高度。

屬性

  • scroll-x 屬性是否允許水平方面滾動(dòng)
  • scroll-y 屬性是否允許垂直方向滾動(dòng)
  • refresher-enable 屬性是否開啟下拉刷新的交互
小程序樣式-全局樣式

app.wxss 定義全局樣式,該文件中的樣式會(huì)在所有的頁面生效。

注:page 在每個(gè)頁面中都有,它是由小程序自動(dòng)添加上的,相當(dāng)于網(wǎng)頁中的 body 標(biāo)簽。

小程序樣式-靜態(tài)資源

小程序中 .wxss 文件中不支持使用本地路徑的資源,比如背景圖片是不允許使用本地圖片路徑的,必須使用網(wǎng)絡(luò)路徑(https:// 或 http:// 開頭)或者轉(zhuǎn)換成 base64 編碼。

小程序樣式-字體圖標(biāo)(iconfont)

小程序中字體圖片的使用與網(wǎng)頁中基本上是一致的,唯一的區(qū)別是小程序的 .wxss 文件中不支持使用本地字體文件,我們使用 iconfont 平臺(tái)提供的服務(wù)生成字體文件后,直接使用其線上的字體文件地址。

資源參考:https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=4061819

小程序基本使用-請(qǐng)求數(shù)據(jù)并渲染

小程序模板語法-數(shù)據(jù)綁定

在js中定義數(shù)據(jù)

Page({
  data: {
    isOpen: true,
    message: 'hello world!'
  }
})

小程序的data是一個(gè)對(duì)象,不同于vue的data是一個(gè)函數(shù)

在模塊中獲取使用數(shù)據(jù)

小程序中使用 {{}} 實(shí)現(xiàn)數(shù)據(jù)與模板的綁定

  1. 內(nèi)容綁定:<view>{{ 屬性名 }}</view>
  2. 屬性綁定: <input value="{{屬性名}}" />

{{}} 內(nèi)寫的是表達(dá)式

簡(jiǎn)易雙向綁定
  1. 小程序中提供了 model:value="{{數(shù)據(jù)名}}" 語法來實(shí)現(xiàn)雙向的數(shù)據(jù)綁定

  2. 目前只能用在 inputtextarea 組件中。

    只能是一個(gè)單一字段的綁定,不能嵌套對(duì)象.否則出現(xiàn)以下報(bào)錯(cuò):

    [pages/index/index] Two-way binding does not support complex data paths currently. This two-way binding is ignored.

    雙向綁定目前不支持復(fù)雜的數(shù)據(jù)路徑。這種雙向綁定將被忽略。

小程序修改數(shù)據(jù)

格式:

<元素 bind:事件名="處理函數(shù)">
this.setData({
  屬性名1: 新值1,
  屬性名2: 新值2
})


this.setData({
  "屬性1.屬性2":})
模板語法—條件渲染

小程序中的條件渲染的方式有兩種

1.wx:if

    • 在小程序中,使用wx:if="{{條件}}"來判斷是否需要渲染該代碼塊
    • 也可以用wx:elif 和 wx:else來添加else判斷

2.hidden

    • 在小程序中,使用hidden="{{條件}}"也能控制元素的顯示與隱藏
    • 條件為true則隱藏,否則則顯示
wx:if 與 hidden區(qū)別

1.區(qū)別

    1. wx:if是通過動(dòng)態(tài)創(chuàng)建或移除元素來控制元素是否可見
    2. hidden 是通過樣式(none/block)來控制元素是否可見

2.要點(diǎn)

  • 如果一個(gè)標(biāo)簽頻繁切換顯示,建議使用 hidden。例如:折疊面板,抽屜面板等等
  • 如果不頻繁切換,建議使用wx:if,它有更好的初始化性能。
模板語法—列表渲染—基礎(chǔ)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

格式

<元素 wx:for="{{列表數(shù)據(jù)}}" >
   <!--  wx:for 結(jié)構(gòu)內(nèi)可以使用兩個(gè)變量(1)item:循環(huán)項(xiàng)(2)index:循環(huán)索引 -->
   {{item}}, {{index}}
</元素>

手動(dòng)指定索引名和當(dāng)前項(xiàng)的變量名

<view wx:for="{{list}}" wx:for-item="value" wx:for-index="key">
	{{key}}-{{value}}
</view>
模板語法-列表渲染-wx:key

wx:key 針對(duì)不同的數(shù)組類型有不同的寫法

  • 普通數(shù)組 wx:key=“*this”
  • 數(shù)組對(duì)象 wx:key=“具有唯一性的某個(gè)屬性名”
小程序內(nèi)置API-網(wǎng)絡(luò)請(qǐng)求

網(wǎng)絡(luò)請(qǐng)求

調(diào)用 wx.request 能夠在小程序中發(fā)起網(wǎng)絡(luò)請(qǐng)求與后端接口進(jìn)行數(shù)據(jù)的交互,其語法格式如下:

wx.request({
  url: '這里是接口的地址',
  method: '這里是請(qǐng)求的方法',
  data: '請(qǐng)求時(shí)提交的數(shù)據(jù)',
  header: {/* 請(qǐng)求頭信息 */},
  success: () => {/* 成功的回調(diào) */},
  fail: () => {/* 失敗的回調(diào) */},
  complete: () => {/* 成功或失敗的回調(diào) */}
})
配置網(wǎng)絡(luò)請(qǐng)求合法域名

域名必須是https

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)
原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

小程序內(nèi)置api-界面交互
showLoading效果

配合網(wǎng)絡(luò)請(qǐng)求來使用

wx.showLoading 顯示 loading 提示框

  • title 文字提示內(nèi)容
  • mask 是否顯示透明蒙層,防止觸摸穿透
hideLoading
  • wx.hideLoading 隱藏 loading 提示框
showToast

wx.showToast 消息提示框(輕提示)

  • title 提示的標(biāo)題
  • mask 是否顯示透明蒙層,防止觸摸穿透
  • duration 延遲時(shí)間(提示框顯示多久,單位是毫秒)
  • icon 指定圖標(biāo),none 不使用圖標(biāo)
操作注意:
  1. 發(fā)請(qǐng)求之前,showLoading
  2. 請(qǐng)求結(jié)束之后(無論成敗),hideLoading
  3. 數(shù)據(jù)渲染成功之后,showToast
微信小程序本地存儲(chǔ)
  • wx.setStorageSync(key, value) 存入一個(gè)數(shù)據(jù),復(fù)雜類型數(shù)據(jù)不需要 JSON.stringify 處理
  • wx.getStorageSync(key) 讀取本地key數(shù)據(jù),復(fù)雜類型數(shù)據(jù)不需要 JSON.parse 處理
  • wx.removeStorageSync(key) 刪除本地key數(shù)據(jù)
  • wx.clearStorageSync()清空本地全部數(shù)據(jù)
微信小程序API的特征

API的用法分類三類:

  1. 異步的api
  2. 同步的api
  3. 支持promise的api
異步 API

絕大部分的 API 都是異步方式,通過回調(diào)函數(shù)獲取 API 執(zhí)行的結(jié)果

  • success API 調(diào)用成功時(shí)執(zhí)行的回調(diào)
  • fail API 調(diào)用失敗時(shí)執(zhí)行的回調(diào)
  • complete API 調(diào)用結(jié)束時(shí)執(zhí)行的回調(diào)(無論成功或失?。?/li>

基本格式:

wx.api名稱({success(res){ console.log(成功執(zhí)行api的結(jié)果) }})
支持promise的api

部分異步的 API 也支持以 Promise 方式返回結(jié)果,此時(shí)可以配合 asyc/await 來使用。

例如:支持Promise格式的異步api有:

  • wx.getSystemInfoSync()
  • wx.getStorage

支持Promise格式的異步api有:

  • wx.request()
同步 API

部分 API 支持以同步方式獲取結(jié)果,這些 API 的名稱都 **Sync** 結(jié)尾。如

  • wx.getStorageSync : 獲取本地存儲(chǔ)
  • wx.getSystemInfoSync: 獲取系統(tǒng)信息

基本格式:

const result = wx.api名稱()
事件處理-事件對(duì)象&傳參

事件對(duì)象

bind:事件類型=事件回調(diào) //回調(diào)函數(shù)第1個(gè)參數(shù)即為事件對(duì)象

事件回調(diào)傳參

小程序的事件回調(diào)不支持傳參數(shù)

因此要將模板中的數(shù)據(jù)傳遞到事件回調(diào)中就必須要通過事件對(duì)象來實(shí)現(xiàn)。

方式1:

  • 補(bǔ)充參數(shù):

     <button bind:tap="eventHandler" **mark:屬性名="值"**>點(diǎn)擊我看看</button>
    
    
  • 獲取值:

    eventHandler(ev){ console.log(**ev.mark.屬性名**) 
    
    

方式2:

  • 補(bǔ)充參數(shù) :

    <button bind:tap="eventHandler" **data-屬性名="值"** >點(diǎn)擊我看看</button>
    
    
  • 獲取值:

    eventHandler(ev){ console.log(**ev.target.dataset.屬性名**) }
    
    
事件處理-組件事件

事件類型只屬于某個(gè)組件,我們將其稱為組件事件

前面介紹的 tap 事件可以在絕大部分組件是監(jiān)聽,我們可以將其理解為通用事件類型,然而也有事件類型只屬于某個(gè)組件,我們將其稱為組件事件。

組件不同,支持的事件也不同

scroll-view組件中的事件

  1. bind:scrolltolower 當(dāng)滾動(dòng)內(nèi)容到達(dá)底部或最右側(cè)時(shí)觸發(fā)
  2. bind:refresherrefresh 執(zhí)行下拉操作時(shí)觸發(fā)

另外,還有注意一個(gè)特別的屬性

refresher-triggered 用它來控制下拉刷新狀態(tài)

事件處理-表單組件中的事件

如何獲取表單中,用戶選擇的值?

  1. input: 簡(jiǎn)易雙向綁定
  2. radioGroup: 綁定change事件,在事件對(duì)象中detail.value拿到值
  3. checkboxGroup: 綁定change事件,在事件對(duì)象中detail.value拿到值
  4. picker: 綁定change事件,在事件對(duì)象中detail.value拿到值
  • change 表單數(shù)據(jù)發(fā)生改變時(shí)觸發(fā)(input 不支持)

? 5.整體表單提交

  • form: submit事件 表單提交時(shí)觸發(fā),button 按鈕必須指定 form-type 屬性
生命周期-頁面生命周期
  • 分類
    • 應(yīng)用生命周期
    • 頁面生命周期
    • 組件生命周期

生命周期是一些名稱固定,會(huì)自動(dòng)執(zhí)行的函數(shù)。

頁面生命周期-基本使用

  • onLoad 在頁面加載完成時(shí)執(zhí)行,只會(huì)執(zhí)行 1 次,常用于獲取地址參數(shù)和網(wǎng)絡(luò)請(qǐng)求

  • onReady頁面初次渲染完成

  • onShow 在頁面處于可見狀態(tài)時(shí)執(zhí)行,常用于動(dòng)態(tài)更新數(shù)據(jù)或狀態(tài)

  • onHide 在頁面處于不見狀態(tài)時(shí)執(zhí)行,常用于銷毀長(zhǎng)時(shí)間運(yùn)行的任務(wù),如定時(shí)器

    頁面生命周期-應(yīng)用場(chǎng)景

onLoad(){ // 發(fā)起請(qǐng)求 }

onShow(){ // 動(dòng)態(tài)更新數(shù)據(jù)或狀態(tài) }

onHide 在頁面處于不見狀態(tài)時(shí)執(zhí)行,常用于銷毀長(zhǎng)時(shí)間運(yùn)行的任務(wù),如定時(shí)器

onReady 在頁面初次渲染完成時(shí)執(zhí)行,只會(huì)執(zhí)行 1 次,常用于節(jié)點(diǎn)操作或動(dòng)畫交互等場(chǎng)景

生命周期-應(yīng)用生命周期

app.js

  • onLaunch 小程序啟動(dòng)時(shí)執(zhí)行1次,常用于獲取場(chǎng)景值或者啟動(dòng)時(shí)的一些參數(shù)(如自定義分享)
  • onShow 小程序前臺(tái)運(yùn)行時(shí)執(zhí)行,常用于更新數(shù)據(jù)或狀態(tài)
  • onHide 小程序后臺(tái)運(yùn)行時(shí)執(zhí)地,常用于銷毀長(zhǎng)時(shí)間運(yùn)行的任務(wù),如定時(shí)器。
// pages/lifetimes/index.js
Page({
  
  // 小程序轉(zhuǎn)發(fā)/分享
  onShareAppMessage() {
    return {
      title: '小程序?qū)W習(xí)',
      path: '/pages/index/index?test=測(cè)試數(shù)據(jù)',
      imageUrl: '/static/images/cover.png'
    }
  }
})

小程序基礎(chǔ)-分包加載&&自定義組件&&&項(xiàng)目全流程

小程序分包加載

小程序分包加載-為什么要分包加載

  • 微信平臺(tái)對(duì)小程序單個(gè)包的代碼體積限制為 2M,超過 2M 的情況下可以采用分包來解決
  • 即使小程序代碼體積沒有超過 2M 時(shí)也可以拆分成多個(gè)包來實(shí)現(xiàn)按需加載
  • 配置文件能忽略的只有靜態(tài)資源,代碼無法被忽略

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

配置忽略文件

project.config.json

{
  "description": "項(xiàng)目配置文件",
  "packOptions": {
    "ignore": [
      {
        "value": "static/uploads",
        "type": "folder"
      }
    ],
    "include": []
  },

type: 表示要忽略的資源類型

value: 表示具體要忽略的

小程序分包加載-使用分包配置

分類:

  1. 主包:
  • 每個(gè)小程序必定含有一個(gè)主包。

  • 默認(rèn)啟動(dòng)頁面、TabBar 頁面,以及公共資源/JS 腳本必須放在主包;

    2.分包 https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html

  • 通過subPackages來配置

  • 所有包的大小之和不超過20M

app.json

{
  // 省略其他的...
  
  "subPackages": [
      {
        "root": "subpkg_user", // 分包代碼的目錄,其實(shí)就是一個(gè)獨(dú)立的文件夾
        "pages": [
          "pages/profile/profile"
        ]
      },
      {
        "root": "subpkg_order", // 文件夾
        "pages": [
          "pages/order_list/index", 
          "pages/order_list/index"
        ]
      }
  ]
}

注意: 寫完分包之后,如果對(duì)應(yīng)的文件夾和頁面不存在,它會(huì)自動(dòng)創(chuàng)建文件夾和頁面

小程序分包—預(yù)加載

https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/preload.html

在打開小程序啟動(dòng)的時(shí)候只下載主包代碼,分包并不會(huì)下載,因此能夠提升小程序啟動(dòng)時(shí)的打開速度,但是分包的代碼只有在訪問到分包的頁面時(shí)才去下載,這樣用戶就需要有一定時(shí)間的等待(一般不太影響),通過分包預(yù)加載技術(shù)可以實(shí)現(xiàn)提前去下載分包的代碼,這樣分包頁面的訪問速度也會(huì)得到提升。
小程序通過 preloadRule 配置需要預(yù)加載的分包。

app.json

{   ......
	"preloadRule": {
    "頁面地址,進(jìn)入這個(gè)頁面就需要預(yù)加載分包": {       // pages/index/index 
      "network": "網(wǎng)絡(luò)環(huán)境",                     // "wifi"
      "packages": ["要預(yù)加載的包名"]              //["goods_pkg"]
    }
  },   ......
}      //當(dāng)用戶訪問到 pages/index/index 時(shí),在 wifi 網(wǎng)絡(luò)前提下預(yù)先下載 goods_pkg 分包的代碼。
  • 指定某個(gè)頁面路徑做為 key,含義是當(dāng)訪問這個(gè)頁面時(shí)會(huì)去預(yù)加載一個(gè)分包
  • network 預(yù)加載分包的網(wǎng)絡(luò)條件,可選值為 all、wifi,默認(rèn)為 wifi
  • packages 指定要預(yù)下載的分包名或根路徑

配置完成之后,訪問指定頁面時(shí),就會(huì)在控制臺(tái)輸出提示。

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

自定義組件—基本使用

創(chuàng)建組件

通常將項(xiàng)目中的組件都放在一個(gè)獨(dú)立的目錄下,并且一般就給這個(gè)文件夾取名為:components 。這個(gè)目錄需要我們手動(dòng)進(jìn)行創(chuàng)建。

  1. 新建一個(gè)目錄:components

  2. 在components上點(diǎn)擊鼠標(biāo)右鍵,選擇「新建Component」

  3. 填入組件的名字。它會(huì)自動(dòng)創(chuàng)建4個(gè)同名的文件。(這一點(diǎn)和創(chuàng)建頁面是一樣的)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

組件和頁面的結(jié)構(gòu)區(qū)別:

  1. 組件的配置文件(.json文件)中,有一個(gè)配置項(xiàng):component: true
  2. 組件的 .js 文件中調(diào)用 Component 函數(shù),頁面的.js文件中調(diào)用Page函數(shù)

注冊(cè)組件

  • 頁面注冊(cè)是在使用組件的(xxxx.json)中通過 usingComponents 進(jìn)行注冊(cè),只能在當(dāng)前頁面中組件
  • 全局注冊(cè)是在 app.json 文件中通過 usingComponents 對(duì)自定義組件進(jìn)行注冊(cè),可以在任意頁面中使用
"usingComponents": {
    "my-test": "/components/MyTest/index"
}

使用組件

在wxml中,直接通過標(biāo)簽的方式使用即可。

自定義組件—組件樣式
  1. 組件中的樣式不要使用標(biāo)簽選擇器
  2. 組件中,樣式默認(rèn)是隔離的: 自定義組件的樣式只受到自定義組件 wxss 的影響
  3. 通過對(duì)組件的配置,可以取消這個(gè)隔離的狀態(tài)。

樣式隔離注意點(diǎn)

  • app.wxss中的全局樣式對(duì)組件無效
  • 只有class選擇器具有樣式隔離效果,id選擇器、屬性選擇器、標(biāo)簽選擇器不受樣式隔離的影響

建議:在組件和引用組件的頁面中建議使用class選擇器,不要使用id、屬性、標(biāo)簽選擇器

修改組件樣式的隔離選項(xiàng)

默認(rèn)情況下,自定義組件的樣式隔離特性能夠防止組件內(nèi)外樣式互相干擾的問題。但有時(shí),我們希望外界能夠控制組件內(nèi)部的樣式,此時(shí),可以通過在組件的.js文件中設(shè)置: options → addGlobalClass 為true

XX.js

Component({
  options: {
    addGlobalClass: true
  }
})

在頁面中設(shè)置的同類名的選擇器就能作用于子組件內(nèi)部的元素。但是,組件內(nèi)的class選擇器,不能影響頁面的元素。

自定義組件—組件樣式-外部樣式類

組件希望接受外部傳入的樣式類。此時(shí)可以在 Component 中用 externalClasses 定義若干個(gè)外部樣式類。

在開發(fā)組件時(shí),主動(dòng)暴露給組件使用者,修改組件內(nèi)部樣式

組件 custom-component.js

/* 組件 custom-component.js */
Component({
  externalClasses: ['my-class']
});

組件 custom-component.wxml

<!-- 組件的wxml -->
<!-- 這里的my-class相當(dāng)于一個(gè)占位符 -->
<view class="my-class">components/MyTest/index.wxml</view>

頁面的 WXML

<!-- 頁面的 WXML -->
<custom-component my-class="red-text" />
<custom-component my-class="large-text" />

頁面的wxss

.red-text{ color: red; }
.large-text {font-size: 50px; }

外部樣式類相當(dāng)于用一個(gè)類名去當(dāng)占位符,以便于在后期使用時(shí)替換成真實(shí)的類名,方便添加額外的樣式。

參考:https://vant-contrib.gitee.io/vant-weapp/#/button#wai-bu-yang-shi-lei
原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

自定義組件—數(shù)據(jù)方法

組件的典型結(jié)構(gòu)

// borderImage.js
Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    
  },

  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    
  },

  /**
   * 組件的方法列表
   */
  methods: {
    
  }
})

定義數(shù)據(jù)

在小程序中,用于組件模板渲染的私有數(shù)據(jù),需要定義到data

methods方法

在小程序的組件中,事件處理函數(shù)和自定義方法需要定義到methods

自定義組件—組件插槽
單個(gè)插槽

在小程序中,默認(rèn)情況下每個(gè)自定義組件中只允許使用一個(gè)插槽進(jìn)行占位。

<!--components/MyTest2/index.wxml-->
<view>
  <text>components/MyTest2/index.wxml</text>
  <!-- 對(duì)于不確定的內(nèi)容,可以使用slot進(jìn)行占位,具體內(nèi)容交給使用者確定 -->
  <slot></slot>
</view>

使用組件

<my-test2>
  <!-- 這里的內(nèi)容將被放到組件中<slot>的位置 -->
  <view>
    這里是slot里的內(nèi)容
  </view>
</my-test2>

多插槽(具名插槽)

組價(jià).js

Component({
  options: {
    multipleSlots: true // 在組件定義時(shí)的選項(xiàng)中啟用多 slot 支持
  },
  // ... 省略其他
})

此時(shí),可以在這個(gè)組件的 wxml 中使用多個(gè) slot ,以不同的 name 來區(qū)分。

定義插槽

<view>
  <text>components/MyTest2/index.wxml</text>
  <!-- 對(duì)于不確定的內(nèi)容,可以使用slot進(jìn)行占位,具體內(nèi)容交給使用者確定 -->
  <!-- <slot></slot> -->
  <slot name="before"></slot>
  <view>
    ---------這里是分割線--------
  </view>
  <slot name="after"></slot>
</view>

使用組件

<my-test2>
  <!-- 這里的內(nèi)容將被放到組件中<slot>的位置 -->
  <!-- <view>
    這里是slot里的內(nèi)容
  </view> -->
  <view slot="before">
    這里是before slot里的內(nèi)容
  </view>
  <view slot="after">
    這里是after slot里的內(nèi)容
  </view>
</my-test2>

自定義組件—生命周期

組件生命周期-lifetimes

生命周期 參數(shù) 描述
created 在組件實(shí)例剛剛被創(chuàng)建時(shí)執(zhí)行,此時(shí)還不能調(diào)用 setData,一般用于給組件的this添加一些自定義的屬性字段
attached 在組件實(shí)例進(jìn)入頁面節(jié)點(diǎn)樹時(shí)執(zhí)行,絕大多數(shù)初始化工作可以在這個(gè)時(shí)機(jī)進(jìn)行,例如發(fā)請(qǐng)求獲取初始數(shù)據(jù)
ready 在組件在視圖層布局完成后執(zhí)行
moved 在組件實(shí)例被移動(dòng)到節(jié)點(diǎn)樹另一個(gè)位置時(shí)執(zhí)行
detached 在組件實(shí)例被從頁面節(jié)點(diǎn)樹移除時(shí)執(zhí)行,適合做一些清理工作
error Object Error 每當(dāng)組件方法拋出錯(cuò)誤時(shí)執(zhí)行

生命周期函數(shù)要寫在lifetimes里邊

lifetimes: {
    created() {
      console.log('組件被created') // 這里使用setData不會(huì)引起視圖的更新
      this.setData({ msg: 'abc!' })
    },
    attached() {
      this.setData({ msg: 'abcd' })
    }
  }

自定義組件-屬性(父?jìng)髯?

在小程序中,properties是組件的對(duì)外屬性,用于接收外界傳遞到組件中的數(shù)據(jù)

父組件傳入屬性值

<my-test isOpen max="9" min="1" />

子組件.js中接收

Component({
	properties: {
    isOpen: Boolean,
  	min: Number, // 直接寫類型
    max: {       // 寫類型 + 初始值
    	type: Number,
      value: 10 // value用于指定默認(rèn)值
    }
  }
})

自定義組件-組件通訊-自定義事件triggerEvent(子傳父)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

Vant組件庫(kù)

官方文檔:https://vant-contrib.gitee.io/vant-weapp/#/quickstart

步驟一 通過 npm 安裝

npm i @vant/weapp -S --production

步驟二 修改 app.json

將 app.json 中的 "style": "v2" 去除

步驟三 修改 project.config.json

開發(fā)者工具創(chuàng)建的項(xiàng)目,miniprogramRoot 默認(rèn)為 miniprogrampackage.json 在其外部,npm 構(gòu)建無法正常工作。

需要手動(dòng)在 project.config.json 內(nèi)添加如下配置,使開發(fā)者工具可以正確索引到 npm 依賴的位置。

{
  ...
  "setting": {
    ...
    "packNpmManually": true,
    "packNpmRelationList": [
      {
        "packageJsonPath": "./package.json",
        "miniprogramNpmDistDir": "./miniprogram/"
      }
    ]
  }
}

步驟四 構(gòu)建 npm 包(重點(diǎn))

開發(fā)者工具上 > “工具” > “構(gòu)建npm”

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

使用

去app.json(全局注冊(cè))或頁面.json(局部注冊(cè))中注冊(cè)

"usingComponents": {
  "van-button": "@vant/weapp/button/index"
}

在頁面中使用

<van-button type="primary">按鈕</van-button>

小程序開發(fā)環(huán)境-優(yōu)化目錄結(jié)構(gòu)

項(xiàng)目的根目錄
├── miniprogram  // 項(xiàng)目相關(guān)的代碼夾
├── node_modules // npm包目錄
├── package.json
├── project.config.json
├── package-lock.json
└── sitemap.json

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

修改 project.config.json 中的配置項(xiàng)

{
  // 省略其他......
  "setting": {
    // 省略其他......
    "packNpmManually": true,
    "packNpmRelationList": [
      {
        "miniprogramNpmDistDir": "./miniprogram",
        "packageJsonPath": "package.json"
      }
    ]
  },
  "miniprogramRoot": "miniprogram/"
}

啟用 less/sass

通過 less/sass 可以更好的管理 css 樣式,通過 project.config.json 可以啟用對(duì) less/sass 的支持。

{
  "setting": {
    "useCompilerPlugins": ["sass"]
  }
}

然后將 .wxss 文件后綴改換成 .scss 即可。

啟動(dòng)項(xiàng)目

  1. 拉取代碼
  2. 導(dǎo)入項(xiàng)目

使用小程序開發(fā)者工具導(dǎo)入【項(xiàng)目】的代碼

3. 使用小程序開發(fā)者工具構(gòu)建 npm

  1. 安裝包:npm install
  2. 手動(dòng)構(gòu)建: 【工具】→【構(gòu)建npm】

project.config.json的幾個(gè)配置

{
  "miniprogramRoot": "miniprogram/",
  "setting": {
    "useCompilerPlugins": ["sass"],
    "packNpmManually": true,
    "packNpmRelationList": [
      {
        "packageJsonPath": "./package.json",
        "miniprogramNpmDistDir": "./miniprogram"
      }
    ],
  }
}
  • miniprogramRoot 項(xiàng)目的根目錄為 miniprogram
  • setting.useCompilerPlugins 啟用了 sass 支持
  • packNpmRelationList 指定了 npm 構(gòu)建時(shí)所需的 package.json 的位置以及構(gòu)建后代碼的生成位置

4. 改成自己的appid

這個(gè)項(xiàng)目中的appid是別人的,如果我們需要改成自己的。

基礎(chǔ)封裝-消息反饋

將所有通用的工具方法封裝到 utils/utils.js 中

/**
 * 用戶消息反饋
 * @param {string} title 文字提示的內(nèi)容
 */
export const toast = (title = '數(shù)據(jù)加載失敗...') => {
  wx.showToast({
    title,
    mask: true,
    icon: 'none',
  })
}
// 掛載到全局對(duì)象 wx
wx.$toast = toast

app.js

// 在入口中執(zhí)行 utils.js
import './utils/utils.js'
App({
  // ...
})

使用

 wx.$toast('//提示文字', "icon圖標(biāo)")
基礎(chǔ)封裝-網(wǎng)絡(luò)請(qǐng)求

安裝第三方的包-構(gòu)建

  1. npm install wechat-http
  2. 安裝完成后還必須要構(gòu)建 npm后才可以使用

wechat-http用法與 axios 類似:

  • http.baseURL 配置接口基礎(chǔ)路徑
  • http.getGET 方法發(fā)起請(qǐng)求
  • http.postPOST 方法發(fā)起請(qǐng)求
  • http.putPUT 方法發(fā)起請(qǐng)求
  • http.deleteDELETE 方法發(fā)起請(qǐng)求
  • http.intercept 配置請(qǐng)求和響應(yīng)攔截器
  • http 本身做為函數(shù)調(diào)用也能用于發(fā)起網(wǎng)絡(luò)請(qǐng)求

二次封裝

新建 utils/http.js 文件

// 導(dǎo)入 http 模塊
import http from 'wechat-http'
// 基礎(chǔ)路徑
http.baseURL = 'https://live-api.itheima.net'
// 掛載到全局對(duì)象
wx.http = http
// 普通的模塊導(dǎo)出
export default http

以全局對(duì)象方式調(diào)用時(shí)需要在入口中執(zhí)行 utils/http.js

// 執(zhí)行 uitls/http.js
import './utils/http.js'
App({
  // ...
})

配置響應(yīng)攔截器

// 配置響應(yīng)攔截器
http.intercept.response = function ({ data, config }) {

  // 檢測(cè)接口是否正常返回結(jié)果
  if (data.code !== 10000) {
    wx.$toast()
    return Promise.reject(data)
  }

  // 只保留data數(shù)據(jù),其它的都過濾掉
  return data.data
}
跳轉(zhuǎn)傳參

點(diǎn)擊公告列表后將公告的ID通過地址參數(shù)傳遞到公告詳情頁面,在公告詳情頁 onLoad 生命周期中讀取到公告 ID,然后調(diào)用接口獲取公告詳情的數(shù)據(jù)。

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)
原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

van-count-down 組件(倒計(jì)時(shí))的應(yīng)用
<van-count-down use-slot time="{{6000}}" bind:change="countDownChange">
  <text>{{timeData.seconds}}秒后重新獲取</text>
</van-count-down>

time: 指定了倒計(jì)時(shí)多少毫秒

bind:change每隔一秒的回調(diào),它會(huì)傳出來當(dāng)前的倒計(jì)時(shí)信息

 countDownChange(ev) {
    console.log(ev.detail)
    this.setData({
      timeData: ev.detail,
      getCodeBtnVisible: ev.detail.minutes === 0 && ev.detail.seconds === 0,
    })
  },
表單驗(yàn)證插件使用

先在data中設(shè)置mobile,再在模板中進(jìn)行雙向綁定

model:value=“{{mobile}}”

  1. 安裝構(gòu)建 表單驗(yàn)證碼插件 wechat-validate
npm install wechat-validate
  1. 將插件導(dǎo)入到項(xiàng)目中
  • behaviors 將插件注入到頁面中
  • rules 由插件提供的屬性,用來定義數(shù)據(jù)驗(yàn)證的規(guī)則(類似于 Element UI)
  • validate 由插件提供的方法,根據(jù) rules 的規(guī)則來對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證
// 導(dǎo)入表單驗(yàn)證插件
import validate from 'wechat-validate'
Page({
  data: {
    mobile: '' // 省略其他
  },
  behaviors: [validate], // 將插件注入到頁面實(shí)例中
  rules: {
    mobile: [
      {required: true, message: '請(qǐng)?zhí)顚懯謾C(jī)號(hào)碼!'},
      {pattern: /^1[3-8]\d{9}$/, message: '請(qǐng)?zhí)顚懻_的手機(jī)號(hào)碼!'}
    ]
  },
  getSMSCode() {
    // 獲取驗(yàn)證結(jié)果
    const { valid, message } = this.validate('mobile')
    // 如果驗(yàn)證不合法則不再執(zhí)行后面的邏輯
    if (!valid) return wx.$toast(message)
    console.log('getCode')
    this.setData({ getCodeBtnVisible: false })
  },
})
保存token-跳轉(zhuǎn)
  1. 在app.js中設(shè)置setToken方法,保存到本地存儲(chǔ)
App({
  // ...
  setToken(key, token) {
 		// 將 token 記錄在應(yīng)用實(shí)例中   
    this[key] = token
    // 將 token 存入本地
    wx.setStorageSync(key, token)
  }
})

2.點(diǎn)擊登錄 | 注冊(cè)發(fā)送請(qǐng)求成功之后

  const app = getApp()    //小程序中獲取全局的實(shí)例對(duì)象
  app.setToken('token', res.token)
  app.setToken('refreshToken', res.refreshToken)
 //  跳轉(zhuǎn)
  const url = '/pages/profile/index'
  wx.redirectTo({ url })
登錄檢測(cè)-鑒權(quán)組件

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

1.在根目錄中創(chuàng)建 components 文件夾用來存放全局的組件,然后通過小程序開發(fā)者工具創(chuàng)建一個(gè)名為 authorization 的組件

2.接下來全局來注冊(cè)這個(gè)組件,保證任何頁面中都可以直接應(yīng)用 authorization 組件

{
  "usingComponents": {
    "authorization": "/components/authorization/index"
  },
}

3.到用戶信息頁面中應(yīng)用 authorization 使用做為頁面根節(jié)點(diǎn)

<authorization>
  	...
</authorization>

4.在authorization中補(bǔ)充插槽和狀態(tài)

<!--components/authorization/index.wxml-->
<slot wx:if="{{isLogin}}"></slot> 
  data: {
    isLogin: false
  },

讀取本地存儲(chǔ)token

讀取本地存儲(chǔ)的 token 數(shù)據(jù),用于判斷是否曾登錄過

// app.js
App({
  ......
    getToken() {
    // 將 token 數(shù)據(jù)記到應(yīng)用實(shí)例中
    // return this.token = wx.getStorageSync('token')
    return this.token
  }
})

在組件內(nèi)讀token并處理

data: {
  isLogin: false
},
lifetimes: {
  attached() {
    const isLogin = !!getApp().getToken()    
    //const app = getApp()  const isLogin = !!app.getToken()
    this.setData({ isLogin })
    if (!isLogin) {
      wx.redirectTo({ url: '/pages/login/index' })
    }
  }
},

地址重定向,登錄成功后跳回到原來的頁面

authoirzation 組件檢測(cè)登錄時(shí)獲取當(dāng)前頁面棧實(shí)例,并在跳轉(zhuǎn)到登錄頁面時(shí)在 URL 地址上拼湊參數(shù):

// /components/authorization/index.js
Component({
  // ...
  lifetimes: {
    attached() {
      // 獲取登錄狀態(tài)
      const isLogin = !!getApp().token
      // 變更登錄狀態(tài)
      this.setData({ isLogin })
      // 獲取頁面棧
      const pageStack = getCurrentPages()
      // 獲取頁面路徑
      const currentPage = pageStack.pop()
      // 未登錄的情況下跳轉(zhuǎn)到登錄頁面
      if (!isLogin) {
        wx.redirectTo({
          url: '/pages/login/index?redirectURL=/' + currentPage.route,
        })
      }
    },
  },
})

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

用戶管理-顯示默認(rèn)值

app.js中添加初始值

App({
  globalData: {},
  userInfo: { avatar: '', nickName: '微信用戶1' }
}

在onLoad中加載值

data: {
  avatar: '',
  nickName: ''
},
onLoad() {
  const app = getApp()
  console.log(app.userInfo)
  const { avatar, nickName } = app.userInfo
  this.setData({ avatar, nickName })
  // 用戶未登錄時(shí)不必請(qǐng)求
  app.token && this.getUserProfile()
},
配置請(qǐng)求攔截器

將用戶的登錄狀態(tài)通過自定義的頭信息 Authorization 隨接口調(diào)用時(shí)一起發(fā)送到服務(wù)端。

// 導(dǎo)入 wechat-http 模塊
import http from 'wechat-http'
// 配置接口基礎(chǔ)路徑
http.baseURL = 'https://live-api.itheima.net'
// 配置請(qǐng)求攔截器

http.intercept.request = function (options) {
  console.log('請(qǐng)求攔截器', options.header)
  // 擴(kuò)展頭信息
  const defaultHeader = {}
  // 身份認(rèn)證
  const token = getApp().getToken()
  if (token) {
    defaultHeader.Authorization = 'Bearer ' + getApp().getToken()
  }
  // 與默認(rèn)頭信息合并
  options.header = Object.assign({}, defaultHeader, options.header)
  // 處理后的請(qǐng)求參數(shù)
  return options
}

注:傳遞 token 時(shí)需要拼湊字符串前綴 "Bearer "

文件上傳(例:更新用戶頭像)

獲取用戶選擇的頭像地址,通過 wx.uploadFile 將圖片上傳到服務(wù)端。

wx.uploadFile 的基本語法:

  • url 上傳接口地址
  • filePath 待上傳文件的臨時(shí)路徑(該路徑只能用于小程序內(nèi)部)
  • name 接口接收上傳文件的數(shù)據(jù)名稱(由后端指定)
  • formData 除上傳文件外的其它數(shù)據(jù)
  • header 自定義頭信息
  • success 上傳成功的回調(diào)函數(shù)
  • fail 上傳失敗后的回調(diào)函數(shù)
  • complete 上傳完成時(shí)的回調(diào)(無論成功或失?。?/li>

注:該 API 不支持返回 Promise,調(diào)用該 API 時(shí),需要提前在小程序管理后臺(tái)添加服務(wù)器域名。

<!-- pages/profile/index.wxml -->
<authorization>
  <view class="profile">
    <van-cell center title="頭像">
      <van-icon slot="right-icon" name="arrow" size="16" color="#c3c3c5" />
      <button
        class="button"
        size="mini"
        hover-class="none"
        bind:chooseavatar="updateUserAvatar" //事件,事件名全部小寫,A千萬不要大寫,不會(huì)觸發(fā)
        open-type="chooseAvatar">    //與上邊事件對(duì)應(yīng)
        <image class="avatar" src="{{avatar}}"></image>
      </button>
    </van-cell>
    ...
  </view>
</authorization>
// pages/profile/index.js
const pageStack = getCurrentPages()
Page({
    ...
  // 更新用戶頭像
  updateUserAvatar(ev.detail.avatarUrl) {
    // 調(diào)用 API 上傳文件
    wx.uploadFile({
      // 接口地址
      url: wx.$http.baseURL + '/upload',
      // 待上傳的文件路徑
      filePath: avatar,
      name: 'file',// wx.uploadFile 要求必傳。
      header: {
        Authorization: 'Bearer ' + getApp().getToken()   // 用戶登錄狀態(tài)
      },
      formData: { // 是我們自己的接口文檔的要求??梢圆粋鳎J(rèn)就是avatar
        type: 'avatar'
      },
      success: (result) => {
        console.log(JSON.parse(result.data))
        const res = JSON.parse(result.data)
        // console.log(res.data.url)
        const avatar = res.data.url
        // 1. 在頁面上顯示
        this.setData({ avatar })
        // 2. 更新全局?jǐn)?shù)據(jù)
        const app = getApp()
        app.userInfo.avatar = avatar
        // 3. 通過頁面棧找到my/index頁面,更新它的avatar信息
        const pages = getCurrentPages()
        // pages[0].data.nickName = nickName 直接修改數(shù)據(jù)不會(huì)讓視圖更新
        // 調(diào)用setData更新
         pages[0].setData({ avatar })
      }
    })
  }
})

上述代碼中通過 wx.http.baseURL 獲取接口服務(wù)器地址,通過應(yīng)用實(shí)例獲取 token。

refresh_token使用

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

  • token:
    • 作用:在訪問一些接口時(shí),需要傳入token,就是它。
    • 有效期:2小時(shí)(安全)。
  • refresh_token
    • 作用: 當(dāng)token的有效期過了之后,可以使用它去請(qǐng)求一個(gè)特殊接口(這個(gè)接口也是后端指定的,明確需要傳入refresh_token),并返回一個(gè)新的token回來(有效期還是2小時(shí)),以替換過期的那個(gè)token。
    • 有效期:14天。(最理想的情況下,一次登陸可以持續(xù)14天。)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

1.用戶在首次完成登錄時(shí)會(huì)分別得到 token 和 refresh_token

2.當(dāng) token 失效后(例如2小時(shí)之后),調(diào)用接口A會(huì)返回 401 狀態(tài)碼(這是與后端約定好的規(guī)則)

3.檢測(cè)狀態(tài)碼是否為 401**,如果是,則攜帶refreshToken去調(diào)用刷新token的接口

4.刷新 token 的接口后會(huì)返回新的 token 和 refreshToken

5.把401的接口A重新發(fā)送一遍

注意:
refresh_token也是有過期時(shí)間的,只不過一般會(huì)比token過期時(shí)間更長(zhǎng)一些。這就是為啥如果某個(gè)應(yīng)用我們天天打開,則不會(huì)提示我們登錄,如果是有幾周或更長(zhǎng)時(shí)間去打開時(shí),會(huì)再次要求我們登錄。
refresh_token一個(gè)更常見的名字叫token無感刷新。

refreshToken功能-基本實(shí)現(xiàn)
// 響應(yīng)攔截器
http.intercept.response = async ({ statusCode, data, config }) => {
  console.log(statusCode, data, config)
  // console.log(statusCode) // http 響應(yīng)狀態(tài)碼
  // console.log(config) // 發(fā)起請(qǐng)求時(shí)的參數(shù)
  if (data.code === 401) {
    const app = getApp()
    // 調(diào)用接口獲取新的 token
    const res = await http({
      url: '/refreshToken',
      method: 'POST',
      header: {
        Authorization: 'Bearer ' + app.getToken('refreshToken'),
      }
    })

    app.setToken('token', res.token)
    app.setToken('refreshToken', res.refreshToken)
     // 獲得新的token后需要重新發(fā)送剛剛未完成的請(qǐng)求
    config = Object.assign(config, {
      header: {
        // 更新后的 token
        Authorization: 'Bearer ' + res.token,
      },
    })
    // 重新發(fā)請(qǐng)求
    return http(config)
  }
  // 攔截器處理后的響應(yīng)結(jié)果
  if (data.code === 10000) {
    return data.data
  } else {
    wx.$toast(data.message || '請(qǐng)求失敗')
    return Promise.reject(data.message)
  }
}
refreshToken也過期的特殊處理

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

完整版響應(yīng)攔截器

// 響應(yīng)攔截器
http.intercept.response = async ({ statusCode, data, config }) => {
  console.log(statusCode, data, config)
  // console.log(statusCode) // http 響應(yīng)狀態(tài)碼
  // console.log(config) // 發(fā)起請(qǐng)求時(shí)的參數(shù)
  if (data.code === 401) {
++    if (config.url.includes('/refreshToken')) {
++      console.log('/refreshToken過期了')
++      // 獲取當(dāng)前頁面的路徑,保證登錄成功后能跳回到原來頁面
++      const pageStack = getCurrentPages()
++      const currentPage = pageStack.pop()
++      const redirectURL = currentPage.route
++      // 跳由跳轉(zhuǎn)(登錄頁面)
++      wx.redirectTo({
++        url: '/pages/login/index?redirectURL=/' + redirectURL,
++      })
++      return Promise.reject('refreshToken也過期了,就只能重新登錄了')
++    }
    const app = getApp()
    // 調(diào)用接口獲取新的 token
    const res = await http({
      url: '/refreshToken',
      method: 'POST',
      header: {
        Authorization: 'Bearer ' + app.getToken('refreshToken'),
      }
    })

    app.setToken('token', res.token)
    app.setToken('refreshToken', res.refreshToken)
    config = Object.assign(config, {
      header: {
        // 更新后的 token
        Authorization: 'Bearer ' + res.token,
      },
    })
    // 重新發(fā)請(qǐng)求
    return http(config)
  }
  // 攔截器處理后的響應(yīng)結(jié)果
  else if (data.code === 10000) {
    return data.data
  } else {
    wx.$toast(data.message || '請(qǐng)求失敗')
    return Promise.reject(data.message)
  }
}
騰訊位置服務(wù)-需要提前注冊(cè)

文檔地址:https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview

使用步驟(共4步)

  1. 申請(qǐng)開發(fā)者密鑰(key):申請(qǐng)密鑰(地址:https://lbs.qq.com/dev/console/application/mine)
  2. 開通webserviceAPI服務(wù):控制臺(tái) ->應(yīng)用管理 -> 我的應(yīng)用->添加key-> 勾選WebServiceAPI -> 保存(小程序SDK需要用到webserviceAPI的部分服務(wù),所以使用該功能的KEY需要具備相應(yīng)的權(quán)限)

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

3.下載微信小程序JavaScriptSDK,微信小程序JavaScriptSDK v1.1(https://mapapi.qq.com/web/miniprogram/JSSDK/qqmap-wx-jssdk1.1.zip) JavaScriptSDK v1.2(https://mapapi.qq.com/web/miniprogram/JSSDK/qqmap-wx-jssdk1.2.zip) js文件

4.安全域名設(shè)置,在小程序管理后臺(tái)-> 開發(fā) -> 開發(fā)管理 -> 開發(fā)設(shè)置 -> “服務(wù)器域名” 中設(shè)置request合法域名,添加https://apis.map.qq.com

地理定位-wx.getLocation

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

獲取用戶所在位置的經(jīng)緯度。在小程序中調(diào)用這個(gè)接口時(shí)必須先在 app.json 中申請(qǐng)調(diào)用權(quán)限(開發(fā)環(huán)境可以省略)。

//app.json
{
  "requiredPrivateInfos": [
++    "getLocation"
  ],
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息將用于小程序位置接口的效果展示"
    }
  },
}

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

Page({
  onLoad() {
    this.getLocation()
  },
  async getLocation() {
    const res = await wx.getLocation() // 要提前申請(qǐng)權(quán)限
    console.log(res)
  },
})

wx.getLocation返回的結(jié)果格式大致如下:

accuracy: 65
errMsg: "getLocation:ok"
horizontalAccuracy: 65
latitude: 30.88131
longitude: 114.37509
speed: -1
verticalAccuracy: 65

wx.getLocation 只能得到經(jīng)緯度信息

逆地址解析-reverseGeocoder

由坐標(biāo) → 坐標(biāo)所在位置的文字描述的轉(zhuǎn)換,輸入坐標(biāo)返回地理位置信息和附近poi列表

文檔地址:https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/methodReverseGeocoder

1. 導(dǎo)入 QQMapWX 并設(shè)置好 key

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

2.在代碼中補(bǔ)充getPoint方法:

  1. 調(diào)用接口把經(jīng)緯度轉(zhuǎn)換成對(duì)應(yīng)位置的文字
  2. 保存文字到address
// 導(dǎo)入位置服務(wù)實(shí)例
import QQMap from '../../../utils/qqmap'

Page({   ......
  onLoad() {
    this.getLocation()
  },
  async getLocation() {
    // 調(diào)用小程序API獲取經(jīng)緯度等信息
    const { latitude, longitude } = await wx.getLocation()  //獲取用戶經(jīng)緯度
    this.getPoint(latitude, longitude)  
  },
  getPoint(latitude, longitude) {
    // 逆地址解析(根據(jù)經(jīng)緯度來獲取地址)
    QQMap.reverseGeocoder({
      location: [latitude, longitude].join(','),
      success: (result) => {
        const address = res.address
        this.setData({ address })
      },
    })
  }
})

3.渲染頁面

 <van-cell-group border="{{false}}" title="當(dāng)前地點(diǎn)">
  <van-cell title="{{address}}" border="{{false}}">  //border="{{false}}"設(shè)置無邊框樣式
    <text bind:tap="chooseLocation" class="enjoy-icon icon-locate">重新定位</text>
  </van-cell>
</van-cell-group>
QQMap地點(diǎn)搜索—search

根據(jù)當(dāng)前的定位,調(diào)用 QQMap.search() 找到周邊的信息。

搜索周邊poi(Point of Interest),比如:“酒店” “餐飲” “娛樂” “學(xué)?!?等等
文檔地址:https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/methodSearch

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

在小程序中調(diào)用這個(gè)接口時(shí)必須要在 app.json 中申請(qǐng)調(diào)用權(quán)限

//app.json
{
  "requiredPrivateInfos": [
++    "chooseLocation"
  ]
}
// 選擇新的位置
async chooseLocation() {
  // 調(diào)用小程序 API 獲取新的位置
  const { latitude, longitude } = await wx.chooseLocation()
  this.getPoint(latitude, longitude)   // 獲取新的位置經(jīng)緯度
},

getPoint(latitude, longitude) {
  wx.showLoading({
    title: '正在加載...',      // 顯示loading提示
  })

  // 逆地址解析(根據(jù)經(jīng)緯度來獲取地址)
  QQMap.reverseGeocoder({
    location: [latitude, longitude].join(','),
    success: ({ result: { address } }) => {
      this.setData({ address })
    },
  })

  QQMap.search({
    keyword: '住宅小區(qū)', //搜索關(guān)鍵詞
    location: [latitude, longitude].join(','), //設(shè)置周邊搜索中心點(diǎn)
    page_size: 5,   //只顯示5條信息,不設(shè)置此項(xiàng)默認(rèn)為10
    success: (result) => {     //success 是一個(gè)回調(diào)函數(shù),表示搜索成功后的處理邏輯。
      const points = result.data
      this.setData({ points }) // 渲染數(shù)據(jù)
    },
    fail: (err) => {    //fail 是一個(gè)回調(diào)函數(shù),表示搜索失敗后的處理邏輯。
      console.log(err.message)
    },
    complete: () => {//complete 是一個(gè)回調(diào)函數(shù),表示搜索結(jié)束后的處理邏輯(無論搜索成功還是失?。?/span>
      wx.hideLoading()   // 隱藏loading提示
    },
  })
},
重新定位-wx.chooseLocation

原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)

申請(qǐng)權(quán)限

獲取用戶指定位置的經(jīng)緯度。在小程序中調(diào)用這個(gè)接口時(shí)必須要在 app.json 中申請(qǐng)調(diào)用權(quán)限

{
  "requiredPrivateInfos": [
    "chooseLocation"
  ]
}

示例代碼:

// 選擇新的位置
async chooseLocation() {
  // 調(diào)用小程序 API 獲取新的位置
  const { latitude, longitude } = await wx.chooseLocation()
  // 獲取新的位置附近的小區(qū)
  this.getPoint(latitude, longitude)

  console.log('起點(diǎn)位置:', latitude, longitude)
},

getPoint(latitude, longitude) {
  // 顯示loading提示
  wx.showLoading({
    title: '正在加載...',
  })

  // 逆地址解析(根據(jù)經(jīng)緯度來獲取地址)
  QQMap.reverseGeocoder({
    location: [latitude, longitude].join(','),
    success: ({ result: { address } }) => {
      // console.log(address)
      // 數(shù)據(jù)數(shù)據(jù)
      this.setData({ address })
    },
  })

  QQMap.search({
    keyword: '住宅小區(qū)', //搜索關(guān)鍵詞
    location: [latitude, longitude].join(','), //設(shè)置周邊搜索中心點(diǎn)
    page_size: 5,
    success: (result) => {
      // console.log(result)
      // 過濾掉多余的數(shù)據(jù)
      const points = result.data.map(({ id, title, _distance }) => {
        return { id, title, _distance }
      })

      // console.log(points)
      // 渲染數(shù)據(jù)
      this.setData({ points })
    },
    fail: (err) => {
      console.log(err.message)
    },
    complete: () => {
      // 隱藏loading提示
      wx.hideLoading()
    },
  })
},
圖片收集(收集身份證信息)

小程序沒有input type="file"用于選擇文件,要實(shí)現(xiàn)類似功能,用以下api:
wx.chooseMedia**:**拍攝或從手機(jī)相冊(cè)中選擇圖片或視頻。
低版本請(qǐng)用wx.chooseImage。

1.綁定事件選擇身份證圖片上傳。

2.發(fā)送請(qǐng)求上傳圖片,拿到上傳后的圖片地址。

Page({
 ...
  async uploadPicture(ev) {
    // 獲取圖片臨時(shí)地址
    const res = await wx.chooseMedia({
      count: 1,
      mediaType: ['image'],
      sizeType: ['compressed'],
    })
    const tempPath = res.tempFiles[0].tempFilePath
    const type = ev.mark.type
    // 上傳圖片到服務(wù)器
    wx.uploadFile({
      url: wx.$http.baseURL + '/upload',
      filePath: tempPath,
      name: 'file',
      header: {
        Authorization:  'Bearer ' +  getApp().getToken(),
      },
      success: (res) => {
        const res = JSON.parse(result.data)
        console.log(res.data.url) 							// 上傳成功的回調(diào)
        this.setData({ [type]: res.data.url })
      },
    })
  },
})
校驗(yàn)表單信息

獲取了全部的表單數(shù)據(jù)后再對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證,說明如下:

  • 房屋的信息是通過url地址獲取的不需要驗(yàn)證
  • 性別可以指定默認(rèn)值也不需要驗(yàn)證
  • 剩下的數(shù)據(jù)通過 wechat-validate 插件進(jìn)行驗(yàn)證:
// house_pkg/pages/form/index.js
// 導(dǎo)入表單驗(yàn)證插件
import wxValidate from 'wechat-validate'
Page({
  behaviors: [wxValidate],
  data: {
    point: '',
    building: '',
    room: '',
    name: '',
    gender: 1,
    mobile: '',
    idcardFrontUrl: '',
    idcardBackUrl: '',
  },
  rules: {
    name: [
      { required: true, message: '業(yè)主姓名不能為空!' },
      { pattern: /^[\u4e00-\u9fa5]{2,5}$/, message: '業(yè)主姓名只能為中文!' },
    ],
    mobile: [
      { required: true, message: '業(yè)主手機(jī)號(hào)不能為空!' },
      { pattern: /^1[3-8]\d{9}$/, message: '請(qǐng)?zhí)顚懻_的手機(jī)號(hào)!' },
    ],
    idcardFrontUrl: [
      { required: true, message: '請(qǐng)上傳身份證國(guó)徽面!' }
    ],
    idcardBackUrl: [
      { required: true, message: '請(qǐng)上傳身份證照片面!' }
    ],
  },
})
表單收集—收集預(yù)約日期

1.時(shí)間選擇控件:van-datetime-pickerhttps://vant-contrib.gitee.io/vant-weapp/#/datetime-picker

2.彈出層控件:van-popuphttps://vant-contrib.gitee.io/vant-weapp/#/popup

  1. 給選擇日期單元綁定事件——顯示選擇日期彈層(van-popup)

2.給日期控件綁定確認(rèn)事件confirm

3.在確認(rèn)回調(diào)中獲取時(shí)間戳

4.將時(shí)間戳格式化并顯示

selectDate(ev) {
  // console.log(ev)
  this.setData({
    currentDate: ev.detail,
    appointment: wx.$utils.formatDate(ev.detail), // 格式化日期
  })
  this.closeDateLayer()
},

補(bǔ)充格式化日期的函數(shù)

formatDate(time) {
  const d = new Date(time)
  const year = d.getFullYear()
  let month = d.getMonth() + 1 // 獲取月份,月份從0開始,所以加1
  let day = d.getDate()
  month = month < 10 ? '0' + month : month
  day = day < 10 ? '0' + day : day
  return `${year}-${month}-${day}`
},

wxml

<van-cell title-width="100" title="預(yù)約日期" value-class="{{appointment && 'active-cell'}}" bind:click="openDateLayer"
        is-link value="{{appointment || '請(qǐng)選擇上門維修日期'}}" />
...省略
<van-popup bind:close="closeDateLayer" round show="{{ dateLayerVisible }}" position="bottom">
  <van-datetime-picker bind:cancel="closeDateLayer" bind:confirm="selectDate" type="date" value="{{ currentDate }}"
    min-date="{{ 1664582400000 }}" />
</van-popup>
加載更多

在scroll-view上添加 bindscrolltolower=“l(fā)oadMore”

  <scroll-view 
  bindscrolltolower="loadMore"
  show-scrollbar="{{false}}" enhanced scroll-y>
    <view class="repairs">
      <view class="repairs-title">我的報(bào)修</view>
loadMore() {
    // if(是否有更多的數(shù)據(jù))
    if (this.data.total <= this.data.list.length)
      return
    console.log('更多的數(shù)據(jù)')
    // 把頁碼+1,發(fā)請(qǐng)求,請(qǐng)求回來的數(shù)據(jù)要 追加 到原數(shù)組
    // [5] → [10]
    this.data.page++
    this.getList()

  },
  async getList() {
    // 發(fā)請(qǐng)求
    const { pageTotal, total, rows: list } = await wx.$http.get('/repair', { current: this.data.page, pageSize: this.data.pageSize })
    console.log(list, pageTotal, total)
    // 渲染數(shù)據(jù)
    // 在原來的基礎(chǔ)上添加數(shù)據(jù)
    this.setData({ total, list: [...this.data.list, ...list] })
  },

路線規(guī)劃

路線規(guī)劃是常見的一個(gè)功能,它用來在地圖上展示兩點(diǎn)間路線,要使用這個(gè)功能需要用到兩部分的知識(shí):

  1. 小程序提供的 map 組件用來在頁面渲染地圖

map | 微信開放文檔https://developers.weixin.qq.com/miniprogram/dev/component/map.html)

  1. 騰訊位置服務(wù)計(jì)算兩點(diǎn)路線的所有坐標(biāo)點(diǎn)(經(jīng)緯度)

首先來看小程序提供的地圖組件 map

  • latitude 指定地圖中心點(diǎn)的緯度
  • longitude 指定地圖中心點(diǎn)的經(jīng)功
  • scale 指定地圖初始的縮放比例,取值范圍 3 - 20
  • markers 地圖上的標(biāo)記點(diǎn)
  • polyline 地圖上的路線

latitude、longitude、scale 相對(duì)容易理解,重點(diǎn)來看一下 markers 的使用:

repqir_pkg/pages/detail/index.js

Page({
  data: {
    markers: [
      {
        id: 1,
        latitude: 40.22077,
        longitude: 116.23128,
        width: 24,
        height: 30,
      },
      {
        id: 2,
        latitude: 40.225857999999995,
        longitude: 116.23246699999999,
        iconPath: '/static/images/marker.png',
        width: 40,
        height: 40,
      },
    ],
  }
})

在定義標(biāo)記點(diǎn)時(shí)每個(gè)標(biāo)記點(diǎn)必須要指定 ID 屬性,否則會(huì)有錯(cuò)誤產(chǎn)生,通過 iconPath 可以自定義標(biāo)記點(diǎn)的圖片,width/height 定義標(biāo)記點(diǎn)的大小尺寸。

polyline

polyline 用來在在圖上展示兩點(diǎn)間的行進(jìn)路線,需要傳遞給它路線對(duì)應(yīng)的坐標(biāo)點(diǎn)(很多個(gè)點(diǎn)組成的線),獲取這些坐標(biāo)點(diǎn)需要通過位置服務(wù)計(jì)算得到。

計(jì)算兩點(diǎn)間路線的坐標(biāo)點(diǎn)需要用到位置服務(wù)的[路線規(guī)劃]https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/methodDirection方法

repqir_pkg/pages/detail/index.js

// repqir_pkg/pages/detail/index.js
Page({
  data: {},
  onLoad() {
    // 生成路線
    this.getPolyline()
  },
  // 調(diào)用位置服務(wù)(路線規(guī)劃)
  getPolyline() {
    qqMap.direction({
      mode: 'bicycling',
      from: '40.227978,116.22998',
      to: '40.22077,116.23128',
      success: ({ result }) => {
        const coors = result.routes[0].polyline
        const points = []
        //坐標(biāo)解壓(返回的點(diǎn)串坐標(biāo),通過前向差分進(jìn)行壓縮)
        for (let i = 2; i < coors.length; i++) {
          coors[i] = Number(coors[i - 2]) + Number(coors[i]) / 1000000
        }
        // 獲取經(jīng)緯度
        for (let i = 0; i < coors.length; i += 2) {
          points.push({ latitude: coors[i], longitude: coors[i + 1] })
        }
        // 渲染數(shù)據(jù)
        this.setData({
          latitude: points[30].latitude,
          longitude: points[30].longitude,
          polyline: [
            {points, color: '#5591af', width: 4},
          ],
        })
      },
    })
  },
})

計(jì)算出來的坐標(biāo)點(diǎn)是經(jīng)過壓縮的,需要按著官方指定的方式對(duì)數(shù)據(jù)進(jìn)行解壓才可以獲取真正的坐標(biāo)點(diǎn),并且為了適應(yīng)小程序地圖組件的用法,還需要對(duì)數(shù)據(jù)進(jìn)行二次的加工。

關(guān)于數(shù)據(jù)的處理大家只需要參考文檔來實(shí)現(xiàn)就可以,可以說之所這么操作是騰訊位置服務(wù)規(guī)訂好的,做為開發(fā)者按著官方提從的方法來應(yīng)用即可。

自定義分享

[onShareAppMessage]https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object

監(jiān)聽用戶點(diǎn)擊頁面內(nèi)轉(zhuǎn)發(fā)按鈕(button 組件 open-type=“share”)或右上角菜單“轉(zhuǎn)發(fā)”按鈕的行為,并自定義轉(zhuǎn)發(fā)內(nèi)容。

注意:只有定義了此事件處理函數(shù),右上角菜單才會(huì)顯示“轉(zhuǎn)發(fā)”按鈕

Page({
  onLoad({ id, encryptedData }) {
    this.getPassport(id)
    this.getPassportShare(encryptedData)
  },
  // 獲取訪客詳情(通行證)
  async getPassport(id) {
    // 檢測(cè)是否存在 id
    if (!id) return
    // 調(diào)用接口
    const passport = await wx.$http.get('/visitor/' + id)
    // 渲染數(shù)據(jù)
    this.setData({ ...passport })
  }
  async getPassportShare(encryptedData) {
    // 檢測(cè)是否存在 id
    if (!encryptedData) return
    // 調(diào)用接口
    const passport = await wx.$http.get('/visitor/share/' + this.data.encryptedData)
    // 渲染數(shù)據(jù)
    this.setData({ passport })
  },
  onShareAppMessage() {
    return {
      title: '查看通行證',
      path: '/visitor_pkg/pages/passport/index?encryptedData=' + encryptedData,
      imageUrl: 'https://enjoy-plus.oss-cn-beijing.aliyuncs.com/images/share_poster.png',
    }
  },
})
保存到本地api介紹

[saveImageToPhotosAlbum]https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.saveImageToPhotosAlbum.html

保存圖片到系統(tǒng)相冊(cè)。

[getImageInfo]https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.getImageInfo.html

獲取圖片信息。網(wǎng)絡(luò)圖片需先配置 download 域名才能生效。

保存到本地實(shí)現(xiàn)

1.給按鈕綁定事件,調(diào)用getImageInfo獲取圖片臨時(shí)路徑

2.調(diào)用saveImageToPhotosAlbum傳入臨時(shí)路徑完成保存功能文章來源地址http://www.zghlxwxcb.cn/news/detail-495075.html

// 保存圖片
  async saveQRCode() {
    try {
      // 讀取圖片信息
      const { path } = await wx.getImageInfo({
        src: this.data.url,
      })
      // 保存圖片到相冊(cè)
      wx.saveImageToPhotosAlbum({ filePath: path })
    } catch (err) {
      wx.$toast('保存圖片失敗,稍后重試!')
    }
  },

ush({ latitude: coors[i], longitude: coors[i + 1] })
}
// 渲染數(shù)據(jù)
this.setData({
latitude: points[30].latitude,
longitude: points[30].longitude,
polyline: [
{points, color: ‘#5591af’, width: 4},
],
})
},
})
},
})


計(jì)算出來的坐標(biāo)點(diǎn)是經(jīng)過壓縮的,需要按著官方指定的方式對(duì)數(shù)據(jù)進(jìn)行解壓才可以獲取真正的坐標(biāo)點(diǎn),并且為了適應(yīng)小程序地圖組件的用法,還需要對(duì)數(shù)據(jù)進(jìn)行二次的加工。

關(guān)于數(shù)據(jù)的處理大家只需要參考文檔來實(shí)現(xiàn)就可以,可以說之所這么操作是騰訊位置服務(wù)規(guī)訂好的,做為開發(fā)者按著官方提從的方法來應(yīng)用即可。

### 自定義分享

**[onShareAppMessage]https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object**

監(jiān)聽用戶點(diǎn)擊頁面內(nèi)轉(zhuǎn)發(fā)按鈕([button](https://developers.weixin.qq.com/miniprogram/dev/component/button.html) 組件 open-type="share")或右上角菜單“轉(zhuǎn)發(fā)”按鈕的行為,并自定義轉(zhuǎn)發(fā)內(nèi)容。

**注意:只有定義了此事件處理函數(shù),右上角菜單才會(huì)顯示“轉(zhuǎn)發(fā)”按鈕**

```js
Page({
  onLoad({ id, encryptedData }) {
    this.getPassport(id)
    this.getPassportShare(encryptedData)
  },
  // 獲取訪客詳情(通行證)
  async getPassport(id) {
    // 檢測(cè)是否存在 id
    if (!id) return
    // 調(diào)用接口
    const passport = await wx.$http.get('/visitor/' + id)
    // 渲染數(shù)據(jù)
    this.setData({ ...passport })
  }
  async getPassportShare(encryptedData) {
    // 檢測(cè)是否存在 id
    if (!encryptedData) return
    // 調(diào)用接口
    const passport = await wx.$http.get('/visitor/share/' + this.data.encryptedData)
    // 渲染數(shù)據(jù)
    this.setData({ passport })
  },
  onShareAppMessage() {
    return {
      title: '查看通行證',
      path: '/visitor_pkg/pages/passport/index?encryptedData=' + encryptedData,
      imageUrl: 'https://enjoy-plus.oss-cn-beijing.aliyuncs.com/images/share_poster.png',
    }
  },
})
保存到本地api介紹

[saveImageToPhotosAlbum]https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.saveImageToPhotosAlbum.html

保存圖片到系統(tǒng)相冊(cè)。

[getImageInfo]https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.getImageInfo.html

獲取圖片信息。網(wǎng)絡(luò)圖片需先配置 download 域名才能生效。

[外鏈圖片轉(zhuǎn)存中…(img-M8SkNwoO-1687267859406)]

保存到本地實(shí)現(xiàn)

1.給按鈕綁定事件,調(diào)用getImageInfo獲取圖片臨時(shí)路徑

2.調(diào)用saveImageToPhotosAlbum傳入臨時(shí)路徑完成保存功能

// 保存圖片
  async saveQRCode() {
    try {
      // 讀取圖片信息
      const { path } = await wx.getImageInfo({
        src: this.data.url,
      })
      // 保存圖片到相冊(cè)
      wx.saveImageToPhotosAlbum({ filePath: path })
    } catch (err) {
      wx.$toast('保存圖片失敗,稍后重試!')
    }
  },

到了這里,關(guān)于原生微信小程序全流程(基礎(chǔ)知識(shí)+項(xiàng)目全流程)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 第四章 云原生架構(gòu)之Kubernetes基礎(chǔ)知識(shí)

    第四章 云原生架構(gòu)之Kubernetes基礎(chǔ)知識(shí)

    ? Kubernetes是一個(gè)可移植、可擴(kuò)展的開源平臺(tái),用于管理容器化的工作負(fù)載和服務(wù),簡(jiǎn)稱 K8S。 K8S的本質(zhì)是一組服務(wù)器集群,可以在對(duì)應(yīng)服務(wù)器集群的每個(gè)節(jié)點(diǎn)上運(yùn)行程序,來對(duì)節(jié)點(diǎn)中的容器進(jìn)行管理 。類似Master-Work方式,每個(gè)服務(wù)器上安裝特定的k8s組件,就可以形成集群,然

    2024年02月17日
    瀏覽(27)
  • 【三維重建】三維重構(gòu)基礎(chǔ)知識(shí)、三維數(shù)據(jù)、重建流程

    【三維重建】三維重構(gòu)基礎(chǔ)知識(shí)、三維數(shù)據(jù)、重建流程

    1.使用幾何建模軟件,通過人機(jī)交互生成人為控制下的三維:3DMAX、Maya、AutoCAD、UG 2.獲取真實(shí)的物體形狀:三維重構(gòu) 三維圖像重構(gòu): 攝像機(jī)獲取圖像,對(duì)圖像分析處理,結(jié)合CV知識(shí)推導(dǎo)出現(xiàn)實(shí)中物體的三維信息 從二維圖像到三維空間的重構(gòu)(模仿生物兩只眼睛觀察物體產(chǎn)生的

    2024年02月02日
    瀏覽(20)
  • webpack基礎(chǔ)知識(shí)二:說說webpack的構(gòu)建流程?

    webpack基礎(chǔ)知識(shí)二:說說webpack的構(gòu)建流程?

    一、運(yùn)行流程 webpack 的運(yùn)行流程是一個(gè)串行的過程,它的工作流程就是將各個(gè)插件串聯(lián)起來 在運(yùn)行過程中會(huì)廣播事件,插件只需要監(jiān)聽它所關(guān)心的事件,就能加入到這條webpack機(jī)制中,去改變webpack的運(yùn)作,使得整個(gè)系統(tǒng)擴(kuò)展性良好 從啟動(dòng)到結(jié)束會(huì)依次執(zhí)行以下三大步驟: 初

    2024年02月14日
    瀏覽(30)
  • 【云原生持續(xù)交付和自動(dòng)化測(cè)試】5.3 持續(xù)交付和DevOps實(shí)踐基礎(chǔ)知識(shí)

    往期回顧: 第一章:【云原生概念和技術(shù)】 第二章:【容器化應(yīng)用程序設(shè)計(jì)和開發(fā)】 第三章:【基于容器的部署、管理和擴(kuò)展】 第四章:【微服務(wù)架構(gòu)設(shè)計(jì)和實(shí)現(xiàn)】 第五章:【5.1 自動(dòng)化構(gòu)建和打包容器鏡像】 第五章:【5.2 自動(dòng)化測(cè)試和集成測(cè)試】 云原生下對(duì)持續(xù)交付(

    2024年02月09日
    瀏覽(57)
  • 基礎(chǔ)課19——客服系統(tǒng)知識(shí)庫(kù)的搭建流程

    基礎(chǔ)課19——客服系統(tǒng)知識(shí)庫(kù)的搭建流程

    注意:我們?cè)谧鰳I(yè)務(wù)數(shù)據(jù)收集時(shí),往往是甲方提供給我們的,這時(shí)就需要確定一個(gè)標(biāo)準(zhǔn),否則對(duì)知識(shí)庫(kù)梳理工作會(huì)帶來很大的難度,建議和甲方溝通確認(rèn)一個(gè)雙方都統(tǒng)一的知識(shí)庫(kù)原材料。 在創(chuàng)建知識(shí)庫(kù)時(shí),我們最常見的就是把問題分為單輪、多輪,來滿足不同場(chǎng)景的需求,如

    2024年02月05日
    瀏覽(31)
  • 網(wǎng)絡(luò)編程 tcp udp http編程流程 網(wǎng)絡(luò)基礎(chǔ)知識(shí)

    網(wǎng)絡(luò)編程 tcp udp http編程流程 網(wǎng)絡(luò)基礎(chǔ)知識(shí)

    OSI分層:應(yīng)用層 表示層 會(huì)話層 傳輸層 網(wǎng)絡(luò)層 數(shù)據(jù)鏈路層 物理層 tcp/ip: 應(yīng)用層 傳輸層 網(wǎng)絡(luò)層 數(shù)據(jù)鏈路 ip地址:唯一標(biāo)識(shí)一臺(tái)主機(jī) ipv4 32位 ipv6 128位 尋址 可以反映物理上的一個(gè)變化 MAC地址:48 固化在計(jì)算機(jī)中 ip地址又兩部分構(gòu)成:網(wǎng)絡(luò)號(hào)+主機(jī)號(hào) 端口號(hào):標(biāo)識(shí)一個(gè)應(yīng)用程序

    2024年02月13日
    瀏覽(39)
  • 云原生可觀測(cè)框架 OpenTelemetry 基礎(chǔ)知識(shí)(架構(gòu)/分布式追蹤/指標(biāo)/日志/采樣/收集器)...

    云原生可觀測(cè)框架 OpenTelemetry 基礎(chǔ)知識(shí)(架構(gòu)/分布式追蹤/指標(biāo)/日志/采樣/收集器)...

    OpenTelemetry 是一個(gè)開源的可觀測(cè)性框架,由云原生基金會(huì)(CNCF)托管。它是 OpenCensus 和 OpenTracing 項(xiàng)目的合并。旨在為所有類型的可觀測(cè)信號(hào)(如跟蹤、指標(biāo)和日志)提供單一標(biāo)準(zhǔn)。 https://opentelemetry.io https://www.cncf.io https://opencensus.io OpenTelemetry 指定了如何收集遙測(cè)數(shù)據(jù)并將其發(fā)送到

    2024年01月16日
    瀏覽(46)
  • Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基礎(chǔ)頁面框架的靜態(tài)設(shè)計(jì)(二)

    Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基礎(chǔ)頁面框架的靜態(tài)設(shè)計(jì)(二)

    Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基礎(chǔ)頁面框架的靜態(tài)設(shè)計(jì)(二) 在開始這個(gè)專欄,我們需要找一個(gè)小程序?yàn)閰⒖?,參考和仿照其界面,聊天交互模式?這里參考小程序- 小檸AI智能聊天 ,可自行先體驗(yàn)。 該小程序主要提供了以下幾點(diǎn) 功能向需求 : 每天免費(fèi)

    2024年02月14日
    瀏覽(21)
  • 【前端知識(shí)】React 基礎(chǔ)鞏固(三十二)——Redux的三大原則、使用流程及實(shí)踐

    【前端知識(shí)】React 基礎(chǔ)鞏固(三十二)——Redux的三大原則、使用流程及實(shí)踐

    單一數(shù)據(jù)源 整個(gè)應(yīng)用程序的state被存儲(chǔ)在一顆object tree 中,并且這個(gè)object tree 只存儲(chǔ)在一個(gè)store中; Redux并沒有強(qiáng)制讓我們不能創(chuàng)建多個(gè)Store,但是那樣做不利于數(shù)據(jù)維護(hù); 單一的數(shù)據(jù)源可以讓整個(gè)應(yīng)用程序的state變得方便維護(hù)、追蹤、修改; State是只讀的 唯一修改State的方法

    2024年02月15日
    瀏覽(31)
  • mysql數(shù)據(jù)庫(kù)面試題基礎(chǔ)知識(shí),Hadoop之MapReduce04,騰訊java面試流程

    mysql數(shù)據(jù)庫(kù)面試題基礎(chǔ)知識(shí),Hadoop之MapReduce04,騰訊java面試流程

    該方法的執(zhí)行過程比較復(fù)雜,我們慢慢來分析,首先來看下簡(jiǎn)化的時(shí)序圖 3.1waitForCompletion public boolean waitForCompletion(boolean verbose ) throws IOException, InterruptedException, ClassNotFoundException { // 判斷任務(wù)的狀態(tài),如果是DEFINE就提交 if (state == JobState.DEFINE) { submit(); } if (verbose) { // 監(jiān)聽并且

    2024年04月14日
    瀏覽(33)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包