分享分享,有用就拿,别喷

68 阅读8分钟

1.封装本地储存

const storage = {
set(key, value) {
    let val = value;
    if (typeof (val) === 'object') {
        val = JSON.stringify(val)
    }
    localStorage.setItem(key, val);
},
get(key) {
    return localStorage.getItem(key);
},
remove(key) {
    return localStorage.removeItem(key);
}
}

2.封装axios请求

import axios from 'axios';
// 服务器请求,needHeader参数用于判断是否需要认证
/**
 *
 * @param {String} url 请求的地址
 * @param {Object} data 请求参数
 * @param {String} method 请求方法(GET,POST等...)
 * @param {Boolean} needHeader 是否需要传token
 * @param {Boolean} getRes 是否将整体请求结果返回,主要用于分页
 * @param {Object} param 用于修改时需要带上参数到请求路径上
 */
const sendRequest = (url, data, method, needHeader, getRes, param) => {
  let headers = {};
  if (needHeader) {
    if (getRes) {
      headers = {
        token: storage.get('token'),
        Prefer: `count=exact`
      };
    } else {
      headers = {
        token: storage.get('token')
      };
    }
  }
  const xhr = axios.create({
    baseURL: baseURL,
    timeout: 10000
  });
  return new Promise((resolve, reject) => {
    if (method === 'GET') {
      var params = data;
      xhr({
          url,
          params,
          headers
        })
        .then(res => {
          if (getRes) {
            resolve(res);
          } else {
            resolve(res.data);
          }
        })
        .catch(err => reject(err));
    } else {
      var params = param;
      xhr({
          url,
          data,
          headers,
          method,
          params
        })
        .then(res => {
          if (getRes) {
            resolve(res);
          } else {
            resolve(res.data);
          }
        })
        .catch(err => reject(err));
    }
  });
};

3.数组去重

var hash = {}; //数组对象去重,选择出来
let newArr = arr.reduce(function(item, next) {
    hash[next.publication_item_title] ? "" : (hash[next.publication_item_title] = true && item.push(next));
    return item;
}, []);

4.过滤数据

let tmp = {};
let list = [];
for (const info of this.RperiodicalAll) {
    tmp[info.book_sku_id] = 1;
}
for (const info of data) {
    console.log(tmp[info.book_sku_id]);
    if (!tmp[info.book_sku_id]) {
        list.push(info);
    }
}
对this.RperiodicalAll循环  并赋值为1
第二个循环,循环第二个数组,将循环的key值放到tmp中判断,有值为1true表示重复数据,对其取反当判断为false 就表示该数组中没有该数据,push到list中

5.时间日期格式化 date-fns

npm install date-fns --save
YYYY-MM-DD HH:mm:ss
format(result.rows[i].publish_date,"YYYY-MM-DD");

6.PG数据库分页

let req_data = {
    offset:(this.pageInfo.page - 1) * this.pageInfo.limit,
    limit:this.pageInfo.limit,
};
      
//得到数据后,解析响应头
let range = result.headers["content-range"]? result.headers["content-range"].split("/"): [];

this.pageInfo.total = Number(range[1]) >> 0;

7.vue中路由跳转自动添加问号

8.vue-cli 快速搭建项目

下载vue-cli 	npm install -g vue-cli
镜像下载 	   npm install -g cnpm --registry=https://registry.npm.taobao.org
创建项目	   vue init webpack vue-web
Simple(太简单,就一个index.html文件)、webpack-simple(比较实用)、webpack(较全,内置有方法检查、单元测试等。) vue-cli3 ===> 更香

9.将数据以表格形式导出

// Blob.js  Export2Excel.js
// 将数据以表格形式导出导出
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => v[j]));
    },
    export2Excel() {
      require.ensure([], () => {
        const { export_json_to_excel } = require("@/export2excel/Export2Excel");
	//表头键
       const tHeader = [ 
          "书号",
          "书名",
          "简称",
        ];
	//表头对应的数据key
        const filterVal = [
          "isbn",
          "publication_item_title",
          "publication_title_py",
        ];
        const list = this.excelList;//要导出的数据
        const data = this.formatJson(filterVal, list);
        export_json_to_excel(tHeader, data, "订单数据列表");//表名
      });

10.时间倒计时和计时器

function countdown () {
  // 目标日期时间戳
  const end = new Date('2017-12-01').getTime()
  // 当前时间戳
  const now = new Date().getTime()
  // 相差的毫秒数
  const msec = end - now
  // 计算时分秒数
  let day = parseInt(msec / 1000 / 60 / 60 / 24)
  let hr = parseInt(msec / 1000 / 60 / 60 % 24)
  let min = parseInt(msec / 1000 / 60 % 60)
  let sec = parseInt(msec / 1000 % 60)
  // 个位数前补零
  hr = hr > 9 ? hr : '0' + hr
  min = min > 9 ? min : '0' + min
  sec = sec > 9 ? sec : '0' + sec
  // 控制台打印
  console.log(`${day}${hr}小时 ${min}分钟 ${sec}秒`)
  // 一秒后递归
  setTimeout(function () {
    countdown()
  }, 1000)
}



function timer(id) {
    var tFlag = 0
    var end = new Date('2017-10-15')
    var now = new Date()
    var tPass = now.getTime() - end.getTime();
    if (tFlag != 0) {
       var tNew = new Date().getTime();
       tPass = tPass + (tNew - tFlag);
       tFlag = tNew;
    } else {
        tFlag = new Date().getTime();
    }
    var sc = Math.floor((tPass / 1000) % 60);
    var mi = Math.floor((tPass / 1000 / 60) % 60);
    var hr = Math.floor((tPass / 1000 / 60 / 60) % 24);
    var dy = Math.floor(tPass / 1000 / 60 / 60 / 24);
     hr = hr > 9 ? hr : '0' + hr
  	 mi = mi > 9 ? mi : '0' + mi
     sc = sc > 9 ? sc : '0' + sc
    var info = "已经是" + dy + "天" + hr + "时" + mi + "分" + sc + "秒";
    consoloe.log(info)
    setTimeout(() => {
       timer('love')
      }, 1000);
    }

11.绘制图标 echarts

官网地址

12.SVG 字体图标

<svg class="ad_icon">
    <use xlink:href="#k12huabanfuben" />
</svg>

<style>
.ad_icon {
  width: 24px;
  height: 24px;
  margin-right: 5px;
}
</style>

13.移动端rem布局

移动端开发屏幕适配

npm i lib-flexible  //在main.js中引入 lib-flexible   import 'lib-flexible/flexible'

npm i postcss-pxtorem  //新建postcss.config.js

//postcss.config.js
module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-pxtorem': {
      rootValue: 37.5,
      propList: ['*']
    }
  }
}

14.elementUi 级联选择器

<el-cascader
    clearable
    :style="{width:'100%'}"
    v-model="form.category_name"
    :options="allClassify"
    :props="{ expandTrigger: 'hover',value:'id',label:'category_name',children:'sub_category' }"
    placeholder="请选择书籍分类"
    @change="handleChange">
</el-cascader>
//获取所有的书籍分类
    AllCategory() {
      getAllCategory()
        .then(result => {
          result.forEach(element => {
       //应对数据可能出现一级分类选择或二级分类选择 进行判断修改
            if (element.sub_category.length < 1) {
              element.sub_category = undefined;
            }
            for (let i = 0; i < element.sub_category.length; i++) {
              if (element.sub_category[i].sub_category.length < 1) {
                element.sub_category[i].sub_category = undefined;
              }
            }
          });
          this.allClassify = result;
          console.log(result);
        })
        .catch(err => {
          this.$message({ message: "获取书籍分类失败!", type: "error" });
        });
    },

15.表单验证

<el-form :model="form" :rules="rules" ref="form" label-width="130px" class="demo-form-inline">
  <el-row>
    <el-col :span="10" :offset="1">
      <el-form-item label="出版社名称:" prop="press_name">
      	<el-input style="width:100%" v-model="form.press_name" placeholder="请输入出版社名称">
    	  </el-input>
	  </el-form-item>
    </el-col>
    <el-col :span="10" :offset="1">
       <el-form-item label="联系电话:" prop="contact_phone">
         <el-input
         v-model="form.contact_phone"
         @keyup.native="keyupMobile"
         maxlength="11"
         placeholder="请输入手机号码"
         ></el-input>
       </el-form-item>
     </el-row>
</el-form>
data() {
    //自定义校验
    let checkMobile = (rule, value, callback) => {
      console.log(rule, value, callback);
      var regu = /^1(3|4|5|6|7|8|9)\d{9}$/;
      var re = new RegExp(regu);
      if (!value) {
        callback(new Error("电话号码不能为空,请输入电话号码"));
      } else if (!re.test(value)) {
        callback(new Error("电话号码格式错误,请输入电话号码"));
      } else {
        callback();
      }
    };
    };
    return {
      cityShow: false,
      rules: {
        //常规校验
        press_name: [
          { required: true, message: "请输入出版社名称", trigger: "blur" }
        ],
        //自定义校验
        contact_phone: [{ validator: checkMobile, trigger: "blur" }],
    }
}
        

16.设置浏览器解析格式

'Content-Type', 'text/plain; charset=utf-8'

17.Map()方法

const sweetArray = [2, 3, 4, 5, 35]
const sweeterArray = sweetArray.map(sweetItem => {
    return sweetItem * 2
})
 
console.log(sweetArray)   // [2, 3, 4, 5, 35]
console.log(sweeterArray)


const myUsers = [
    { name: 'chuloo', likes: 'grilled chicken' },
    { name: 'chris', likes: 'cold beer' },
    { name: 'sam', likes: 'fish biscuits' }
]
 //格式化数组对象
const usersByFood = myUsers.map(item => {
    const container = {};
 
    container[item.name] = item.likes;
    container.age = item.name.length * 10;
 
    return container;
})
 
 
console.log(usersByFood);
// [{chuloo: "grill

18.上传文件

<el-upload
        style="display:inline-block"
        :show-file-list="false"
        accept=".xls, .xlsx"
        class="upload-demo"
        action="https://upload-z1.qiniup.com"
        :on-success="handleChange"
        :before-upload="beforeUpload"
        :data="qiniuData"
      >
        <el-button size="medium" round type="primary">点击导入</el-button>
</el-upload>
//before-upload	上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
beforeUpload(file) {
      console.log(file);
      var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
      const extension = testmsg === "xls";
      const extension2 = testmsg === "xlsx";
      // const isLt2M = file.size / 1024 / 1024 < 10
      if (!extension && !extension2) {
        this.$message({
          message: "上传文件只能是 xls、xlsx格式!",
          type: "warning"
        });
      }
      // if(!isLt2M) {
      //     this.$message({
      //         message: '上传文件大小不能超过 10MB!',
      //         type: 'warning'
      //     });
      // }
      // return extension || extension2 && isLt2M
      return extension || extension2;
},

19.elementUI 表格单元格合并

//获取数据的方法内
		  this.spanArr = [];
          let pos,position = null
          for (var i = 0; i < result.rows.length; i++) {
            if (i === 0) {
              this.spanArr.push(1);
              pos = 0;
              position = 0;
            } else {
              // 判断当前元素与上一个元素是否相同(第1和第2列)
              if (result.rows[i].book_id === result.rows[i - 1].book_id) {
                this.spanArr[pos] += 1;
                this.spanArr.push(0);
              } else {
                this.spanArr.push(1);
                pos = i;
              }
            }
          }


 //表格单元格合并
   objectSpanMethod({ row, column, rowIndex, columnIndex }) {
       //columnIndex表示要合并的行
      if (columnIndex === 1 ) {
        const _row = this.spanArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        };
      } 
    },

20.解决git pull时一直需要输入账号密码

git config --global credential.helper store

21.小程序省市区选择器

<text class="section_title">所在地区</text>
      <view class="provinces_select">
        <picker class="province" bindchange="handleGetProvince" value="{{index}}" range="{{provinceArr}}">
          <view class="picker {{province === '省/自治区/直辖市'?'gary':''}}">
            {{province}}
            <view class="provinces_btn">
              <image src="../../assets/image/xiangxia.svg" mode="widthFix" />
            </view>
          </view>
        </picker>
        <picker class="city" bindchange="handleGetCity" value="{{index}}" range="{{cityArr}}">
          <view class="picker {{city === '市'?'gary':''}}">
            {{city}}
            <view class="provinces_btn">
              <image src="../../assets/image/xiangxia.svg" mode="widthFix" />
            </view>
          </view>
        </picker>
        <picker class="area" bindchange="handleGetArea" value="{{index}}" range="{{areaArr}}">
          <view class="picker {{area === '区/县'?'gary':''}}">
            {{area}}
            <view class="provinces_btn">
              <image src="../../assets/image/xiangxia.svg" mode="widthFix" />

            </view>
          </view>
        </picker>
      </view>
	data: {
    province: '省/自治区/直辖市',
    city: '市',
    area: '区/县',
    areaList: [], //省市区数组
    provinceIndex: 0,
    provinceArr: [], //省数组
    cityIndex: 0,
    cityArr: [], //市数组
    areaArr: [], //区数组
    province_id: '',
    city_id: '',
    area_id: '',
  },
   // 获取省市区列表
  getProvincesList() {
    request('#', 'GET', {}).then(result => {
        this.setData({
          areaList: result.data,
          provinceArr: result.data.map(t => t.label),
          cityArr: result.data[0].children.map(t => t.label),
          areaArr: result.data[0].children[0].children.map(t => t.label)
        });
      })
      .catch(err => {
        console.log(err);
      });
  },
// 选择省
  handleGetProvince(e) {
    let areaList = this.data.areaList;
    let index = e.detail.value;
    this.setData({
      provinceIndex: index,
      province_id: areaList[index].value,
      cityArr: areaList[index].children.map(t => t.label),
      areaArr: areaList[index].children[0].children.map(t => t.label),
      province: areaList[index].label,
      city_id: "",
      area_id: "",
      city: "市",
      area: "区/县"
    });
  },
  // 选择市
  handleGetCity(e) {
    let provinceIndex = this.data.provinceIndex;
    let areaList = this.data.areaList;
    let cityArr = this.data.cityArr;
    let index = e.detail.value;
    this.setData({
      cityIndex: index,
      province_id: areaList[provinceIndex].value,
      city_id: areaList[provinceIndex].children[index].value,
      areaArr: areaList[provinceIndex].children[index].children.map(t => t.label),
      city: areaList[provinceIndex].children[index].label,
      province: areaList[provinceIndex].label,
      area_id: "",
      area: "区/县"
    });
    console.log(this.data.province_id, this.data.city_id, this.data.area_id);
  },
  // 选择县
  handleGetArea(e) {
    console.log(e.detail.value);
    let provinceIndex = this.data.provinceIndex;
    let cityIndex = this.data.cityIndex;
    let areaList = this.data.areaList;
    let cityArr = this.data.cityArr;
    let index = e.detail.value;
    this.setData({
      province: areaList[provinceIndex].label,
      city: areaList[provinceIndex].children[cityIndex].label,
      province_id: areaList[provinceIndex].value,
      city_id: areaList[provinceIndex].children[cityIndex].value,
      area_id: areaList[provinceIndex].children[cityIndex].children[index].value,
      area: areaList[provinceIndex].children[cityIndex].children[index].label
    });
    console.log(this.data.province_id, this.data.city_id, this.data.area_id);
  },

22.小程序封装一个安全校验提示框

子组件

<--components/verify/verify.wxml-->
<view class="verify" hidden="{{!verifyShow}}">
  <view class="main">
    <!-- 标题 -->
    <view class="verify_title">
      安全校验
    </view>
    <!-- 内容 -->
    <view class="verify_content">
      <view>
        <input type="text" placeholder="请输入验证码" bindinput="handleGetVal" /> 
        <image class="code" src="{{imgBase}}" /> 
        <image class="shuaxin" src="../../assets/image/shuaxin.svg" />
      </view>
      <view class="warning" wx:if="{{warning}}">
        请输入验证码
      </view>
    </view>
    <view class="verify_btn">
      <view bindtap='_cancel'>取消</view>
      <view bindtap="_confirm">确认</view>
    </view>
    
  </view>
</view>
@function rpx($a) {
  $rpx: 1.8;
  @return ($a * $rpx)+rpx
}

.verify{
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background-color: rgba(0,0,0,.4);
  >.main{
    margin: 30vh 10vw;
    width: 80vw;
    background-color: #fff;
    border-radius: rpx(10);
    text-align: center;
    >.verify_title{
      padding: rpx(15);
      font-size: rpx(18);
    }
    >.verify_content{
      padding: rpx(10);
      margin-bottom: rpx(30);
      >view{
        display: flex;
        align-items: center;
        width: 90%;
        margin: 0 auto;
        padding: rpx(6) 0;
        border: rpx(2) solid #adadad;
        input{
          vertical-align: middle;
          text-align: left;
          width: rpx(120);
          height: rpx(30);
          padding-left: rpx(10);
        }
        >.code{
          vertical-align: middle;
          width: rpx(96);
          margin-left: rpx(10);
          height: rpx(30);
          border: rpx(2) solid #000;
          border-radius: rpx(4);
        }
        >.shuaxin{
          vertical-align: middle;
          flex: rpx(1);
          width: rpx(22);
          height: rpx(22);
        }
      }
      >.warning{
        border: none;
        margin-top: rpx(6);
        font-size: rpx(14);
        color: #f00;
      }
    }
    >.verify_btn{
      display: flex;
      border-top: rpx(2) solid #adadad;
      >view{
        width: 50%;
        padding: rpx(15);
        text-align: center;
        color: rgb(105, 177, 196);
      }
      >view:nth-of-type(1){
        border-right: rpx(2) solid #adadad;
      }
    }
  }
}
// components/verify/verify.js
Component({
  /**
   *  存放 父组件向子组件传递的数据
   */
  properties: {
    imgBase: {
      type: "String",
      value: ""
    },
    warning: {
      type: 'blur',
      value: false,
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    verifyShow: false,
  },
  /**
   * 组件的方法列表
   */
  methods: {
    show() {
      this.setData({
        verifyShow: true
      })
    },
    hide() {
      this.setData({
        verifyShow: false
      })
    },
    handleGetVal(e) {
      console.log(e)
      let inputVal = e.detail.value
      this.triggerEvent('getVal',{inputVal})
    },
    /*
     * 内部私有方法建议以下划线开头
     * triggerEvent 用于触发事件
     */
    _cancel() {
      //触发取消回调
      this.triggerEvent("cancel")
    },
    _confirm() {
      //触发成功回调
      this.triggerEvent("confirm");
    }
  }
})

父组件

<!-- 安全校验 -->
<verify
id="verify"
imgBase="{{imgBase}}"
warning="{{warning}}"
bind:cancel="handleCancelVerify"
bind:confirm="handleConfirmVerify"
bind:getVal="handleGetVal">
></verify>
import request from '../../utils/request';
import regeneratorRuntime from '../../lib/runtime/runtime';

// pages/register/index.js
let num = 0;
Page({
  /**
   * 页面的初始数据
   */
  data: {
  	imgBase:"",
    warning: false, //子组件警告提示
    codeVerify:""  //子组件图形校验码
  },
  // 点击了弹出框的取消
  handleCancelVerify() {
    this.verify.hide()
  },
  handleGetVal(e) { 
    console.log();
    let val = e.detail.inputVal
    if (val) {
      this.setData({
        codeVerify:val,
        warning:false
      })
    }
  },
  // 点击了弹出框的确认
  handleConfirmVerify() {
    let codeVerify = this.data.codeVerify
    let phone = this.data.phone
    console.log(codeVerify);
    if (codeVerify === '') {
      this.setData({
        warning:true
      })
    } else { 
      this.verify.hide()
  },
  
});

23.axios response中headers中数据和实际响应的不一致问题

//出现这个问题是原因是CORS的限制,我们可以通过在服务器端使用
Access-Control-Expose-Headers

24.设置网页全局为样式

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script>
    const url = "https://www.baidu.com/img/baidu_resultlogo@2.png";
    let html = "";
    [{
        name: "灰度100%",
        style: "grayscale(100%)"
      },
      {
        name: "模糊5px",
        style: "blur(5px)"
      },
      {
        name: "3倍亮度",
        style: "brightness(300%)"
      },
      {
        name: "200%对比度",
        style: "contrast(200%)"
      },
      {
        name: "200%饱和度",
        style: "saturate(200%)"
      },
      {
        name: "色相旋转180度",
        style: "hue-rotate(180deg)"
      },
      {
        name: "100%反色",
        style: "invert(100%)"
      },
      {
        name: "50%透明度",
        style: "opacity(50%)"
      },
      {
        name: "阴影",
        style: "drop-shadow(10px 5px 5px #f00)"
      },
      {
        name: "100%透明度",
        style: "opacity(100%)"
      },
      {
        name: "褐色程度70%",
        style: "sepia(70%)"
      }
    ].forEach(({
      name,
      style
    }) => {
      html += `<div>${name}-${style}: <img src=${url} style="filter: ${style}" /></div><br />`;
    });
    document.body.innerHTML = html;
  </script>
</body>

</html>

25.微信小程序尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素1rpx = 0.5px = 1物理像素

设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。

使用步骤:

  1. 确定设计稿宽度 pageWidth
  2. 计算比例 750rpx = pageWidth px ,因此 1px=750rpx/pageWidth
  3. 在sass文件中,只要把设计稿中的 px => 750/pageWidth rpx 即可。
@function rpx($a) {
  $rpx: 2;
  @return ($a * $rpx)+rpx
}

26.正则校验

链接

//手机号校验
!/^1(3|4|5|6|7|8|9)\d{9}$/.test(phone)

27.文本省略号

//单行省略
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis

//多行省略
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2

28.小程序强制更新

/**
 * 下载小程序新版本并重启应用
 */
  const downLoadAndUpdate = (updateManager)=>{
  wx.showLoading();
  //静默下载更新小程序新版本
  updateManager.onUpdateReady(function () {
    wx.hideLoading()
    //新的版本已经下载好,调用 applyUpdate 应用新版本并重启
    updateManager.applyUpdate()
  })
  updateManager.onUpdateFailed(function () {
    wx.hideLoading()
    // 新的版本下载失败
    wx.showModal({
      title: '新版本更新异常',
      content: '新版本更新出现异常,请按以下方式更新: ⒈请回到微信的"聊天列表"; ⒉下拉,找到当前小程序图标长按拖动删除; ⒊点击"发现"→"小程序",顶部搜索"书籍审查入库工具",即可进入最新版本。',
    })
  })
}
const autoUpdate = () => {
  // 获取小程序更新机制兼容
  if (wx.canIUse('getUpdateManager')) {
    const updateManager = wx.getUpdateManager()
    //1. 检查小程序是否有新版本发布
    updateManager.onCheckForUpdate(function(res) {
      // 请求完新版本信息的回调
      if (res.hasUpdate) {
        //检测到新版本,需要更新,给出提示
        wx.showModal({
          title: '更新提示',
          content: '检测到新版本,是否更新为最新版本并重启小程序?',
          success: function (res) {
            console.log(res);
            if (res.confirm) {
              //2. 用户确定下载更新小程序,小程序下载及更新静默进行
              downLoadAndUpdate(updateManager)
            } else if (res.cancel) {
              //用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
              wx.showModal({
                title: '温馨提示',
                content: '本次版本更新涉及到新的功能添加,旧版本无法正常使用',
                showCancel:false,//隐藏取消按钮
                confirmText:"确定更新",//只保留确定更新按钮
                success: function(res) {
                  if (res.confirm) {
                    //下载新版本,并重新应用
                    downLoadAndUpdate(updateManager)
                  }
                }
              })
            }
          }
        })
      }
    })
  } else {
    // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
    })
  }
}

module.exports = autoUpdate

29. 小程序请求封装

import regeneratorRuntime from '../lib/runtime/runtime'; //解决小程序使用promise报错的问题
// 公共的url
let token = '';
var app = getApp();
let baseUrl = app.globalData.baseUrl;

function request(url, method, data, headers, param) {
  if (headers) {
    token = wx.getStorageSync('token');
  }
  return new Promise((resolve, reject) => {
    // 显示正在等待
    wx.showLoading({
      title: '正在加载中',
      mask: false
    });
    if (param) {
      wx.request({
        data,
        method,
        url: baseUrl + url + `?${param}`,
        header: {
          token: token
        },
        success: result => {
          // 隐藏正在等待图标
          setTimeout(() => {
            wx.hideLoading();
          },300);
          if (result.statusCode == 401 || result.statusCode == 403) {
            wx.showToast({
              title: '登录验证已过期,请重新登录',
              icon: 'none',
              image: '',
              duration: 1500,
              mask: false,
            });
            wx.clearStorageSync();
            setTimeout(() => {
              wx.redirectTo({
                url: '/pages/login/index',
              });

            }, 1500);
          } else if (result.statusCode == 200 || result.statusCode == 204) {
            resolve(result);
          } else {
            reject(result.data)
          }
        },
        fail: err => {
          // 隐藏正在等待图标
          setTimeout(() => {
            wx.hideLoading();
          },300);
          reject(err);
        },
      });
    } else {
      wx.request({
        data,
        method,
        url: baseUrl + url,
        header: {
          token: token
        },
        success: result => {
          // 隐藏正在等待图标
          setTimeout(() => {
            wx.hideLoading();
          },300);
          if (result.statusCode == 401 || result.statusCode == 403) {
            wx.showToast({
              title: '登录验证已过期,请重新登录',
              icon: 'none',
              image: '',
              duration: 1500,
              mask: false,
            });
            wx.clearStorageSync();
            setTimeout(() => {
              wx.redirectTo({
                url: '/pages/login/index',
              });
            }, 1500);
          } else if (result.statusCode == 200 || result.statusCode == 204) {
            resolve(result);
          } else {
            reject(result.data)
          }
        },
        fail: err => {
          // 隐藏正在等待图标
          setTimeout(() => {
            wx.hideLoading();
          },300);;
          reject(err);
        },
      });
    }

  });
}
module.exports = request;

30. 根据所在ip地址获取所在地区名称

const path = require('path');
module.exports = () => {
  const { IDC, City, District, BaseStation } = require('ipip-ipdb');
  return async function parseAddress(ctx, next){
    await next();
    const city = new City(path.join(ctx.app.baseDir)+'/ipipfree.ipdb');
    
    var clientIP = ctx.ips.length > 0 ? ctx.ips[ctx.ips.length - 1] : ctx.ip;
    clientIP = clientIP.replace('::ffff:','');
    
    const regionName = city.findInfo(clientIP, 'CN').regionName;

    if(!ctx.session.manualRegionName){
      if(regionName == '本机地址' || regionName == '局域网'){
        ctx.session.regionName = '全国';
      }else{
        ctx.session.regionName = regionName;
      }
    }
  }
};