放心,手把手教你寫微信小程式

2020-10-22 21:02:15

欄目今天詳細教大家寫微信小程式。

小程式的歷史介紹

什麼是微信小程式?

微信小程式,簡稱小程式。英文名mini program,是一種不需要下載安裝就可以直接使用的應用。他實現了觸手可及的夢想。使用者掃一掃或搜一下就可以直接開啟應用。

為什麼是微信小程式

  1. 微信有海量使用者
  2. 推廣app或公眾號成本太高
  3. 開發適配成本低
  4. 容易小規模試錯,然後快速迭代
  5. 跨平臺

歷史

  1. 2016年1月11日,張小龍,微信內部研究新的形態,應用號,後改名小程式
  2. 2016年8月12日,開始內測
  3. 2017年1月9日,上線

#環境規範

  1. 註冊賬號

    mp.weixin.qq.com/ (帳號資訊 --- 郵箱啟用 --- 資訊登記)

  2. 獲取id

    APPID ([登入微信公眾平臺](https://mp.weixin.qq.com/wxamp/devprofile/get_profile?token=942994743&lang=zh_CN) ---> 開發 ---> 開發設定)複製程式碼

    <img src="https://img.php.cn/upload/article/000/000/052/62154dd59d731a99e80263d5b4735b83-0.jpg Support/typora-user-images/image-20200707110747168.png" alt="image-20200707110747168" style="zoom:80%;" />

  3. 開發者工具

    微信開發者工具下載

小程式開發者工具

開發者工具介紹

快捷鍵:

1. ctrl + shift + F (搜尋)
2. alt + shift + F (程式碼格式化---VSCode)複製程式碼

<img src="https://img.php.cn/upload/article/000/000/052/62154dd59d731a99e80263d5b4735b83-0.jpg Support/typora-user-images/image-20200707112457994.png" alt="image-20200707112457994" style="zoom:50%;" />

小程式原生框架

小程式的原生框架,mina框架 框架詳情

小程式組態檔(寫組態檔在微信開發者工具工具寫,有提示)

  1. app.json 全域性組態檔

    設定全域性檔案
    
    * pages:新增要建立的檔案項,儲存後就會自動生成檔案
    
    * [windows](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html):設定小程式的狀態列,導覽列,標題視窗顏色複製程式碼

    <img src="https://img.php.cn/upload/article/000/000/052/62154dd59d731a99e80263d5b4735b83-0.jpg Support/typora-user-images/image-20200707142609082.png" alt="image-20200707142609082" style="zoom:50%;" />

    * [tabBar](https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html)複製程式碼

    <img src="https://img.php.cn/upload/article/000/000/052/62154dd59d731a99e80263d5b4735b83-0.jpg Support/typora-user-images/image-20200707143939070.png" alt="image-20200707143939070" style="zoom:50%;" />

  2. page.json 頁面組態檔

  3. sitemap

小程式的模板語法

WXML ---> HTML (結合基礎元件,事件系統,構件出頁面結構)

  1. 相當於 ,行內標籤,不會換行
  2. 相當於,塊級元素,會換行

資料繫結

{{ 資料 }}

  1. 運算 --> 表示式( 數值計算,字串拼接,三元表示式)

  2. 列表迴圈 (wx:for)

    wx:key繫結的是陣列中的為唯一屬性,wx:key=this表示陣列是普通陣列,`this`是迴圈項

    <view wx:for="{{ person }}" wx:for-item="item" wx:for-index="index"wx:key="id">
        索引: {{ index }}
        名稱: {{ item.name }}</view>複製程式碼
  3. 標籤 ---> 佔位標籤

  4. 條件渲染(wx:if)(wx:if, wx:elif, wx:else) (hidden 屬性是通過新增樣式的方式來呈現的)

    當標籤不是頻繁的切換使用if,頻繁切換使用hidden

事件繫結

關鍵字:bind (bindinput,bindtap【點選事件】)

獲取事件源物件的值:

 e.detail.value複製程式碼

獲取data中資料的值:

 this.data.屬性名複製程式碼

將事件源物件的值設定回data中:

 this.setData({
        num: this.data.num + operation
});複製程式碼

事件繫結是不能直接傳參,要通過自定義屬性的方式傳參( {{ 傳遞的引數}} ):

 <button bindtap="bandletap" data-operation="{{ 1 }}">+</button>
 
 bandletap(e) {
    // console.log(e);
    const operation = e.currentTarget.dataset.operation;
    this.setData({
        num: this.data.num + operation
    });
  },複製程式碼

樣式

尺寸單位

當螢幕寬度等於 750px 時,1px = 1rpx

當螢幕寬度等於375px時, 1px =0.5rpx

樣式匯入只支援相對路徑

選擇器(微信小程式不支援萬用字元)

小程式的內建元件

小程式中常用的佈局元件:

view,text,rich-text,button,image,icon,swiper,radio,checkbox等。複製程式碼
  1. view標籤 相當於 p標籤

  2. text標籤 只能巢狀text標籤 長按文字可以複製【selectable】(只有這個標籤有這個功能) 可以對回車,空格進行編碼 (decode)

  3. image標籤 (打包上線的大小不能超過2M,使用圖片的時候統一使用外網圖片)

    1. 圖片存在預設的寬高(320px * 240px)

    2. mode 決定 圖片內容 和 圖片標籤 做適配

      scaleToFill 預設值 不保持縱橫比,拉伸至標籤定義的寬高

      aspectFit 保持寬高比,保證圖片的長邊完全顯示(常用 輪播圖)

      aspectFill 短邊完全顯示

      widthFix 寬度不變,高度自動變化,保持原寬高比不變

      top,left,bottom,right 背景圖定位

    3. 小程式中的圖片 直接支援 懶載入

      lazy-load 會自己判斷 當圖片出現在視口的上下三屏之內的時候,自己開始載入圖片

  4. swiper標籤 ---》 輪播圖

    swiper高度 = swiper的寬度 * 圖片的高度 / 原圖的寬度

    <swiper autoplay interval="1000" circular indicator-dots>
        // 圖片存在預設寬高  320 * 240    <swiper-item><image model="widthFix" src="" /></image></swiper-item></swiper>複製程式碼
  5. navigator 導航元件 (塊級元素,預設換行)

    <navigator url="/pages/homepage/index" open-type="navigate"></navigator>複製程式碼
  6. rich-text(富文字標籤,將字串解析成對應標籤,相當於v-html)

    // 1 標籤字串<rich-text nodes="{{ html }}"></rich-text>// 2 物件陣列<rich-text nodes="{{ html.model }}"></rich-text>複製程式碼
  7. button 按鈕

    大小(size:mini/default),顏色(type:default/primary/warn),是否鏤空(plain),是否在文字前有載入loading(loading),開發能力(opentype)

開放能力(opentype):

  1. concat 直接開啟 客服對話 功能,需要在小程式的後臺設定

    1. 將小程式的appid由測試號改為自己的appid
    2. 登入微信小程式官網,新增 客服 - 微信
  2. share 轉發當前小程式到微信朋友中 ,不能把小程式轉發到朋友圈中

  3. getPhoneNumber 獲取當前使用者的手機號碼,結合事件來使用,不是企業的小程式賬號 沒有許可權來獲取使用者的手機號碼

  4. getUserInfo獲取使用者的個人資訊

  5. launchApp在 小程式 中直接開啟 app

  6. openSetting 開啟小程式內建的授權頁面

    只會出現使用者點選過的許可權

  7. feedback 開啟小程式內建的意見反饋頁面

  8. icon

    type:型別 success,success_no_circle,info,warn,wating.success_no_circle,info,warn,waiting,cancel,downkload,search,clear

    size:大小 number / string

    color:顏色

  9. radio 單選框

    <radio-group bindchange="handleChange">
        <radio color="red" value="male">男</radio>
        <radio color="red" value="female">女</radio></radio-group><view>選中的是: {{ gender }} </view>data:{
        gender: ""
    },
    handleChange(e) {
        // 獲取單選框選中的值
        let gender = e.detail.value;
        // 把值賦值給data中的資料
        this.setData({
            gender // 相當於 gender:gender
        })
    }複製程式碼
  10. checkbox 多選框

    <checkbox-group bindchange="handleChange">
        <checkbox value="{{ item.value }}" wx:for="{{ list }}" wx:key="id">{{ item.name }}           </checkbox></checkbox-group><view>選中的是: {{ checkedList }} </view>checkedList:[]
    handleChange(e) {
        let checkedList = e.detail.value;
        this.setData({
            checkedList
        })
    }複製程式碼

小程式的生命週期

應用生命週期

觸發過程:

onLaunch -》 onShow

App({    // 1 應用 第一次啟用的時候觸發
    onLaunch() {        // 在應用第一次啟動的時候 獲取使用者資訊
    }    
    // 2 應用 被使用者看到的時候觸發
    onShow() {        // 常用於小程式介面之間的切換
        // 對應用的資料或者頁面的效果進行重置
    }    // 3 應用 被隱藏的時候觸發
    onHide() {        // 暫停或者清楚定時器
    }    // 4 應用 程式碼發生報錯的時候  執行
    onError() {        // 在應用發生程式碼報錯的時候,收集使用者的錯誤資訊,通過非同步請求,將錯誤資訊傳送到後臺去
    }    // 5 頁面找不到的時候就會觸發
    // 應用第一次啟動的時候,如果找不到第一個入口頁面,才會觸發
    onPageNotFound() {        // 如果頁面不存在了  通過js的方式來重新跳轉頁面  重新跳轉到第二個首頁
        // 不能跳轉到tabbar頁面  導航元件類似
        wx.navigateTo({            url: "/pages/demo02/index"
        })
    }
})複製程式碼

頁面生命週期

onLoad -> onShow -> onReady

Page({    data: {
        
    },    onLoad: function(options) {        // onload傳送非同步請求來初始化頁面資料
    },    onShow: function() {        // 頁面顯示載入
    },    onReady: function() {        // 頁面初次渲染完成
    },    onHide: function() {        // 頁面隱藏時載入  一個頁面跳轉到另外一個頁面也會觸發onHide事件
    },    onUnload: function() {        // 頁面解除安裝  也可以通過超連結   關閉當前頁面就會觸發onUnload事件
        // <navigator url="/pages/demo01/demo01" open-typr-redirect>demo01</navigator>
        
        // 關閉當前頁面就代表著解除安裝頁面
    },    onPullDownRefresh: function() {        // 監聽使用者下拉事件  "enablePullDownRefresh":true
        //  頁面效果的重新載入
    },    onReachBotton: function() {        // 監聽使用者上拉觸底事件   【需要讓頁面出現上下的捲動才行】
        // 常用於  上拉載入下一頁操作
    },    onShareAppMessage: function() {        // 使用者點選右上角轉發
    },    onPageScroll: function() {        // 頁面捲動就觸發
    },    onResize: function() {        // 頁面尺寸發生變化的時候觸發   
        // 常指 手機橫屏豎屏的時候  觸發    
        //  app.json中新增   "pageOrientation":"auto"
    },    onTabItemTap: function() {        // 1. 當前頁面必須為tabbar頁面
        // 2. 點選的是自己的tab  item的時候才觸發
    }
})複製程式碼

小程式自定義元件

步驟:

  1. 建立

  2. 宣告(那個頁面要使用自定義元件,就在那個頁面的json檔案中宣告)

    {    "usingComponents": {        "Tabs": "../../components/Tabs/Tabs"
        }
    }複製程式碼
  3. 使用

    <Tabs></Tabs>複製程式碼

注意:

  • 頁面的.js檔案中,存放事件回撥函數的時候,存放在data同層級下

  • 元件的.js檔案中,存放時間的回撥函數的時候,存放在methods中

  • 在小程式中不要直接通過this.data.x.來修改陣列的值(建議先拷貝一份陣列,然後再對拷貝的陣列進行修改)

    let tabs = JSON.parse(JSON.stringify(this.data.tabs));let tabs = this.data;複製程式碼

元件之間的傳值

父元件向子元件傳值

通過 標籤的屬性來傳遞的:

  1. 父元件傳遞

    <Tabs aaa="123"></Tabs>複製程式碼
  2. 子元件接收

    Component({    // 裡面存放的是要從父元件中接收的資料
        properties: {        // 要接受的資料的名稱
            aaa:{            //type 接收資料的型別
                type: String,            //value 預設值
                value: ""
            }
        }
    });複製程式碼
  3. 子元件使用父元件中傳遞過來的資料

    將接收過來的資料當作本身data中的資料來使用

    <view>{{ aaa }}</view>複製程式碼

子元件向父元件傳值

通過事件來傳遞的。

tab切換欄,點選切換。

  1. 繫結點選事件 需要在methods中繫結
  2. 獲取被點選的索引
  3. 獲取原陣列
  4. 對陣列迴圈
    1. 給每一個迴圈項 選中屬性 改為 false
    2. 給 當前的索引 的 項 新增啟用選中效果
  5. 點選事件觸發的時候,觸發父元件中的自定義事件同時傳遞給父元件
    1. this.triggerEvent("父元件自定義事件的名稱",要傳遞的引數)

Tabs頁面中:

<view 
      wx:for="{{tabs}}" 
      wx:key="id" 
      class="title_item {{item.isActive?'active':''}}"
      bindtap="hanldeItemTap"
      data-index="{{index}}">{{ item.name }}</view><view class="tabs_content">
    // 預留位置  傳遞的引數會替換掉 
    <slot></slot></view>複製程式碼

子元件的js檔案中:(這樣寫不能改變元件內部的資料,只是基於樣式的改變,不是基於功能)

methods: {
    hanldeItemTap(e) {        // 獲取索引
        const {index} = e.currentTarget.dataset;        // let {tabs} = this.data;
        // tabs.forEach((v,i) => i===index?v.isActive=true:v.isActive=false);
        // 修改data中的資料
        // this.setData({
        //    tabs
        // })
        
        // 觸發父元件中的自定義事件同時傳遞給父元件
        this.triggerEvent("itemChange", {
            index
        })
    }
}複製程式碼

父元件中的自定義元件中新增自定義事件:

<Tabs binditemChange="handleItemChange">
    <block wx:if="{{tabs[0].isActive}}">1</block>
    <block wx:if="{{tabs[1].isActive}}">2</block>
    <block wx:else>3</block></Tabs>複製程式碼

父元件的js中:

data: {    tabs: [
        {            id: 1,            name: "首頁",            isActive: true
        },
        {            id: 2,            name: "待發貨",            isActive: false
        },
        {            id: 3,            name: "待付款",            isActive: false
        }
    ]
}// 自定義事件   接收子元件傳遞的資料的handleItemChange(e) {    // 接收傳遞過來的引數
    const {index} = e.detail;    // 拿到原陣列
    let {tabs} = this.data;
    tabs.forEach((v,i) => i===index?v.isActive=true:v.isActive=false);    // 修改data中的資料
    this.setData({
        tabs
    })
}複製程式碼

其他屬性

定義段型別
描述
propertiesObject Map
元件的對外屬性,是屬性名,是屬性設定的對映表
dataObject
常用於父元件向子元件傳值,子元件接收父元件的值
observersObject
監聽properties和data的資料變化
methodsObject
元件的方法
createdFunction
元件的生命週期函數(元件範例剛剛被被建立時執行)此時不能呼叫setData
attachedFunction
元件範例進入頁面節點樹時執行
readyFunction
元件佈局完成時執行
movedFunction
移動執行
detachedFunction
移除執行




專案

  1. 首頁
  2. 商品列表
  3. 購物車
  4. 授權頁面
  5. 商品搜尋
  6. 商品收藏
  7. 商品分類
  8. 商品詳情
  9. 結算
  10. 訂單列表
  11. 個人中心
  12. 意見反饋

小程式的第三方框架

  1. 騰訊 wepy 類似於 vue
  2. 美團 mpvue 類似於 vue
  3. 京東 taro 類似於 react
  4. 滴滴 chameleon
  5. uni-app 類似於 vue
  6. 原生框架 MINA

使用阿里字型圖示庫

  1. 在阿里圖示官網,將要使用的圖示,加入購物車

  2. 將圖示,加入專案

  3. 小程式 pyg ---》 Font class(通過類的方式來使用圖示) ---》 檢視線上連結

  4. 在專案的styles資料夾中,建立iconfont.wxss檔案

  5. 開啟連結,將連結中的內容複製到iconfont.wxss檔案中

  6. 使用字型圖示庫中的字型

    1. 在全域性wxss檔案中,引入wxss檔案

      @import "./styles/iconfont.wxss"複製程式碼
    2. 使用

      <text class="iconfont icon-shoucang"></text>複製程式碼

tabBar

在app.json中設定

tbaBar: {    "color": "",    //未選中的字型的顏色
    "selectedColor": "",    //選中後的字型的顏色
    "backgroundColor": "",  // 背景色
    "position": "", //定位
    "borderStyle": "",   //邊框樣式 
    "list": [
        {            "pagePath": "",   // 頁面的路徑
            "text": "",   // 標題的名稱
            "iconPath": "",   // 未選中的圖示路徑
            "selectedIconPath": ""   // 選中後的圖示的路徑
        }
    ]
}複製程式碼

頁面樣式的初始化

注意:在小程式中是不支援 萬用字元(*)的

app.wxss檔案中

page,view,text,swiper,swiper-item,image,navigator {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}


/*
    主題顏色
    1. less 中是存在  變數  的
    2. 原生的css和wxss 也是支援 css的
*/
page {
    --themeColor: #eb4500;
    // 設計稿大小為 375px 時,1px = 2rpx,14px = 28rpx
    font-size: 28rpx;
}複製程式碼

使用主題顏色:

view {
    color: var(--themeColor);
}複製程式碼

頭部

設定主題色:

"window": {    "backgroundTextStyle": "light",   // 字型顏色
    "navigatorBarBackgroundColor": "#2b4500",  // 背景色
    "navigatorBarText": "唯品會",  // 字型提示
    "navigatorBarTextStyle": "white",  // 字型樣式    }複製程式碼

使用介面資料

Page({    data: {        swiperList: []
    },    // 頁面載入事件
    onLoad: function() {        /*
            1. 傳送非同步請求 獲取使用的資料
        */
        wx.request({            url: '',  // 介面地址
            success: (result) => {                // 請求成功 給swiperList陣列賦值
                this.setData({                    swiperList: result.data.message
                })
            }
            
        });        /*
            wx.request非同步請求太多了就會產生   回撥地獄   的問題
            
            解決方法:  es6中的promise
        */
    }
})複製程式碼

請求報錯(兩種解決方法):

  1. 在小程式 詳情 介面 勾選上 不校驗合法域名,web-view(業務域名),TLS版本以及HTTPS證書
  2. 設定請求介面 見 8.7.將小程式請求的域名新增到後臺

解決回撥地獄的問題(es6的promise)

在專案的request資料夾中建立index.js檔案

通過封裝方法,然後呼叫函數傳遞引數的方式來使用

// 同時傳送非同步程式碼的次數let ajaxTime=0;export const request=(params) => {
    ajaxTime++;    // 資料載入效果
    wx.showLoding({       title: "載入中",        mask: true
    });    return new Promise((resolve, reject) => {
        wx.request({            // 解構傳遞的引數
            ...params,            success: (result) => {
                resolve(result);
            },            faile: (err) => {
                reject(err);
            },            // 不管是成功還是失敗都會呼叫這個函數
            complete: () => {
                ajaxTime--;                if(ajaxTime === 0) {                   // 關閉正在等待的圖示
                    wx.hideLoading();
                }                
            }
        });
    });
}複製程式碼

使用封裝好的請求方法:

//  引入封裝檔案 (注意: 一定要把路徑補全)import { request } from '../../request/index.js';  // 這裡引入的是封裝的request函數Page({    data: {        swiperList: []
    },    // 頁面載入事件
    onLoad: function() {        /*
            1. 傳送非同步請求 獲取使用的資料
        */
        /*
            wx.request({
                url: '',  // 介面地址
                success: (result) => {
                    // 請求成功 給swiperList陣列賦值
                    this.setData({
                        swiperList: result.data.message
                    })
                }

            });
        */
        /*
            wx.request非同步請求太多了就會產生   回撥地獄   的問題
            
            解決方法:  es6中的promise
        */
        
        // 呼叫方法
        this.getSwiperList();
        
    },    // 呼叫封裝好的方法
    getSwiperList() {        //  這裡填充的資料會替換掉request方法中的...params,
        request({ url: 'htltps://api/zbtbs/home/swiperList'}); 
        //  資料獲取成功
        .then (result => {            this.setData({                swiperList: result.data.message
            })
        });
    }
})複製程式碼

將小程式請求的域名新增到後臺

  1. 進入 微信公眾平臺
  2. 開發
  3. 開發設定
  4. 伺服器域名
  5. 新增request合法域名

獲取本地儲存的資料

web中的本地儲存 和 小程式中的本地儲存的區別:

  1. 寫程式碼的方式不一樣
    1. web中:
      1. 儲存方式:localStorage.setItem("key", "value");
      2. 獲取方式: localStorage.getItem("key");
    2. 小程式中:
      1. 儲存方式:wx.setStorageSync("key", "value");
      2. 獲取方式:wx.getStorageSync("key", "value");
  2. 存的時候 有沒有做型別轉換
    1. web:不管存的資料是什麼型別的資料,最後都會通過toString()方法轉換為字串型別的資料
    2. 小程式:不存在資料的型別轉換
// 介面返回的資料Cates: [],onLoad: function(options) {    // 獲取本地儲存中有沒有舊資料
    const Cates = wx.getStorageSync("cate");    // 判斷本地是否存在
    if(!Case) {        // 不存在  傳送請求資料
        this.setCates();
    }else {        // 有舊的資料
        // 定義資料過期的時間
        if(Date.now() - Cates.time > 1000 * 10) {           // 重新傳送請求
            this.getCates();
        } else {            this.Cates = Cates.data;            // 渲染資料
        }
    }
}// 獲取請求的資料getCates() {    // 把介面的資料儲存到本地儲存中
    wx.setStorageSync("cates", {time:Date.now(),data: this.Cates});
}複製程式碼

定義公共的url

在request.js檔案中,封裝請求方法

export const request=(params) => {    // 定義公共的url
    const baseUrl = "https://api.zbsb.cn/api/public"
    return new Promise((resolve, reject) => {
        wx.request({            // 解構傳遞的引數
            ...params,            url: baseUrl + params.url;
            success: (result) => {
                resolve(result);
            },            faile: (err) => {
                reject(err);
            }
        });
    });
}複製程式碼

小程式支援es7的async語法

  1. 在微信開發者工具中勾選es6轉es5語法

  2. 在github裡面下載regenerator庫中的runtime.js

  3. 在小程式目錄檔案下新建資料夾/lib/runtime/runtime.js,將程式碼拷貝進去

  4. 在每一個需要使用async語法的頁面js檔案中,引入檔案

    import regeneratorRuntime from '../lib/runtime/runtime';複製程式碼

    使用asyn語法:

    async getCates() {    // 1 使用es7的async await來傳送請求
        const res=await request({url:"/categories"});
    }複製程式碼

小程式url傳參

// 傳遞引數<navigator wx:for="Cates" wx:for-item="item" wx:for-index="index" wx:key="id" url="/pages/goods/index?cid={{item.cid}}"></navigator>// 拿取引數
onLoad:function(options) {
    consol.log(options);  // 列印輸出options的值
}複製程式碼

封裝tab切換元件

封裝的Tab元件中:

properties: {    tabs: Array,    value: []
}

<style>
    .tabs-title {        display: flex;
        padding: 15rpx 0;
    }
    .title-item {        display: flex;
        justify-content: center;
        align-item: center;
        flex: 1;
    }
    .active {        color: red;
        border-bottom: 1rpx solid red;
    }
</style><view class="tabs">
    <view class="tabs-title">
        <view wx:for="{{ tabs }}" wx:key="id" 
        class="title-item {{item.isActive?'active':''}}"
        bindtap="handleItemTap"  data-index="{{ index }}"
        >   
            {{ item.value }}         </view>
    </view>
    // 切換內容    <view class="tabs-content">
        <slot></slot>
    </view></view>methods: {    // 點選事件
    handleItemTap(e) {        // 獲取點選的索引
        const {index} = e.currentTarget.dataset;        // 觸發父元件中的事件
        this.triggerEvent("tabsItemChange", {index});
    }
}複製程式碼

使用封裝的Tab元件:

//bindtabsItemChange 監聽自定義事件<Tab tabs="{{ tabs }}" bindtabsItemChange="handelTabsItemChange">
    <block wx:if="{{tabs[0].isActive}}">1</block>
    <block wx:if="{{tabs[1].isActive}}">2</block>
    <block wx:if="{{tabs[2].isActive}}">3</block></Tab>// 標題的點選事件
bindtabsItemChange(e) {
  // 獲取被點選的標題的索引
  const {index} = e.detail;
  // 修改原陣列
  let {tabs} = this.data;
  tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
  // 賦值到data中
  this.setData({
    tabs
  });
}複製程式碼

卷軸觸底事件(頁面上滑事件)

卷軸觸底,載入下一頁資料

總頁數 = Math.ceil(總條數 / 每頁顯示的資料數)

// 獲取商品資料列表async getGoodsList() {    const res=await request({url:"/goods/search",data:this.QueryParams});    // 獲取總條數
    const total = res.total;    // 計算總頁數
    this.totalPage = Math.ceil(total / this.QueryParams.pagesize);    // 拼接陣列
    this.setData({        goodsList: [...this.data.goodsList,...res.goods]
    });    // 關閉下拉重新整理的視窗
    wx-stopDownRefresh();
}// 卷軸觸底事件onReachBottom() {    // 判斷還有沒有下一頁資料
    if(this.QueryParams.pagenum >= this.totalPage) {        // 當前頁碼 > 總頁數    沒有下一頁
        
    }    else {        // 還有下一頁  當前頁碼++ 重新傳送請求  資料請求回來後要對data中的陣列進行拼接
        this.QueryParams.pagenum++;        this.getGoodsList();
    }
}複製程式碼

下拉重新整理頁面

  1. 觸發下拉重新整理事件(需要在頁面的json檔案中開啟一個設定項)【enablePullDownRefresh: true,backgroundTextStyle: dark】
  2. 重置 資料 陣列
  3. 重置頁碼 設定為1
  4. 重新傳送請求
  5. 資料請求成功,手動關閉等待效果
onPullDownRefresh() {    // 重置  資料  陣列
    this.setData({        goodsList: []
    });    // 重置頁碼   設定為1
     this.QueryParams.pagenum=1;    // 重新傳送請求
    this.getGoodsList();
}複製程式碼

wx.showModel改變this的指向問題

wx.showModel({    title: '提示',    content: '您是否要刪除?',    success :(res) => {
        ...
    }
})複製程式碼

js中的刪除

cart.splice(index, 1);  // 刪除索引為index的元素cart.filter(v => v.checked);  // 挑選出cart陣列中checked為true的值複製程式碼

彈窗的封裝

在asyncWX.js檔案中

export const showModel=({content}) => {    return new Promise((resolve,reject) => {
        wx.showModel({            title: '提示',            content: content,            success :(res) > {
                resolve(res);
            },            fail :(err) => {
                reject(err);
            }
        })
    })
}複製程式碼

使用

import {showModel} from '../../utils/asyncWx.js';async showTips() {    const res=await showModel({content: '您是否要刪除?'})    if(res.confirm) {
       cart.splice(index, 1);        this.setData(cart);
    }
}複製程式碼

獲取快取中的資料

wx.getStorageSync("address");複製程式碼

微信支付

  1. 企業賬號
  2. 在企業賬號的小程式後臺中 必須 給 開發者新增上白名單
    1. 一個AppID可以繫結多個開發者
    2. 繫結之後的開發者就擁有了開發者的許可權了
  3. 支付按鈕
    1. 先判斷快取中有沒有token
    2. 沒有 跳轉到授權頁面 獲取使用者的 token 值
    3. 有 執行支付操作

流程:建立訂單,準備預支付,發起微信支付,查詢訂單

一,獲取token

handleOrderPay() {   try {        // 1. 判斷快取中有沒有token值
        const token = wx.getStorageSync("token");        // 2. 判斷
        if(!token) {            // 跳轉到  授權 頁面
            wx.navigateTo({                url: "/page/auth/index"
            })            return;
        }        // 3. 建立訂單
        // 準備建立訂單需要的引數
        const header = {Authorization:token};        // 準備請求體引數
        const order_price = this.data.totalPrice;   // 訂單總價格
        const consignee = this.data.address.all;  // 詳細地址
        let goods = [];        const cart = this.data.cart;
        goods.forEach(v => goods.push({            goods_Id: v.goods_Id, // 商品的id
            goods_number: v.goods_number, //商品數量
            goods_price: v.goods_price  // 商品的單價
        }))        const orderParams = {order_price,consignee,goods}        // 4. 準備傳送請求  建立訂單  獲取訂單編號
        const {order_number}=await request({url:                     "/order/create"},method:"POST",data:orderParams,head:head});        // 5. 發起 預支付介面
        const {pay}=await request({url:"/order/req_unifiedorder",method:"POST",head,data:{order_number}});        // 6. 發起微信支付
        await requestPayment(pay);        // 7. 查詢後臺  訂單狀態是否成功
        const res=await request(url:"/orders/chkOrder",method:"POST",head,data:{order_number}});        // 提示支付成功
        await showToast({title:"支付成功"});        // 手動刪除 快取中支付成功購物車的資料
        let newCart = wx.getStorageSync("cart");        // 過濾出沒有被選中的資料
        newCart = newCart.filter(v => !v.checked);
        wx.setStorageSync("cart",newCart);        // 8.支付成功  跳轉到訂單頁面
        wx.navigateTo({            url: '/page/order/index'
        })
   } catch(err) {       await showToast({title:"支付失敗"});
   }
    
}複製程式碼

page/autn/index頁面中:

<button open-type="getUserInfo" bindgetUserInfo="handleGetUserInfo">
    獲取授權</button>複製程式碼
// 獲取使用者資訊// encryptedData  // rawData// iv// signatureasync handleGetUserInfo(e) {    try {        // 獲取使用者資訊
        const { encryptedData,rawData,iv,signature } = e.detail;        // 獲取小程式登入之後的token值  在asyncWX.js中封裝token請求方法
        // wx.login({
        //     timeout: 1000,
        //    success: (result) => {
        //      cost { code } = result;   
        //    }
        // })
        const {code} = await login();        const loginParams = { encryptedData, rawData, iv, signature, code }        // 傳送請求  獲取使用者的token
        const {token}=await request(url: '/user/wxlogin',data: loginParams,methods:         "post");        // 將獲取到的token儲存到快取中,同時跳轉回上一個介面
        wx.getStroageSync("token", token);
        wx.navigateBack({            data: 1 // 返回上一層
        })    
    } catch(err) {        console.log(err);
    }
}複製程式碼

asyncWX.js檔案中封裝支付方法:

export const requestPayment=(pay) => {    return new Promise((resolve,reject){
        wx.request({
           ...pay,           success: (result) => {
                resolve(result);
           },           fail: (err) => {
               reject(err);
           }
        })                   
    })
}複製程式碼

二,準備預支付(獲取引數 pay)

三,發起微信支付(提交pay引數)

四,查詢訂單

五,刪除快取中已經被選中購買的商品

六,刪除後的購物車資料 填充會快取

七,跳轉頁面

圖片上傳(wx.uploadFile)

圖片上傳的時候,儲存上傳的圖片的時候,要先拼接上之前的圖片。

chooseImage:[],

this.setData({

chooseImage: [上傳之前的圖片組, 上傳的圖片組]

chooseImage: [...this.data.chooseImage, ...chooseImage]

})

上傳檔案的api不支援多個檔案同時上傳

解決方法:遍歷陣列 挨個上傳

wx.uploadFile({    url: '', // 圖片要上傳到哪裡
    filePath: '', // 被上傳檔案的路徑
    name: '',  // 上傳的檔案的名稱  後臺通過定義的上傳的名稱來獲取名稱
    formData: {}, // 順帶的文字資訊})複製程式碼

專案發布

注意:釋出之前記得關閉詳情介面的 不校驗合法域名

上傳的每個檔案大小不超過2M,總大小不超過10M。

上傳:

  1. 版本號
    1. 第一個數位(大版本的更新)
    2. 第二個數位(重要功能更新)
    3. 第三個數位(最小功能,小bug,小修補程式)
  2. less檔案是不會被打包上傳的
  3. 上傳成功後的小程式還是一個體驗版本的小程式,如果需要將體驗版本的小程式變成線上版本的小程式,就在 微信公眾平臺將提交的體驗本的小程式,提交稽核(稽核的時間大概是一個小時)。

小程式外掛

  1. 小程式開發助手[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-7znr3gju-1594264046886)(https://img.php.cn/upload/article/000/000/052/62154dd59d731a99e80263d5b4735b83-0.jpg Support/typora-user-images/image-20200707145006263.png)]

  2. 安裝easy less外掛在這裡插入圖片描述在vscode中設定(ctrl + shift + p 然後輸入 setting,然後新增上如下設定):

    "less.compile": {    "outExit": ".wxss"}複製程式碼

相關免費學習推薦:

以上就是放心,手把手教你寫微信小程式的詳細內容,更多請關注TW511.COM其它相關文章!