微信小程序开发总结

微信小程序开发总结

写在前面:小程序的开发需要精益求精,一起来努力探索吧

帮助文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/
微信公众平台:
https://mp.weixin.qq.com/
开发环境:原生小程序+vscode+less+es7(async/await)
可安装如下插件:‘小程序开发助手’,‘minapp’,‘wechat-snippet’,‘wxapp-helper’

小程序中使用less

  1. 编辑器为vscode
  2. 安装插件‘Easy less’
  3. vscode中的setting.json中配置如下代码
"less.compile": {
    "outExt": ".wxss"
},
  1. vscode中新建.less文件编辑即可,如自动生成对应的.wxss文件

使用async/await语法糖参考以下文章照做就好

https://www.cnblogs.com/replaceroot/p/11421713.html

基础和适配

750rpx = 开发屏幕宽度
swiper默认:宽100%,高150px’
imgae默认:宽320px,高240px
在小程序开发中:百分比,vw,vh,rpx会用的比较多,所以掌握这些基础知识是前提

小程序引入iconfont

在这里插入图片描述
在小程序项目中新建styles文件夹 新建iconfont.wxss文件 将刚才网页中打开的iconfont样式代码粘贴进去
在这里插入图片描述
在app.wxss中引入iconfont.wxss

@import './styles/iconfont.wxss';

使用字体图标

<view class="iconfont icon-gouwuche"></view>

封装小程序自带的请求接口wx.request

// 同时发送异步请求的次数
let ajaxNum = 0;
export const request = (params)=>{
    ajaxNum++;
    const baseUrl = "https://api-hmugo-web.itheima.net/api/public/v1";
    wx.showLoading({
        title: '加载中',
        mask: true,
    });
    return new Promise((resolve,reject)=>{
        wx.request({
            ...params,
            url:baseUrl + params.url,
            success: (result) => {
                resolve(result)
            },
            fail: (err) => {
                reject(err)
            },
            // 无论成功失败都会执行的回调
            complete:()=>{
                // 全部请求完毕,删除加载圈
                ajaxNum--;
                if(ajaxNum===0){   //*此处不能写成if(ajaxNum)
                    wx.hideLoading();
                }
            }
        });
    })
}

用户授权及获取用户信息

<button open-type="getUserInfo" bindgetuserinfo="handleGetUserInfo" type="primary" plain>登录</button>
// 获取用户信息
handleGetUserInfo({detail:{userInfo}}){
    wx.setStorageSync('userinfo',userInfo);
    wx.navigateBack({
      delta: 1
    });
}

获取登录的code以及小程序自带功能使用promise的封装示例

export const login = ()=>{
    return new Promise((resolve,reject)=>{
        wx.login({
            timeout:10000,
            success: (result) => {
                resolve(result)
            },
            fail: (error) => {
                reject(error)
            }
        });
    })
}

export const showToast = ({title})=>{
    return new Promise((resolve,reject)=>{
        wx.showToast({
            title,
            success: (result) => {
                resolve(result)
            },
            fail: (error) => {
                reject(error)
            }
        });
    })
}
const {code} = await login();  //拿到code,有时候在获取用户token值用到
await showToast({title:'添加成功'});  //showToast弹窗

获取用户收货地址

<button bindtap="handleChooseAddress" type="primary" plain>获取收货地址</button>
//一套组合拳
async handleChooseAddress(){
    const res = await wx.getSetting();
    const scopeAddress = res.authSetting['scope.address'];
    if(scopeAddress===true || scopeAddress===undefined){
      const res1 = await wx.chooseAddress();
      this.setData({
        address:{
          username:res1.userName,
          add:res1.provinceName+res1.cityName+res1.countyName+res1.detailInfo,
          telNumber:res1.telNumber
        }
      });
      // 下次方便存取
      wx.setStorageSync("address",this.data.address);
    }else{
      const res2 = await wx.openSetting();
      const res3 = await wx.chooseAddress();
    }
  },

wx.previewImage()实现图片预览

<swiper autoplay circular indicator-dots>  //通常轮播图的三个属性
    <swiper-item
    wx:for="{{goods_detail.pics}}"
    wx:key="pics_id"
    data-url="{{item.pics_mid}}"
    bindtap="handlePreview">
        <image mode="widthFix" src="{{item.pics_mid}}"></image>
    </swiper-item>
</swiper>

// 图片放大预览
handlePreview({currentTarget:{dataset:{url}}}){
    const urls = this.goods_detail.pics.map(item=>item.pics_mid)
    wx.previewImage({
      current: url, // 当前显示图片的http链接
      urls // 需要预览的图片http链接列表,支持滑动播放
    })
},

联系客服和分享功能

<button open-type="contact">联系客服</button>
<button open-type='share'>分享</button>

效果图:
在这里插入图片描述
在这里插入图片描述

关于onLoad和onShow方法的获取页面参数

案例:从商品跳转到商品详情页面需要携带商品id:

<view class="first_tab">
    <navigator
    class="goods_item"
    wx:for="{{goods_list}}"
    wx:key="goods_id"
    url="/pages/goods_detail/goods_detail?goods_id={{item.goods_id}}"
    >
    //...此处省略部分代码
    </navigator>
</view>
onShow(){
    let pages =  getCurrentPages();
    let options = pages[pages.length-1].options;
    const {goods_id} = options;
    // 处理收藏商品的逻辑
    this.getGoodsDetail(goods_id);
},
onLoad(options){
    const {goods_id} = options;
   // 处理收藏商品的逻辑
   this.getGoodsDetail(goods_id);
}

在这里插入图片描述

自定义组件使用block占位符类似插槽

wxml:

<!-- 导航栏开始 -->
<tabs tabs="{{tabs}}" bindtabItemClick="handleTabItemClick">
    <block wx:if="{{tabs[0].isActive}}">
        <view class="first_tab">
            <navigator
            class="goods_item"
            wx:for="{{goods_list}}"
            wx:key="goods_id"
            url="/pages/goods_detail/goods_detail?goods_id={{item.goods_id}}"
            >
                <!-- 左侧图片容器 -->
                <view class="goods_img_wrap">
                    <image mode="widthFix" src="{{item.goods_small_logo}}"></image>
                </view>
                <!-- 右侧商品容器 -->
                <view class="goods_info_wrap">
                    <view class="goods_name">{{item.goods_name}}</view>
                    <view class="goods_price">{{item.goods_price}}</view>
                </view>
            </navigator>
        </view>
    </block>
    <block wx:if="{{tabs[1].isActive}}">1</block>
    <block wx:if="{{tabs[2].isActive}}">2</block>
</tabs>
<!-- 导航栏结束 -->

tabs组件:配合使用slot

<view class="tabs_content">
    <slot ></slot>
</view>

类效果图:
在这里插入图片描述

搜索输入框input事件防抖处理(*想到一个点:hidden对设置了display:flex的元素不起作用)

防抖节流是一个类型的事件处理,百度上有很清晰的答案

timeId:-1,
//输入框input事件
handleInput({detail:{value}}){
  // 防抖
  clearTimeout(this.timeId);
  this.timeId = setTimeout(() => {
    this.search(value.trim());
  }, 1000);
},
//方法
async search(query){
    const res = await request({
      url:'/goods/qsearch',
      data:{query}
    });
    this.setData({
      searchList:res.data.message
    });
}

小程序选择文件和上传文件

  // 选择图片事件
  handleChooseImg(){
    wx.chooseImage({
      count: 9,
      sizeType: ['original','compressed'],
      sourceType: ['album','camera'],
      success: (result)=>{
        // 追加图片
        this.setData({
          imgList:[...this.data.imgList,...result.tempFiles]
        });
      }
    });
  },
imgList.forEach(item=>{
  // 上传文件的api不支持多个文件同时上传,只能遍历
  wx.uploadFile({
    // 服务器路径
    url: '',
    // 文件路径
    filePath: '',
    // 文件名
    name: '',
    // 携带的文本信息
    formData: {},
    success:(result)=>{
      //可以得到外网文件链接  
      console.log(result);
    }
  });
});

小程序登录页面的滑块动画功能

小程序类似登录界面的整体可以往下拉,然后滑动回去(样式也可以绑定);
注意:bind事件支持事件冒泡,catch不支持,所以在真机调试时,使用catch事件

<!-- 测试滑动效果开始 -->
  <view class="moveContainer"
        catchtouchstart='handleTouchStart'
        catchtouchmove='handleTouchMove'
        catchtouchend='handleTouchEnd'
        style="transform:{{coverTransform}};transition:{{coverTransition}}">
    <view class="item">1212</view>
    <view class="item">1212</view>
    <view class="item">1212</view>
    <view class="item">1212</view>
    <view class="item">1212</view>
    <view class="item">1212</view>
  </view>
  <!-- 测试滑动效果结束 -->
data: {
    // 位移距离
    coverTransform:'',
    // 过渡回去的效果
    coverTransition:''
  },
  startY:0,
  moveY:0,
  moveDistance:0,
  endY:0,
  onShow: function () {
    
  },
  // 手指按下
  handleTouchStart(e){
    this.setData({
      coverTransition:''
    });
    this.startY = e.touches[0].clientY;
  },
  // 手指移动
  handleTouchMove(e){
    this.moveY = e.touches[0].clientY;
    this.moveDistance = this.moveY - this.startY;
    if(this.moveDistance >= 120 || this.moveDistance < 0){
      return;
    };
    this.setData({
      coverTransform:`translateY(${this.moveDistance}rpx)`
    });
  },
  // 手指离开回到原点
  handleTouchEnd(e){
    this.setData({
      coverTransform:'translateY(0rpx)',
      coverTransition:'transform 1s linear'
    });
  }

小程序对象名为变量时的setData使用

let type = e.currentTarget.id;
this.setData({
    [type]:e.detail.value
})

使用getApp创建全局数据

/app.js

wx-App({
  globalData:{
    isMusicPlay:'全局数据'
  },
})

/index.js

onShow: function () {
    const app =  getApp();
    console.log(app.globalData.isMusicPlay,'全局数据');
},

小程序结合C3动画案例

  <!-- 测试旋转动画开始 -->
  <view class="rotateContainer rotate">
    <image src="/static/image/logo.jpg"></image>
  </view>
  <!-- 测试旋转动画结束 -->
.rotateContainer{
    margin: 20rpx auto;
    width: 200rpx;
    height: 200rpx;
    image{
        width: 100%;
        height: 100%;
        border-radius: 50%;
    }
}
// 这样即可实现动画动态绑定
.rotate{
    animation: rotate 4s linear infinite;
}
@keyframes rotate{
    from{
        transform: rotate(0deg);
    }
    to{
        transform: rotate(360deg);
    }
}

关于scroll-view

小程序scroll-view中的设置display:flex要设置enable-flex
在这里插入图片描述
两个属性用来设置滚动到第一个并且附加上动画;(见代码)

  <!-- 测试scroll-view及动画开始 -->
  <scroll-view
    class="scrollContainer"
    scroll-x
    enable-flex
    scroll-into-view="n1"
    scroll-with-animation
  >
    <view>111</view>
    <view>2222</view>
    <view id="n1">3333</view>
    <view>4444</view>
    <view>5555</view>
    <view>6666</view>
    <view>7777</view>
    <view>8888</view>
    <view>9999</view>
  </scroll-view>
  <!-- 测试scroll-view及动画结束 -->
.scrollContainer{
    display: flex;
    view{
        padding: 10rpx 30rpx;
    }
}

效果:3333的自然就滚动到最前面

在这里插入图片描述

swiper的露出前后项

在这里插入图片描述

  <!-- 轮播图区域开始-->
  <swiper class="wx_swiper" autoplay circular indicator-dots
      indicator-color="ivery"
      indicator-active-color="#043c33"
      previous-margin="30rpx"
      next-margin="30rpx">
    <swiper-item>
      <image src="/static/image/logo.jpg"></image>
    </swiper-item>
    <swiper-item>
      <image src="/static/image/logo.jpg"></image>
    </swiper-item>
    <swiper-item>
      <image src="/static/image/logo.jpg"></image>
    </swiper-item>
  </swiper>
  <!-- 轮播图区域结束-->
swiper{
    height: 500rpx;
    swiper-item{
        width: 100%;
        text-align: center;
        image{
            width: 96%;
            height: 100%;
        }
    }
}

效果图
在这里插入图片描述

哈哈,又临时想到几个点:

  1. button等有默认padding,margin,包括图片,swiper的样式等
  2. 输入框文本域等赋值(类似vue中v-model的双向数据绑定)
 <input type='text' value="{inputValue}"/> //我们只需要给inputValue赋值即可

3 小程序对于获取data中数据,一般要使用深拷贝比较严谨,但是浅拷贝不影响效果

对于小程序,接下来大家就一顿狂写就好了,多多参考官网就好了。

组件中监听properties中数据的变化

  properties: {
    activeIndex:{
      type:Number,
      default:0
    }
  },
  observers: {
    'activeIndex': function (val) {
      if(val != 0){
        this.setData({
          active:val
        })
      }
    }
  },

获取用户信息(最新接口升级)

<button class="login-btn logOrResgister" type="primary" plain wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile">登录/注册</button>
<button class="login-btn logOrResgister" type="primary" plain wx:else open-type="getUserInfo" bindgetuserinfo="getUserInfo">登录/注册</button>
  onShow: function(){
    if (wx.getUserProfile) {
      this.setData({
        canIUseGetUserProfile: true
      })
    };
  },
  getUserProfile(){
    var that = this;
    wx.getUserProfile({
      lang: "zh_CN",
      desc: "用于互动",
      success: function (res) {
        res.userInfo.id = (Math.random() * 10000);
        that.setData({
          userInfo:res.userInfo
        });
        wx.setStorage({
          key: 'userInfo',
          data: res.userInfo,
        })
      }
    })
  },
  // 开发者工具中使用
  getUserInfo(e) {
    var that = this;
    wx.getSetting({ 
      success: (res) => {
        if (res.authSetting['scope.userInfo']) {
          wx.getUserInfo({
            lang: "zh_CN",
            success: function (res) {
              res.userInfo.id = (Math.random() * 10000);
              that.setData({userInfo:res.userInfo});
              wx.setStorage({
                key: 'userInfo',
                data: res.userInfo
              })
            }
          })
        }
      }
    })
  }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值