前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小程序入门,看这一篇就够了!

小程序入门,看这一篇就够了!

作者头像
腾讯NEXT学位
发布2019-11-18 11:10:16
7740
发布2019-11-18 11:10:16
举报
文章被收录于专栏:腾讯NEXT学位腾讯NEXT学位

文章为实战中踩坑经历,以及解决方案。同时是自己的一个项目回顾,在这里分享给大家,希望能帮助到大家。文章内代码需要左右滑动噢~

登录授权

授权(基本信息,手机号码 )必须使用小程序原生的的button组件,然后指定open-type 后通过回调才能拿到用户信息。代码入下:

代码语言:javascript
复制
index.wxml<view class="authorization" wx:if="{{!getUserInfo}}">       <view class="clue">你还未登录,请先授权登录</view>            <button open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">                授权登录            </button>        </view>        <view class="authorization" wx:if="{{getUserInfo && !getPhone}}">            <view class="clue">你还未绑定手机号,请先去绑定</view>            <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">                立即绑定            </button></view>index.jspage({    // ...     data: {        hasUserInfo: false,        canIUse: wx.canIUse('button.open-type.getUserInfo'),        userInfo: {},        getUserInfo: false,        getPhone: false,        hasAuth: false    },    onLoad: async function () {        var that = this;        // 查看是否授权        wx.getSetting({            success: function (res) {                if (res.authSetting['scope.userInfo']) {                    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: '警告',                content: '拒绝授权,您将无法使用小程序',                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: '警告',                content: '拒绝授权,您将无法使用小程序',                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去方便的使用:

代码语言:javascript
复制
onLoad: async function (options) {        const editListParams = await wx.getStorageSync('editListParams')        this.findReportDetails(editListParams)}复制代码

webView

webview不是在某个页面使用的,当时我以为是类似iframe这种东西嵌入到页面。正确的使用态度是新建一个page页面,然后跳转到这个page去使用。例如跳转到小程序关联的公众号文章:

代码语言:javascript
复制
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,虽然能拿来就用,如果不封装就会造成代码冗余。大家可自行参考如下封装

代码语言:javascript
复制
ajax.js
import { baseURL } from '../config/interfaceURL' // baseUrl
class AJAX {    AJAX ({ url, methods = 'GET', 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: {                'content-type': 'application/json'            },            success: res => {                const code = res.statusCode.toString()                if (code.startsWith('2')) {                    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: 'error',            duration: 2000        })    }    static serializeLink (obj) { // 序列化get请求        let temp = '?'        for (let index in obj) {            if(obj.hasOwnProperty(index)){                temp += (index + '=' + obj[index] + '&')            }        }        return temp.substr(0, temp.length - 1)    }}export default AJAX
// model层调用UserModel.jsimport AJAX from '../utils/AJAX'
export class UserModel extends AJAX {    // 小程序授权登陆    login (params) {        return this.AJAX({            url: `/service/api/users/applet/login`,            data: params,            methods: 'POST'        })    }}// control调用index.jsasync 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语法糖。在处理表单的双向绑定会显得比较蛋疼。所以还是有必要说下小程序里面的双向绑定是怎么样的。

代码语言:javascript
复制
file:index.js
Page({    data: {       list: []    },    onLoad: function (options) {      // do ...    },    onInput (e) {        let value = e.detail.value        let temp = e.target.dataset.name.split(',')        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域名才能生效,方法如下:

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

保存图片也是需要授权的,看代码就完事了。

其他

textarea 在ios上表现会有padding值,这个就坑了。我采用要不全是textarea或者全是input 这种去实现表单的填写,其他样式问题也蛮多的,有点ie的味道,多用flex float去解决一些差异吧~

文章每个点都是开发小程序的时候遇到的问题,本人能力有限,欢迎大家提出自己的问题。小程序坑还是蛮多的,而且写博客也蛮难得,码字不易,觉得有用的话点个在看吧!

原文作者:Rolan

原文地址:http://www.wxapp-union.com/article-5650-1.html

  -好课来袭-  

「人人都会微信小程序实战进阶」

腾讯大牛手把手教学,0基础快速上手小程序

更多课程优惠信息请添加助教微信

(微信:TencentNext)

附赠福利:

0.02元掌握云开发技巧、

让你的小程序开发又快又好!

【NEXT公开课】

小程序云开发技巧 

点击阅读原文,马上报名

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯NEXT学院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档