微信小程序

微信公众平台

公众号
订阅号
小程序:
基本语法
组件
api
业务逻辑
1,原生开发,
2,vue开发,,uniapp,wepy,mpvue
3,react 方式taro
微信开发者工具
小程序ID:开发,开发设置
个人服务器关联微信服务器:
开发 -开始开发-接入指南
配置服务器接收token
body-parser-xml:解析xml

基础

wxml html 页面骨架
wxss css 样式
xx.js js 业务逻辑
xx.json json配置文件(所有页面写在pages里)
pages里数组的第一项就是首页
view 相当于div块级元素
home.model做业务逻辑
home:只做业务处理
utils
api:接口文件
:base类

<template   name=''>:创建模板
<template  is= name>:调用模板
使用模板  import导入<import  src='路径'/>
页面中写上标签<template is='文件名'></template
data传参

路由传参方式
switchTab:只能往tabbar页面(不带参)
reLaunch:哪一个页面都能跳(可以带参)
redirectTo:跳转非tabbar页面(可以)
navigateTo:带后退符号(可以)

传参:
1,地址栏拼接参数
2,目标页 onLoad接受传递的参数

下拉刷新
wx.stopPullDownRefresh
在这里插入图片描述
案列


const req = require('../../req/index.js'); //接口
Page({
  data: {
    list:[],
    params:{
      p:1
    }
  },
  onLoad: function (options) {
    let data ={
      p:1
    }
    this.getList(this.data.params)
  },
  getList(data){
    req.my.getrecord(data)
    .then((res) => {
      if (res.status == 1) {
        this.setData({
          user:res.data.user,
      })
        let list = res.data.integral_log
        if(data.p==1){
          this.setData({
            list: list
          })
          wx.stopPullDownRefresh()
        }else {
          this.setData({
            list: list ? this.data.list.concat(list) : this.data.list
          })
        }
      }
    })
    .catch(req.err.show);
  },  
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    this.setData({
      ['params.p']: 1
    })
    this.getList(this.data.params)
  },
  
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    this.setData({
      ['params.p']: ++this.data.params.p
    })
    this.getList(this.data.params)
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

样式
宽度:vw,高度:vh,
任何宽度都是750rpx
事件:
bindtap 点击事件 tap:事件名
bindlongtap:长按事件
cathtap:
bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
事件传参:data-事件名= ‘value’
修改数据,this.setData({key:value})
适配 rpx 宽度 都是750prx
弹性盒布局
跳转传参
../notice_info/notice_info?id=${id}&type=${type}
缓存站10个页面
没有跨域问题。
请求的api放在列表中
开发,配置服务器信息api接口是https 的
http数据是明文传输,

生命周期

在app.js里的生命周期 onLaunch,onShow,onHide,onError。
onLaunch:初始化完成触发 全局触发一次。
onShow:小程序启动,或从后台进入前台显示会触发。
onHide:前台进入后台会触发。
onError:小程序脚本错误,或者api调用失败时,会触发。
执行了onLaunch和onShow
== 在页面里的生命周期==
onLoad 生命周期函数–监听页面加载
onReady生命周期函数–监听页面初次渲染完成
onShow 生命周期函数–监听页面显示
onHide 生命周期函数–监听页面隐藏
onUnload 生命周期函数–监听页面卸载

打开小程序后会依次执行onLoad,onReady,onShow方法
前后台切换会分别执行onHide和onShow方法,
当小程序页面销毁时会执行 onUnload方法

缓存优化:
取数据之前先判断数据是否存在缓存
有:读取缓存
没有:请求数据,存到缓存里
优先从缓存中获取
清除localstore,设置事件戳,超时时间

谁用直接引入在这里插入图片描述

购物车逻辑:
加入购物车让你登录,
本地存一份

没有登录可以加入购物车:数据存到缓存中的
都在购物车页面写,
加入购物车,缓存
数量的加减
删除购物车,清空购物车
获取数量,总价钱
选中全选,反选
选中数量,选中总价格
提交
在这里插入图片描述

登录:
先调用wx.longin获取code
再调用自己后端的接口获取用户基本信息和token

在这里插入图片描述

微信支付

微信服务器:生成收款订单(prepay_id),预付款id
商户系统:库存数量,生成订单id,添加订单数据(未付款)
**用户系统 :**下单:商品,调ajax接口

1,生成订单id,添加订单数据,(未服款)
微信:生成收款订单(prepay_id)(预订单id,预付款id)

1。调用后端的下单接口,返回5个参数(时间戳,随机字符串,package预订单id,signType签名)
2。调用wx.requestPayment 进行支付,处理返回结果

前端:
1,调用后端下单接口,返回5个参数
2,调用wx.requestPayment,进行支付,处理返回结果

API

获取用户授权:
wx.getUserInfo
验证登录状态:wx服务器的登录状态
wx.checkSession

公众号

消息回复

1,配置服务器,公众号的消息可以转发到自己的服务器

公众号本身开发

1.消息回复
2.自定义菜单

用户在公众号发送消息 将消息发给微信的服务器 微信服务器做处理返回数据
用户在公众号发送消息 将消息发给微信的服务器 微信服务器不做处理 将消息转发给开发者服务器
需要一台外网访问的服务器

内网穿透(9+3)natapp

将一台局域网的服务器映射到外网 可以实现外网访问

公众号网页开发

1.分享朋友圈
2.调用微信的扫一扫,摇一摇

消息回复 (周公解梦 星座运势 情侣匹配 天气查询 。。。 每日音乐 点歌平台)
  1. 配置服务器 公众号的消息可以转发到自己的服务器
  2. 接受公众号消息 xml post url
  3. 处理消息
  4. 返回xml 数据格式
创建自定义菜单 调用微信的api接口

创建自定义菜单
1.获取access_token (当前的微信账号有权限,去申请公众号测试账号)
2.调用相关的接口

jssdk 微信的网页开发

网页 可以调用微信的功能
O7pxPBNkfsueenY6
1.安全域名的配置
2.通过模板ejs引擎将后端的数据注册到网页上
3.产生签名数据
a.获取jsapi_ticket
b.产生时间戳 以s为单位
c.产生16进制随机字符串
d. jsapi_ticket 时间戳 随机字符串 以及要调用微信功能的网页地址 进行加密产生签名
4.将签名数据注册到网页上
5.调用接口 所有接口必须在apiList 声明
在这里插入图片描述

保存照片到相册
 let _this = this
    wx.downloadFile({
      url: _this.data.imgUrl,     //图片地址后台传来的
      success (res) {
        if (res.statusCode === 200) {
         let img = res.tempFilePath
         wx.saveImageToPhotosAlbum({
            filePath:img,
            success(arr){
        wx.showToast({
            title: '保存成功',
            icon:'success'
          })
          _this.setData({
            isShow:false
          })
            }
         })    
       }
      }
    })

video全屏展示

   this.videoContext = wx.createVideoContext('myVideo', this);
   this.videoContext.requestFullScreen({ direction: 90 });

搜索关键字标红

const getInf =(str, key) =>str.replace(new RegExp(`${key}`, 'g'), `%%${key}%%`).split('%%');  
请求接口返回列表成功执行:this.searchTap(); 
  searchTap:function(){
        var list = this.data.list  			  		//list接口返回数据
        for (var i = 0; i < list.length; i++) {
          var dic = list[i];
          var text = dic.name;					//name接口存在的参数需要改变颜色的参数
          if(list !=''){
            dic.name =getInf(text, this.data.params.name);    // this.data.params.name搜索关键字
          }else {
            return
          }     
      }
        this.setData({
          list: list
      });    
  },
  页面
  <view class="{{item== params.name?'e1':''}}" wx:for="{{item.name}}" wx:key="name">{{item}}</view>

富文本展示

页面:
<import src="../../wxParse/wxParse.wxml" />
<template is="wxParse" data="{{wxParseData:article.nodes}}" />
JS:
const WxParse = require('../../wxParse/wxParse.js')
接口请求成功后:
 let _this = this;
let article = res.data.content
WxParse.wxParse('article', 'html', article, _this,5)
富文本:<wxParse nodes="{{htmlText}}" />(json引入wxParse)
        "wxParse": "../../components/wxParse/wxParse"

scroll-view组件

//隐藏横向滚动条
::-webkit-scrollbar{
  width: 0;
  height: 0;
  color: transparent;
  display:none;
}

遮罩层

  	width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, .5);
    z-index: 999;	
授权点取消,再次进入再授权
    let that = this;
    // 获取位置信息
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) { //非初始化进入该页面,且未授权
          wx.showModal({
            title: '是否授权当前位置',
            content: '需要获取您的地理位置,请确认授权,否则无法获取您所需数据',
            success: function (res) {
              if (res.cancel) {
                that.setData({
                  isshowCIty: false
                })
                wx.showToast({
                  title: '授权失败',
                  icon: 'error',
                  duration: 1000
                })
              } else if (res.confirm) {
                wx.openSetting({
                  success: function (dataAu) {
                    console.log(dataAu)
                    if (dataAu.authSetting["scope.userLocation"] == true) {
                      wx.showToast({
                        title: '授权成功',
                        icon: 'success',
                        duration: 1000
                      })
                      that.getLocation(that);
                    } else {
                      wx.showToast({
                        title: '授权失败',
                        icon: 'error',
                        duration: 1000
                      })
                    }
                  }
                })
              }
            }
          })
        } else if (res.authSetting['scope.userLocation'] == undefined) { //初始化进入
          that.getLocation(that);
        } else { //授权后默认加载
          that.getLocation(that);
        }
      }
    })
  },

//重复点击

1,
	data:{
		lock:false
	}
    if (!this.data.lock) {
      this.setData({
      	  lock: true  //true可以点击
      });
  2:
    var lasttime = 0;
    let d = new Date();
    let nowtime = d.getTime(); //获取点击时间
    if (nowtime - lasttime > 1500) { //1500ms内无法识别再点击
    		  this.ping()   //提交接口
    }
   			 lasttime = nowtime;

倒计时

gettimer: function () {
       let time = 60;
       this.setData({
	timer: setInterval(() => {
	        time--
		this.setData({
		      hint: time + '秒后重发'
		})
		if (time == 0) {
		    clearInterval(this.data.timer)
		   this.setData({
		     hint: '获取验证码',
		  })
	        }
      }, 1000)
   })
},

数字取整

<wxs module="filters" src="../../utils/addmul.wxs" />

---
var filters = {
  toFix2: function (value) {
    return parseFloat(value).toFixed(2)//此处2为保留两位小数
  },
  toFix1: function (value) {
    return parseFloat(value).toFixed(1)//此处1为保留一位小数
  },
  toFix: function (value) {
    return parseFloat(value).toFixed(0)//此处0为取整数
  }
}
module.exports = {
  toFix2: filters.toFix2,
  toFix1: filters.toFix1,
  toFix: filters.toFix
}

---

自定义tabbar
闪烁问题

    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
      this.getTabBar().setData({
        selected: 0    //索引
      })
    }

分页

  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark"
  data:定义params:{ }
  onLoad:{
  
  this.getList(data)
  }
  -------
  onPullDownRefresh: function () {
    this.setData({
      ['params.page']: 1
    })
    this.getList(this.data.params)
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    this.setData({
      ['params.page']: ++this.data.params.page
    })
    this.getList(this.data.params)
  },
  ------
  bindinput(e) {
    const value = e.detail.value
    const num = parseInt(e.detail.value.length)
    if (num <= 200) {
      this.setData({
        value: value,
        num: num
      })
    } else if(num>200){
      $.toast('最多输入200字')
      this.setData({
        num:200,
        value:''
      })
    }
  },

分享

  onShareAppMessage: function (res) {
    if (res.from === 'button') {}
    return {
      title: this.data.Info.work_name,
      path: 'pages/productionInfo/productionInfo?id='+this.data.Info.work_id,
      imageUrl: this.data.Info.cover_id,
    }
  },

地理位置
腾讯地图api
地理位置获取城市

引入
var QQMapWX = require('../../utils/qqmap-wx-jssdk.js');
var qqmapsdk;
onLoad(){
	  qqmapsdk = new QQMapWX({
      key: 'YUUBZ-T6C3X-RVI4M-7P2EQ-AEQWH-RTBCJ'
    });
   this.getUserLocation() 
 },
   getUserLocation: function () {
    let that = this;
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) {
          wx.showModal({
            title: '请求授权当前位置',
            content: '需要获取您的地理位置,请确认授权',
            success: function (res) {
              if (res.cancel) {
                wx.showToast({
                  title: '拒绝授权',
                  icon: 'none',
                  duration: 1000
                })
              } else if (res.confirm) {
                wx.openSetting({
                  success: function (dataAu) {
                    if (dataAu.authSetting["scope.userLocation"] == true) {
                      wx.showToast({
                        title: '授权成功',
                        icon: 'success',
                        duration: 1000
                      })
                      that.getLocation();
                    } else {
                      wx.showToast({
                        title: '授权失败',
                        icon: 'none',
                        duration: 1000
                      })
                    }
                  }
                })
              }
            }
          })
        } else if (res.authSetting['scope.userLocation'] == undefined) {
          //调用wx.getLocation的API
          that.getLocation();
        } else {
          //调用wx.getLocation的API
          that.getLocation();
        }
      }
    })
  },
    // 获取定位当前位置的经纬度
  getLocation: function () {
    let that = this;
    wx.getLocation({
      success: function (res) {
        let latitude = res.latitude
        let longitude = res.longitude
        app.globalData.lat = res.latitude;
        app.globalData.lng = res.longitude; //把onload定位时候的经纬度存到全局
        that.getLocal(latitude, longitude)
      },
    })
  },
    // 获取当前地理位置
  getLocal: function (latitude, longitude) {
    let that = this;
    qqmapsdk.reverseGeocoder({
      location: {
        latitude: latitude,
        longitude: longitude
      },
      success: function (res) {
        console.log(res)    //返回信息
        $.toast('定位成功')
        wx.setStorageSync('city_name', res.result.ad_info.city)  //城市
      },
    });
  },

进度条

组件 progress
  <progress percent="" border-radius="20"  color="#FC5B0A" stroke-width="8"backgroundColor="#ffdece"/>

上传oss
(尚街小程序案例)

uploadImg文件夹
config.js文件
var fileHost = "https://***********";//你的oss地址
var config = {
  //aliyun OSS config
  uploadImageUrl: `${fileHost}`,
  AccessKeySecret:'GaLGiAGvVh2wWb3UvQdxDNuu6biZ1E',//登录oss控制台查看
  OSSAccessKeyId: 'LTAI4G3bJRTvg5yvg35sCCsn',//登录oss控制台查看
  timeout:200
};
module.exports = config

使用
var uploadImage = require('../../uploadImg/uploadImg.js');
 //上传头像
  uploadImg() {
    let _this = this
    wx.chooseImage({
      count: 1, // 默认最多一次选择3张图
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: (res) => {
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        var tempFilePaths = res.tempFilePaths;
        //支持多图上传
        for (var i = 0; i < res.tempFilePaths.length; i++) {
          //显示消息提示框
          wx.showLoading({
            title: '上传中' + (i + 1) + '/' + res.tempFilePaths.length,
            mask: true
          })
          uploadImage(res.tempFilePaths[i], 'images/',
            function (result) {
              _this.setData({
                head_pic: result
              })
              wx.hideLoading();
            },
            function (result) {
              wx.hideLoading()
            }
          )
        }
      }
    })
  },

确认订单页选择优惠券

selectedNum==index
data:{
selectedNum :-1,
}

  if (this.selectedNum === i) {
        this.selectedNum = -1; //取消选中
      } else {
        this.selectedNum = i;
      }
网页变灰
  filter: grayscale(100%);
  -webkit-filter: grayscale(100%);
  -moz-filter: grayscale(100%);
  -ms-filter: grayscale(100%);
  -o-filter: grayscale(100%);
  filter: url("data:image/svg+xml;utf8,#grayscale");
  filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
  -webkit-filter: grayscale(1);
排序
          function compare(property) {
            return function (a, b) {
              var value1 = a[property];
              var value2 = b[property];
              return value1 - value2; //升序,降序为value2 - value1
            }
          }
            this.setData({
            list:this.data.medal.sort(compare('type'))
          })
          (科艺小程序案例)

小程序点赞 不获取列表直接改变状态
在这里插入图片描述

点击图片放大

bindtap='previewImage'  data-url="{{item.image_url}}"
  previewImage(e) {
    let currentImg = e.currentTarget.dataset.url   //图片链接
    let urls = []
    let gallery = this.data.gallery   //图片数组
    for (let i = 0; i < gallery.length; i++) {
      urls.push(gallery[i].image_url)
    }
    wx.previewImage({
      current: currentImg,
      urls: urls
    })
	},

苹果端底部黑线处理

**1**
app.js里
    wx.getSystemInfo({
      success: (res) => {
        //将机型存入到本地缓存 以免后期其他业务逻辑需要使用
        wx.setStorageSync('Modelmes', res.model)
        if (res.model === 'iPhone X' || 'iPhone XR' || 'iPhone XS Max' || 'iPhone 11' || 'iPhone 11 Pro' || 'iPhone 11 Pro Max') {
          this.globalData.Modelmes = true;
        } else {
          this.globalData.Modelmes = false;
        }
      }
    })
    使用:
    let { Modelmes } = app.globalData;
    this.setData({
      Modelmes: Modelmes
    });
	样式:padding-bottom:{{Modelmes?'30rpx':'0'}}
**2**
	page {
	  padding-bottom: constant(safe-area-inset-bottom);
	  padding-bottom: env(safe-area-inset-bottom);
	}

商品倒计时显示

单个倒计时用vant
多个倒计时:
     <view class="countdown">
       <view class="item">
          <view class="txt-time">{{item.time.hou}}</view>:
          <view class="txt-time">{{item.time.min}}</view>:
          <view class="txt-time">{{item.time.sec}}</view>
      </view>
  this.severalCountDown(); //多个定时器
  
   timeFormat(param) {
    return param < 10 ? '0' + param : param;
  },
  severalCountDown: function () {
    var that = this;
    var time = 0;
    var obj = {};
    var timeList = that.data.list; //时间的数组
    //遍历数组,计算每个item的倒计时秒数
    timeList.forEach(function (item) {
      // var endTime = new Date(item.endTime.replace(/-/g, "/")).getTime(); //结束时间时间戳 (格式时yyy:zz:xx)
      var endTime = parseInt(item.end_time) * 1000; (这个格式是时间戳,*1000是转换为毫秒)
      var currentTime = new Date().getTime(); //当前时间时间戳
      time = (endTime - currentTime) / 1000;
      // 如果活动未结束
      if (time > 0) {
        var hou = parseInt(time / (60 * 60));
        var min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
        var sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
        obj = {
          hou: that.timeFormat(hou),
          min: that.timeFormat(min),
          sec: that.timeFormat(sec)
        }
      } else { //活动已结束
        obj = {
          hou: "00",
          min: "00",
          sec: "00"
        }
        clearTimeout(that.data.timeIntervalSeveral); //清除定时器
      }
      item.time = obj;
    })
    var timeIntervalSeveral = setTimeout(that.severalCountDown, 1000);
    that.setData({
      timeIntervalSeveral,
      list: timeList       (赋值)
    })
  }, 

动画

 wx.createAnimation
 案例,选择框的显示和隐藏
 data:{
    chose_box: false,
    animationData: {}
 }
   show() {
    let animation = wx.createAnimation({
      duration: 500,
      timingFunction: 'ease',
    })
    wx.getSystemInfo({
      success: (res) => {
        const H = res.safeArea.height   H屏幕高度
        if (this.data.chose_box) {
          animation.translateY(0).step()
              this.setData({
                animationData: animation.export(),
                chose_box: false
          })
        } else {
          console.log(11);
          animation.translateY(50 - H).step()
              this.setData({
                animationData: animation.export(),
                chose_box: true
              })
        }
      }
    })
  },
  页面
    <view class="ln-center card" bindtap="show">购买检测卡</view>  点击触发
</view>
<view class=" black" bindtap="show" animation="{{animationData}}">
</view>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值