在此立一个flag,每月15日之前发布上一个月的项目总结,以此督促自己坚持

本月上线两个项目:1,现有PC审批系统移动化;2,小程序。

一,PC审批移动化项目
  • 1, 问题描述:
  • 场景:修复微信6.7.4版本,部分ios系统12.1.1手机 ,在自定义模态框中 textarea input 在调起键盘输入完成之后,如果页面有点击确认按钮,会出现点击失效问题。
  • 原因:当软键盘隐藏的时候,遮罩层回到原位,但是body未回到原来位置,需要手动设置。
  • 解决方案:
!(/iphone|ipod|ipad/i.test(navigator.appVersion)) && document.addEventListener('blur', function (e) {
    // 滚动时 让body的底部与视图容器底部对齐
    // 页面(容器)可滚动时有效
    // console.log('123')
    // console.log(e.target.localName)
    document.body.scrollIntoView(false)
  }, true)
  • 2,问题描述:
  • 场景:手机页面有弹出模态框选择,操作完成之后需要刷新页面。在ios手机上可以使用 window.location.reload() 但是安卓手机上面无法使用
  • 解决方案:
// 刷新页面
   window.location.href = location.href + '&time=' + ((new Date()).getTime());
  // window.location.reload();  //此功能安卓手机不支持,采用上面替代方案
二,小程序项目(本期重点)

前期准备 (由于公司属于第一次开发小程序,小程序坑也比较多,如下会有点啰嗦)

  • 1,首先需要在微信公众平台 https://mp.weixin.qq.com/ 注册自己公司的 AppID(小程序ID) ,并在下载微信开发者工具(创建项目时需要用到公司的AppID)
  • 2,在微信公众平台成员管理中,添加自己为公司的开发者(添加成开发者之后你就可以自己登陆公司的公众平台了)
  • 3,完成上述工作基本上就可以开始搭建环境

技术栈选择

  • 1,项目搭建:经过多方对比和询问,本次项目采用mpvue框架 + less + axios组合
  • 2,一定要多看几次微信小程序api(排版不友善)+mpvue官方的问题解答
  • 3,小程序有限制一个包大小为2mb,所有分包大小为8mb,如果项目很大提前做好分包计划,分包计划也很简单

正式开始

  • 1,使用mpvue推荐的步骤搭建开发环境(当然,提前得安装node);
# 全局安装 vue-cli
$ npm install --global vue-cli

# 创建一个基于 mpvue-quickstart 模板的新项目
$ vue init mpvue/mpvue-quickstart my-project

# 安装依赖
$ cd my-project
$ npm install
# 启动构建
$ npm run dev
  • 2,把搭建好的文件目录通过微信开发者工具打开,就可以实现在vue开发,开发者工具中看结果的目的。
    通过脚手架搭建出来之后的项目结构;
  • 3,对wx.request请求进行axios封装(在src中的main.js中引入);
import Vue from 'vue'
import App from './App'
import axios from 'axios'
const globalData = {
  isIpx: false
}

Vue.config._mpTrace = true
Vue.config.productionTip = false
App.mpType = 'app'

// 测试地址 请求前面加的域名
axios.defaults.baseURL = 'https://xxx.cn'

// 封装wx.request 并添加到axios中, 最后注册到vue原型上供以后使用
axios.defaults.adapter = function (config) {
  return new Promise((resolve, reject) => {
  // 在请求中加入loading效果
    wx.showLoading({
      title: '加载中',
      mask: true
    })
    // 本质是通过微信请求的api 里面的config是axios的config
    wx.request({
      url: config.url,
      data: config.data,
      method: config.method === 'get' ? 'GET' : 'POST',
      success: res => {
        if (res.data.code === '0') {
          if (res.data.data === 'success' || !res.data.data) {
            res.data.data = {
              'success': 'success'
            }
          }
          resolve(res.data.data)
        } else {
        // 失败的一些逻辑
          wx.hideLoading()
          wx.showModal({
            title: '失败',
            content: res.data.msg,
            showCancel: false,
            success () {
              if (res.data.code !== '109') {
                wx.clearStorageSync()
              }
              wx.navigateTo({
                url: '/pages/login/main'
              })
            }
          })
        }
      },
      fail: err => {
        reject(err)
        wx.showModal({
          title: '失败',
          content: '连接服务器失败',
          showCancel: false
        })
      }
    })
  })
}

Vue.prototype.$axios = axios
Vue.prototype.$globalData = globalData
const app = new Vue(App)
app.$mount()
  • 4,app.json 是小程序整体配置文件,包括主包,分包,tabBar(2.7基础库目前可以使用网络图片),window等,这部分就需要多看文档中的–框架部分,有许多生命周期需要了解;
  • 5,小程序需要特别注意的api,获取用户信息的api将不会自动获取了,需要用户点击才可以获取(微信推荐在button中获取头像),所以本次项目中首页就是进入授权登录页面;
  • 6,在mpvue项目中需要把微信原有的bindgetuserinfo 改成@getuserinfo ;
  • 7,在生命周期中,所有请求请放在mounted(){} 或者 onShow(){}钩子中。如果放在created中,小程序第一次加载就会全部调用所有页面的created;
  • 8,可以对每一个页面自定义头部导航样式,如果在mpvue中需要单独在main.js同级中新建一个main.json来进行配置
//这是单独页面中的main.json
{
  "enablePullDownRefresh": true, //开启下拉刷新
  "navigationStyle":"custom" //自定义导航,需要设置成custom,,设置之后页面将不会有头部导航,页面会贯穿整个屏幕,只保留微信的胶囊那妞,此时我们只需要自己写元素和样式即可
}
//如下这段代码是我自己定义的导航 抽取出来成为一个子组件,系统的高度使用了全局变量,也可以在组件中通过微信api wx.getSystemInfo({})获取
<template>
  <div id="compNavbar">
    <!-- 占位栏 -->
    <view class="placeholder-bar" :style="{height: navBarHeight + 'px'}"></view>
    <!-- 导航栏主体 -->
    <view class="navbar" :style="{height: navBarHeight + 'px',backgroundColor:navBackgroundColor }">
      <!-- 状态栏 -->
      <view class="nav-statusbar" :style="{height: statusBarHeight + 'px'}"></view>
      <!-- 标题栏 -->
      <view class="nav-titlebar" :style="{height: titleBarHeight + 'px' }">
        <!-- 铃铛图片 -->
        <view class="bar-options" @click="goToMessage">
          <img class="img" src="/static/images/icon_bell.png">
          <view class="bell-title" v-show="bellTitle">{{bellTitle}}</view>
        </view>
        <!-- 标题 -->
        <view class="bar-title" :style="[{color:titleColor}]">{{title}}</view>
      </view>
    </view>
  </div>
</template>
<script>
export default {
  props: {
    // 导航栏背景色
    navBackgroundColor: {
      default: '#ffffff'
    },
    // 标题颜色
    titleColor: {
      default: '#333'
    },
    // 标题文字
    title: {
      required: false,
      default: '汇联行'
    },
    // 铃铛消息提示
    bellTitle: {
      default: ''
    }
  },
  data () {
    return {
      statusBarHeight: '', // 状态栏高度
      titleBarHeight: '', // 标题栏高度
      navBarHeight: '', // 导航栏总高度
      platform: '',
      model: '',
      brand: '',
      system: ''
    }
  },
  beforeMount () {
    const system = this.$globalData
    this.statusBarHeight = system.statusBarHeight
    this.platform = system.platform
    this.model = system.model
    this.brand = system.brand
    this.system = system.system

    let platformReg = /ios/i
    if (platformReg.test(system.platform)) {
      this.titleBarHeight = 44
    } else {
      this.titleBarHeight = 48
    }
    this.navBarHeight = this.statusBarHeight + this.titleBarHeight
  },
  methods: {
    goToMessage () {
      wx.navigateTo({
        url: '../myMessage/main'
      })
    }
  }
}
</script>
<style lang="less" scoped>
#compNavbar {
  width: 100%;

  .navbar {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    z-index: 1000;
    border-bottom: 2rpx solid #efeff1;
    .nav-titlebar {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      .bar-options {
        width: 50rpx;
        height: 50rpx;
        display: flex;
        box-sizing: border-box;
        align-items: center;
        justify-content: center;
        position: absolute;
        left: 20rpx;
        top: 50%;
        transform: translateY(-50%);
        .img {
          width: 37rpx;
          height: 40rpx;
        }
        .bell-title {
          color: #fff;
          background-color: #fd7322;
          font-size: 10px;
          padding: 5rpx;
          width: 30rpx;
          height: 30rpx;
          line-height: 30rpx;
          text-align: center;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          border-radius: 50%;
          position: absolute;
          top: -10rpx;
          right: -10rpx;
          z-index: 100;
        }
      }
      .bar-title {
        width: 45%;
        font-size: 36rpx;
        font-weight: 500;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        text-align: center;
      }
    }
  }
  .placeholder-bar {
    background-color: transparent;
    width: 100%;
  }
}
</style>
  • 9,input 输入框点,点击输入的时候placeholder会抖动,至今官方没有给解决方案,我也没有解决;
  • 10,如果要实现点击按钮有交互的效果,如果用button 他默认会再带hover-class,,如果用其它(目前支持 hover-class 属性的组件有三个:view、button、navigator可以加入hover-class=“button-hover”
// mpvue会把div编译成view 如果想要使按钮有点击的交互效果,就需要加上hover-class
<div class="cance btn " hover-class="button-hover"  @click="cance">返回</div>

// button-hover 默认为{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;}
// 如果需要修改,可以在app.vue入口中进行样式的修改,以便于所有页面都用自己的
  • 11,如果使用官方组件scroll-view 进行区域滚动或者滑动,如果里面有textarea 将出现bug,无法滚动,输入完成之后textarea层级会比scroll-view高,无法通过z-index调整;所以我的项目中就直接把textarea改成了input来进行输入功能;
  • 12,scroll-view 使用时必须给设置固定高度;
<scroll-view scroll-y 
 :style="{ height:windowHeight + 'px' }"
  @scroll="scroll" 
  :scroll-into-view="toView" 
  scroll-with-animation="true">
 
 </scroll-view>
 // 我的高度是通过计算属性监听设置上去的
 computed: {
    windowHeight () {
      return this.height
    }
  },
  methods: {
  getSystem () {
      let that = this
      
      this.isIpx = this.$globalData.isIpx
      wx.getSystemInfo({
        success: function (res) {
          // 计算主体部分高度
          // 此处有加判断是否是iPhone X 因为iPhone X底部会有一条线,所以需要把高度减少到安全区域,
          if (that.isIpx) {
          // 这是一个理论值(68px),是我自己试出来的
            that.height = res.windowHeight - 134
          } else {
            that.height = res.windowHeight - 120
          }
        }
      })
    },
   }
  • 13,scroll-view 会有一个滚动条,我觉得难看,就使用了下面的方法去掉
// 在样式中加入 取消滚动条 好像没有什么效果
::-webkit-scrollbar {
  width: 0;
  height: 0;
  color: transparent;
}
// 最终解决方案是
    <form class="collectInfoMain"  @submit="formSubmit" report-submit="true">
    	<scroll-view scroll-y :style="{ height:windowHeight + 'px' }" @scroll="scroll" :scroll-into-view="toView" scroll-with-animation="true">
    		 <div class="basic-info-wrap" id="baseInfo">内容</div>
    	</scroll-view>
   	</form>
// 如上三层结构样式如下:原理是通过父元素的overflow:hidden 把scroll的滚动条隐藏, scroll宽度比父元素款,没什么兼容问题
.collectInfoMain {
  display: block;
  width: 100%;
  overflow: hidden;
  
  scroll-view {
    box-sizing: border-box;
    width: 105%;
    
    .basic-info-wrap {
      width: 95%;
    }
  }
}
  • 14,手机formId (这个也是最老火的地方了)下面是官方解释

当用户在小程序内发生过提交表单行为且该表单声明为要发模板消息的,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下发条数独立,相互不影响)

  • 但是我们业务需求是需要给用户发送很多消息推送呀
  • 网络收集各种办法都被微信和谐了
  • 最后还是只能在每一个能点击的按钮地方嵌套一个form表单,,,但最后还是不够,,,头疼
// 登录中的输入用户名和密码当然是不能放过了,为了多收集formId,但是有效期也只有7天。微信做得非常nice
<form @submit="collectAccount" report-submit="true">
   <div class="loginItem">
     <div class="icon _phone">
       <img src="/static/images/phone.png" alt="手机">
     </div>
     <button form-type="submit" hover-class="none">
       <input type="text" placeholder="请输入账号" v-model="account">
     </button>
   </div>
 </form>
        
 <form @submit="collectPassword" report-submit="true">
   <div class="loginItem">
     <div class="icon _password">
       <img src="/static/images/password.png" alt="密码">
     </div>
     <button form-type="submit" hover-class="none">
       <input type="text" password=true placeholder="请输入密码" v-model="password">
     </button>
   </div>
 </form>
  • 15,以上就是4月的两个项目,小程序目前已经上线,但是还是有bug,页面加载图片的时候会很慢无论是多大的(官方也没有解释,传说是所有的图片地址都会经过腾讯服务器过滤一遍,怕有不健康图片)
  • 16,小程序踩坑之路还很遥远,坚持每月更新一篇,提升自己的战斗实力。
(补充)小程序发布上线
  • 发布上线特别简单,只要在微信开发者工具上,点击—上传
  • 上传之后就可以在微信公众平台中–版本管理中–看见体验版,此时你就可以在成员管理中心添加体验人员进行体验
  • 体验如果没有什么bug就可以提交代码审核(首次审核要2-3小时)
  • 审核之后需要等2个小时就可以在微信小程序收到你提交的名字了
  • tips:公司域名要用https开头的哟