wepy+vant 微信小程序开发总结
前言
本次小程序开发选择使用 wepy作为小程序第三方框架,在UI组件库方面选择的是有赞的移动端组件库Vant去快速搭建小程序应用。这次小程序功能需求并不是特别复杂,目前亲测功能基本满足。这段时间刚好工作空闲期,决定将这次开发的坑以及重要点记录下来,以备今后查阅。(另外,与小程序同期还有用vue做的H5 app开发,下面会在部分情况比较二者的区别!)
wepy准备工作
全局安装wePy模块包
npm install wepy-cli -g
代码编辑用的一直还是VsCode,在VsCode编辑器里开发,然后通过开启wepy实时编译,用微信原生开发者工具实时预览与调试!
wepy build --watch
微信原生开发者工具使用注意事项
- 在项目设置中,关闭
ES6转ES5
,上传代码时样式自动补全
,开启不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书
。 注意:官网说,应当关闭上传代码时自动压缩混淆
,否则会导致部分功能不能正常使用,但我因为在真机调试或者预览的时候,编译打包失败超出大小限制还是勾上了,以保证手机可以正常预览调试。 - 使用微信原生开发者工具实时预览时,只需导入wepy build 后生成的build目录即可!
wepy 基本常见用法总结
-
事件绑定
原生的
bindtap="click"
变成@tap="click"
,catchtap="click"
变成@tap.stop="click"
-
事件传参
原来通过自定义data-param
变量 :bindtap="click" data-index={{index}}
传参优化成:@tap="click('{{index}}')"
吃(注:传递变量需要加' ' 包裹)传递多个变量:
@tap="checkedChange('{{item.id}}', '{{index}}')"
-
wepy使用单文件模式,将原生的page页面的4个文件
page.js
,page.json
,page.wxml
,page.wxss
汇总成一个page.wpy
;app页面一样。以page页面为例,简述wepy优化后的页面代码结构:
<template> <view> ... 我是html部分 <view> </template> <script> import wepy from 'wepy'; import HomoloStep from '../../components/HomoloStep'; export default class PayResult extends wepy.page { config = { navigationBarBackgroundColor: '#447BC9', // 此处设置相当于page.json内容,定义页头 navigationBarTitleText: '支付结果', navigationBarTextStyle: 'white', usingComponents: { // 引入的第三方UI组件库vant 'van-button': '../../components/van/button/index' } }; // 此处注册自己封装的公共组件 components = { 'HomoloStep': HomoloStep } data = { show: false, ... }; // methods 里面只负责写页面交互相关的方法,比如:@tap... methods = { ... }; // 无交互的事件,自己写的一些初始方法挪出methos,保持于methods同级! getNotaryOffices () { } // 初始化生命周期,加载页面数据 onLoad () { this.getNotaryOffices() } } </script> <style lang='less' scoped> ... </style>
-
数据更新
原生使用
this.setData({title: 'this is title'});
的形式更新数据,wepy优化为:this.title = 'this is title'
。注意:在异步更新数据,接口返回数据前端对数据做复杂forEach操作,或者比如删除操作成功很久了,视图才减少掉等等...各种数据更新,页面没有更新的情况,都可以使用
this.$apply()
方法,触发脏数据检查,使页面强制更新! -
img属性绑定区别
这里没有为什么,就想特别记录一下
image
标签的src
绑定区别:用vue 写的h5 APP时是这样的:
<img :src="environment.restServiceUrl +'tk.File/' +unUploadItem.fileId +'/view'">
并且:vue这边,要想在data数据里面直接写入img的src本地图片路径,需要使用
requie('../../bg.png')
defaultOfficeBg: require("@/assets/images/office-default.png")
微信小程序是这样的...
<image src="{{item.img}}" />
注: 小程序无法在样式style中,直接使用
background-image
去加载本地图片,只能用网络url或者base64的形式 ;要想使用本地图片要用image
标签才行。 -
动态样式
// 写法一: <ul class="search-history {{isShowMore ? 'search-history-more' : ''}} {{...}}"></ul> // 写法二: <view class="m-select-group-item" :class="{'m-select-group-item--active': activeIdx === index}"></view>
-
数据循环 , 条件判断
小程序这边数据循环,我因为写法的大意,踩了一个坑,这边特别记录一下:
// 特别设置key,item 属性的时候,注意没有{{}},并且 wx:key就可以啦,没有for-前缀 <view wx:for="{{offices}}" wx:key="item.id" wx:for-item="item"> {{item.name}} ... </view>
// 小程序条件判断 <view wx:if="{{ident.result === '同一人'}}">...</view> <view wx:elif="{{ident.result === '非同一人'}}">...</view> <view wx:else>...</view> // vue 这边是直接 v-if... v-else 即可
-
组件封装使用
组件引用:父组件
script
中,先import
引用子组件,然后在components
对象中给组件声明唯一的组件ID,接着在template
中,用声明的组件ID所命名的自定义标签插入组件。<template> <!-- 以`<script>`脚本部分中所声明的组件ID为名命名自定义标签,从而在`<template>`模板部分中插入组件 --> <child></child> </template> <script> import wepy from 'wepy'; //引入组件文件 import Child from '../components/child'; export default class Index extends wepy.page { //为两个相同组件的不同实例分配不同的组件ID,从而避免数据同步变化的问题 components = { child: Child, anotherchild: Child }; } </script>
props 父子组件传值:与vue一样,包括
静态传值
与动态传值
。静态传值
:父组件给子组件传递常量数据 String类型(不需要加:
)<homolo-select-translate placeholder="请选择翻译语种"></homolo-select-translate>
动态传值
:父组件向子组件传递动态数据(需要加::
),可以通过使用.sync
修饰符达到父组件数据绑定至子组件,也可以通过设置twoWay:true
达到子组件数据绑定至父组件的效果。两者同时使用,可以实现双向绑定
。<homolo-select-translate :list.sync="translateLists" :id.sync="translateId"></homolo-select-translate>
export default class HomoloSelect extends wepy.component { props = { list: { // 父组件向子组件单向传值,有.sync修饰符的props属性值,当在父组件中改变时,会同时改变子组件对应的值 type: Array, default: [] }, id: { type: String, default: undefined, twoWay: true // 子组件props中的属性值改变时,会同时改变父组件对应的值 }, placeholder: String // 静态传值 } };
组件通信交互
$emit
:子组件向父组件通信交互 。(暂时只用过这种...)$broadcast
: 父组件向所有子组件通信。$invoke
: 是一个页面或组件对另一个组件中的方法的直接调用,通过传入组件路径找到相应的组件,然后再调用其方法。 -
请求封装
wepy框架
wepy.request()
默认对所有的小程序提供的API进行了promise处理。支持promise,但是需要手动开启promise的支持。wxRequest.js页面:
import wepy from 'wepy'; const request = (url, config = {}) => { return wepy.request({ url: url, data: Object.assign({}, config.data, wepy.$instance.globalData.tokenId ? {personId: wepy.$instance.globalData.tokenId} : {}) || {}, // 每次请求data中携带固定的参数 method: config.method || 'GET', dataType: config.dataType || 'json', header: config.header || { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': wepy.$instance.globalData.CSRF_TOKEN, // 自定义js文件获取globalData的全局变量 } }) } export default { request }
小程序授权,登陆流程
暂时项目进度,还没有特别完善的登陆流程。后续,看情况再更新。。。暂时记录一下,关于授权,登陆的注意点:
-
授权方面:
如果想通过
wx.getUserInfo()
获取用户信息,需要先走授权
。可以使用 wx.getSetting 获取用户当前的授权状态。向用户发起授权窗口请使用:
<button open-type="getUserInfo">
<button open-type="getUserInfo" bindgetuserinfo="onGotUserInfo">获取用户信息</button> <script> onGotUserInfo(e) { console.log(e.detail.userInfo) wx.getSetting({ success (res) { if (res.authSetting['scope.userInfo']) { wx.redirectTo({url: './login-register/login'}) } else { ... } } }) }, </script>
-
登陆流程