首頁  >  文章  >  微信小程式  >  小程式入門就看這篇

小程式入門就看這篇

hzc
hzc轉載
2020-06-16 10:42:092707瀏覽

說明

文章為實戰中踩坑經歷,以及解決方案。同時是自己的一個專案回顧,在這裡分享給大家,希望能幫助大家,如果覺得文章對你有用,請點個贊,謝謝!原諒我也是個標題黨:)

登入授權

授權(基本訊息,手機號碼)必須使用小程式原生的的button元件,然後指定open- type 後透過回呼才能拿到使用者資訊。程式碼入下:

index.wxml
<view wx:if="{{!getUserInfo}}">
       <view>你还未登录,请先授权登录</view>
            <button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
                授权登录
            </button>
        </view>
        <view wx:if="{{getUserInfo && !getPhone}}">
            <view>你还未绑定手机号,请先去绑定</view>
            <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
                立即绑定
            </button>
</view>
index.js
page({
    // ... 
    data: {
        hasUserInfo: false,
        canIUse: wx.canIUse(&#39;button.open-type.getUserInfo&#39;),
        userInfo: {},
        getUserInfo: false,
        getPhone: false,
        hasAuth: false
    },
    onLoad: async function () {
        var that = this;
        // 查看是否授权
        wx.getSetting({
            success: function (res) {
                if (res.authSetting[&#39;scope.userInfo&#39;]) {
                    wx.login({
                        success: loginRes => {
                            // 获取到用户的 code 之后:loginRes.code
                            wx.getUserInfo({
                                success: async function (res) {
                                    // 这里处理业务逻辑
                                }
                            })
                        }
                    })
                } else {
                    // 用户没有授权
                }
            }
        });
    },
    bindGetUserInfo: function (e) {
        // 需要什么信息都从e中拿到 以下部分业务逻辑
        if (e.detail.userInfo) {
            //用户按了允许授权按钮
            var that = this;
            // 获取到用户的信息
            wx.login({
                success: async res => {
                    const aUserModel = new UserModel();
                    const params = {
                        code: res.code,
                        encryptedData: e.detail.encryptedData,
                        iv: e.detail.iv
                    }
                    const { data } = await aUserModel.login({ ...params })
                    if(data.roles){
                        // do ...
                    }
                    if (data.mobile) {
                        // do ...
                    }
                }
            });
            //授权成功后,通过改变 isHide 的值,让实现页面显示出来,把授权页面隐藏起来
            that.setData({
                isHide: false
            });
        } else {
            //用户按了拒绝按钮
            wx.showModal({
                title: &#39;警告&#39;,
                content: &#39;拒绝授权,您将无法使用小程序&#39;,
                showCancel: false
            });
        }
    },
    getPhoneNumber: async function (e) {
        if (e.detail.encryptedData) {
            //用户按了允许授权按钮
            const aUserModel = new UserModel();
            const params = {
                userId: userInfo.id,
                encryptedData: e.detail.encryptedData,
                iv: e.detail.iv
            }
            // do ...
        } else {
            //用户按了拒绝按钮
            wx.showModal({
                title: &#39;警告&#39;,
                content: &#39;拒绝授权,您将无法使用小程序&#39;,
                showCancel: false
            })
        }
    },
    // ...
})

路由

路由跳轉的各個方法可以去官網學習,這裡提遇到的坑,navigateTo路由跳轉最多只能10層,所以使用的時候需要考慮是不是確定需要歷史記錄。為什麼要這麼說呢。 場景:一個清單頁面(如下圖),使用者的檔案是可以修改的,如果用navigateTo跳轉(/page/archivesEdit?id=1923XXXX),修改儲存用navigateTo(/page/archivesList),這樣來回編輯跳轉10次​​就不讓點擊跳轉了。

小程式入門就看這篇

解決:思考那我用2個redirectTo 行不行? redirectTo是關閉目前歷史記錄跳到下一頁。造成了我跳到修改頁面點擊微信自帶的返回是直接跳過列表頁面跳到首頁。這時候測試小姐姐就又要提bug單了。 。 。
完美姿勢: 就是用navigateTo和navigateBack。我再編輯儲存的時候返回用navigateBack返回。這樣小程式的路由棧就一會在2-3層之間。當然有時候在列表頁面會遇到要重新呼叫接口,這時候路由跳轉提供了幾個重要的鉤子函數onShow,onHide,我們可以在onShow的時候可以調用一下列表的接口。

這2個鉤子函數足夠我們簡單的跳轉,更複雜的場景下可以透過存Storage這種存取參數來返回到上一個頁面進行操作,感覺不是優雅,但是沒有好的辦法解決了。

Storage


場景:storage有2種方式獲取,當你直接wx.getStorageSync('xxx')取得一個id,去請求介面的可能是取得不到就已經發送請求了,導致出現bug。

因為wx.getStorageSync('xxx')是異步的我們可以利用async/await去方便的使用

onLoad: async function (options) {
        const editListParams = await wx.getStorageSync(&#39;editListParams&#39;)
        this.findReportDetails(editListParams)
}

webView


#webview不是在某個頁面使用的,當時我以為是類似iframe這種東西嵌入到頁面。正確的使用態度是新建一個page頁面,然後跳到這個page去使用。例如跳到小程式關聯的公眾號文章:

other.wxml
<navigator url="/pages/webView/webView"  hover-class="none">跳转到webView</navigator>
webView.wxml
<web-view src="https://mp.weixin.qq.com/s/xxxx"></web-view>

request


#微信自帶的網路下的request,雖然能拿來就用,如果不封裝就會造成程式碼冗餘。大家可自行參考以下封裝

ajax.js

import { baseURL } from &#39;../config/interfaceURL&#39; // baseUrl

class AJAX {
    AJAX ({ url, methods = &#39;GET&#39;, data = {} }) {
        return new Promise((resolve, reject) => {
            this.request(url, resolve, reject, methods, data)
        })
    }
    request (url, resolve, reject, methods, data) {
        wx.request({
            url: baseURL + url,
            method: methods,
            data: data,
            header: {
                &#39;content-type&#39;: &#39;application/json&#39;
            },
            success: res => {
                const code = res.statusCode.toString()
                if (code.startsWith(&#39;2&#39;)) {
                    resolve(res)
                } else {
                    reject()
                    const errorMessage = res.data.message
                    AJAX.showError(errorMessage)
                }
            },
            fail: err => {
                reject()
                AJAX.showError("网络异常,请稍后重试!")
            }
        })
    }
    static showError (errorMessage) {
        wx.showToast({
            title: errorMessage,
            icon: &#39;error&#39;,
            duration: 2000
        })
    }
    static serializeLink (obj) { // 序列化get请求
        let temp = &#39;?&#39;
        for (let index in obj) {
            if(obj.hasOwnProperty(index)){
                temp += (index + &#39;=&#39; + obj[index] + &#39;&&#39;)
            }
        }
        return temp.substr(0, temp.length - 1)
    }
}
export default AJAX

// model层调用
UserModel.js
import AJAX from &#39;../utils/AJAX&#39;

export class UserModel extends AJAX {
    // 小程序授权登陆
    login (params) {
        return this.AJAX({
            url: `/service/api/users/applet/login`,
            data: params,
            methods: &#39;POST&#39;
        })
    }
}
// control调用
index.js
async onLoad (options){
    const aUserModel = new UserModel()
    const params = {
        code: loginRes.code,
        encryptedData: res.encryptedData,
        iv: res.iv
    }
    const { data } = await aUserModel.login({ ...params })
    // 其他
}

npm生態以及第三方ui框架


直接透過初始化的微信小程式項目裡面沒有package.json檔案。所以在使用npm install xxx 是沒有卵用。所以我們要自己在資料夾根目錄下執行npm init 。這時候才能透過微信開發者工具建構npm,建置成功會產生一個目錄。推薦用有讚的vant小程式版,社群較活躍,使用起來不會有很多坑。

雙向綁定


對於習慣使用vue的開發者來說,少了這個v-model語法糖。在處理表單的雙向綁定會顯得比較頭痛。所以還是有必要說下小程式裡面的雙向綁定是怎麼樣的。

file:index.js

Page({
    data: {
       list: []
    },
    onLoad: function (options) {
      // do ...
    },
    onInput (e) {
        let value = e.detail.value
        let temp = e.target.dataset.name.split(&#39;,&#39;)
        let tempKey = temp[1]
        let tempIndex = temp[0]
        let tempSubIndex = temp[2]
        let targetKey = `list[${tempIndex}].children[${tempSubIndex}].${tempKey}`
        this.setData({
            [targetKey]: value
        })
    }
})

file:index.wxml
<block  wx:for="{{item.children}}"  wx:for-item="subItem"  wx:key="{{index}}">
    <view class="td" style="height: {{ 100 / item.children.length}}%;">
      <input placeholder-style="color:#ccccccc;"  type="text" placeholder="未填写" value="{{subItem.testResult}}" data-name="{{idx}},testResult,{{index}}"  bindinput="onInput"/>
    </view>
</block>

下載圖片和下載圖片授權


這裡場景是下載一個固定的靜態資源圖片,網頁圖片需先設定download網域才能生效,方法如下:

 savePhoto () {
        const _this = this;
        wx.getImageInfo({
            src: &#39;/static/images/home/Qr.png&#39;,
            success: function (res) {
                wx.saveImageToPhotosAlbum({
                    filePath: res.path,
                    success (result) {
                        _this.setData({ show: false });
                        wx.showToast({
                            title: &#39;保存成功&#39;,
                            icon: &#39;success&#39;,
                            duration: 2000
                        })
                    },
                    fail (err) {
                        if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
                            wx.openSetting({
                                success (settingdata) {
                                    if (settingdata.authSetting[&#39;scope.writePhotosAlbum&#39;]) {
                                        _this.savePhoto()
                                    } else {
                                        wx.showToast({
                                            title: &#39;获取权限失败,无法保存图片&#39;,
                                            icon: &#39;success&#39;,
                                            duration: 2000
                                        })
                                    }
                                }
                            })
                        }
                    }
                })
            }
        })
    }

儲存圖片也是需要授權的,看程式碼就完事了。

其他


textarea 在ios上表現會有padding值。我曹 這個就坑了。我採用要不全是textarea或全是input 這種去實現表單的填入。 其他樣式問題也蠻多的,有點ie的味道。 ! !多用flex float去解決一些差異吧~

結語


文章每個點都是開發小程式的時候遇到的問題,本人能力有限,歡迎大家在留言區提出問題交流學習,也可以追蹤好享家公眾號獲取更多優質文章。

推薦教學:《微信小程式

以上是小程式入門就看這篇的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除