wepy+vant 微信小程序开发总结

前言

本次小程序开发选择使用 wepy作为小程序第三方框架,在UI组件库方面选择的是有赞的移动端组件库Vant去快速搭建小程序应用。这次小程序功能需求并不是特别复杂,目前亲测功能基本满足。这段时间刚好工作空闲期,决定将这次开发的坑以及重要点记录下来,以备今后查阅。

全局安装wePy模块包

npm install wepy-cli -g

代码编辑用的一直还是VsCode,在VsCode编辑器里开发,然后通过开启wepy实时编译,用微信原生开发者工具实时预览与调试!

wepy build --watch

微信原生开发者工具使用注意事项

  1. 项目设置中,关闭ES6转ES5,上传代码时样式自动补全,开启不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书 。 注意:官网说,应当关闭上传代码时自动压缩混淆,否则会导致部分功能不能正常使用,但我因为在真机调试或者预览的时候,编译打包失败超出大小限制还是勾上了,以保证手机可以正常预览调试。
  2. 使用微信原生开发者工具实时预览时,只需导入wepy build 后生成的build目录即可!

wepy 基本常见用法总结

  1. 事件绑定

    原生的bindtap="click" 变成 @tap="click"catchtap="click"变成@tap.stop="click"

  2. 事件传参
    原来通过自定义data-param变量 :bindtap="click" data-index={{index}}传参优化成:@tap="click('{{index}}')"吃(注:传递变量需要加’ ’ 包裹)

    传递多个变量:@tap="checkedChange('{{item.id}}', '{{index}}')"

  3. 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>
    
  4. 数据更新

    原生使用this.setData({title: 'this is title'});的形式更新数据,wepy优化为:this.title = 'this is title'

    注意:在异步更新数据,接口返回数据前端对数据做复杂forEach操作,或者比如删除操作成功很久了,视图才减少掉等等…各种数据更新,页面没有更新的情况,都可以使用this.$apply()方法,触发脏数据检查,使页面强制更新!

  5. 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标签才行。

  6. 动态样式

    // 写法一: 
    <ul class="search-history {{isShowMore ? 'search-history-more' : ''}} {{...}}">ul>
    // 写法二:
    <view class="m-select-group-item" :class="{'m-select-group-item--active': activeIdx === index}">view>
    
  7. 数据循环 , 条件判断

    小程序这边数据循环,我因为写法的大意,踩了一个坑,这边特别记录一下:

    // 特别设置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 即可
    
  8. 组件封装使用

    组件引用:父组件script中,先import引用子组件,然后在components对象中给组件声明唯一的组件ID,接着在template中,用声明的组件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: 是一个页面或组件对另一个组件中的方法的直接调用,通过传入组件路径找到相应的组件,然后再调用其方法。

  9. 请求封装

    wepy框架wepy.request() 默认对所有的小程序提供的API进行了promise处理。支持promise,但是需要手动开启promise的支持。在封装通用请求接口时,可以一起加上loading,以及请求失败的提示。

    wxRequest.js页面:

import wepy from 'wepy';
const request = (url, config = {}) => {
    return new Promise((resolve, reject) => {
      wx.showLoading({
        title: '加载中',
      })
      wepy.request({
        url: url,
        data: Object.assign({}, config.data, wepy.$instance.globalData.tokenId ? {tokenId: wepy.$instance.globalData.tokenId} : {}) || {},
        method: config.method || 'GET',
        dataType: config.dataType || 'json',
        header: config.header || {
          'Content-Type': 'application/json',
          'X-CSRF-TOKEN': wepy.$instance.globalData.CSRF_TOKEN,
     }
      }).then(res => {
        resolve(res)
        wx.hideLoading()
      }).catch(err => {
        console.error(err)
        reject(err)
        wx.hideLoading()
        wx.showToast({
          title: '网络请求失败,请检查网络后重试 !',
          icon: 'none',
          duration: 2000
        })
      })
    })
  }
  
  export default {
    request
  }

小程序授权

暂时项目进度,还没有特别完善的登陆流程。后续,看情况再更新。。。暂时记录一下,关于授权,登陆的注意点:

如果想通过wx.getUserInfo()获取用户信息,需要先走授权。可以使用 wx.getSetting 获取用户当前的授权状态。

向用户发起授权窗口请使用:

你可能感兴趣的:(小程序系列)