美文网首页
小程序的总结和一些坑

小程序的总结和一些坑

作者: butters001 | 来源:发表于2020-11-19 16:08 被阅读0次

    持续更新中

    1. 解决VS Code中小程序的wxml文件的注释是双斜杠
    image-20201021102156036.png

    重启vscode就可以了

    2. vscode安装easy less
    image-20201021102309968.png

    在settings.json中添加如下 "less.compile"

    image-20201021102439281.png
    "less.compile": {
            "compress": false,//是否压缩
            "sourceMap": false,//是否生成map文件,有了这个可以在调试台看到less行数
            "out": true, // 是否输出css文件,false为不输出
            "outExt": ".css", // 输出文件的后缀
           }
    
    3. vscode如何自动格式化代码

    安装插件 Prettier -Code formatter

    image-20201021103905892.png

    在settings.json中添加如下 "editor.formatOnSave": true

    image-20201021102813041.png
    4. 小程序标签绑定点击事件

    .wxml文件

    <view bindtap="changeInputSizeUp">123</view>
    

    .wxss文件

    changeInputSizeUp: function() {
        do something
    }
    
    5. 弹窗时 禁止背景页面滑动操作
    弹框标签添加 catchtouchmove="return"
    <view wx:if="{{isShowConfirm}}" catchtouchmove="return">
    
    6. 输入框标签聚焦或键盘输入时触发
    bindinput 键盘输入时触发 
    bindfocus 输入框聚焦时触发
    <textarea maxlength="70" bindinput='setValue' data-name='stuEidtName'></textarea>
    
    7.日期选择器
    <view class="section">
      <view class="section__title">日期选择器</view>
      <picker mode="date" value="{{date}}" start="2015-09-01" end="2017-09-01" bindchange="bindDateChange">
        <view class="picker">
          当前选择: {{date}}
        </view>
      </picker>
    </view>
    
    bindDateChange: function(e) {
        console.log('picker发送选择改变,携带值为', e.detail.value)
        this.setData({
          date: e.detail.value
        })
      },
    
    8. 文本超出显示省略号
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    
    9. 小程序下拉刷新之后停止下拉框的显示

    加载完数据后添加 wx.stopPullDownRefresh()

    onPullDownRefresh: function () {
        this.loadTodoList();
        wx.stopPullDownRefresh();
      },
    
    10. 给后端服务器发送http请求 支持es7的async await
    1. 跟目录下创建 request/index.js
    // 同时发送异步代码的次数
    let ajaxTimes = 0;
    
    export const request = (params) => {
      ajaxTimes++;
      // 显示加载中loading 效果
      wx.showLoading({
        title: "加载中",
        mask: true,
      });
    
      return new Promise((resolve, reject) => {
        wx.request({
          ...params,
          success: (result) => {
            resolve(result.data);
          },
          fail: (err) => {
            reject(err);
          },
          complete: () => {
            ajaxTimes--;
            if (ajaxTimes === 0) {
              //  关闭正在等待的图标
              wx.hideLoading();
            }
          },
        });
      });
    };
    
    
    1. 根目录下创建 lib/runtime/runtime.js

      regenerator/packages/regenerator-runtime/runtime.js 的代码拷到自己的 runtime.js里

    2. 需要使用async语法的页面js导入 哪个页面使用就哪个页面导入

     import { request } from "../../request/index.js";
     import regeneratorRuntime from "../../lib/runtime/runtime";
     
     async loadTodoList() {
         var that = this;
         var url = "http://127.0.0.1:8000/api/add"
         const result = await request({
           url: url,
           data: this.SubmitParams,
           method: "post",
           header: {
             "Content-Type": "application/x-www-form-urlencoded",
           },
         });
     
         if (result.code == 0) {
           pass
         } else {
           pass
         }
       },
    
    11. 监听用户下拉操作
    // 监听用户下拉操作
      onPullDownRefresh: function () {
        // 1 重置数组
        this.setData({
          todo_show: [],
        });
        // 2 重置页码
        this.SubmitParams.page_num = 1;
        // 3 发送请求
        this.loadTodoList();
        wx.stopPullDownRefresh();
      },
    
    12. 页面上拉触底事件的处理函数 如加载下一页
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function () {
        //  1 判断还有没有下一页数据
        // console.log(this.SubmitParams.page_num, this.totalPages);
        if (this.SubmitParams.page_num >= this.totalPages) {
          // 没有下一页数据
          //  console.log('%c'+"没有下一页数据","color:red;font-size:100px;background-image:linear-gradient(to right,#0094ff,pink)");
          wx.showToast({ title: "没有下一页数据" });
        } else {
          // 还有下一页数据
          //  console.log('%c'+"有下一页数据","color:red;font-size:100px;background-image:linear-gradient(to right,#0094ff,pink)");
          this.SubmitParams.page_num++;
          this.loadTodoList();
        }
      }
    
    13. 出现遮罩层后禁止背景页面上下拉动
    image-20201023165326893.png

    在遮罩层的标签中添加 catchtouchmove="noneEnoughPeople" 注意:在开发平台上可能不起效果 在手机上测试会起作用

    image-20201023165431724.png
    14. button透明 放到图片或view等标签下面

    .login_btn 就是button按钮 放到了.user_icon标签下面了

     .user_icon {
            position: relative;
            width: 120rpx;
            height: 120rpx;
            border-radius: 50%;
            .login_btn {
              position: absolute;
              top: 0;
              left: 0;
              width: 120rpx;
              height: 120rpx;
              border-radius: 50%;
              opacity: 0;
            }
    
    15. 下面的标签 部分压住上面的标签效果实现
    image-20201024155835179.png
    // 下面的白色标签 要绝对定位 然后 top指定为负数
    .user_content {
      position: relative;
      .user_business_info_wrap {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        top: -40rpx;
        width: 94.6%;
        height: 100rpx;
        background-color: #ffffff;
      }
    }
    
    16. async a函数 在别的函数b里需要同步调用

    给b变成async 然后在调用a前await一下

    async a() {
        ......
    }
    
    async b() {
      // 如果不添加await a() 和 other执行顺序不定 会出现问题
        await a();
        do other......
    }
    
    17. 外部this不能被success内部使用问题
    image-20201027101722625.png
    18. 小程序登陆功能

    小程序调用 wx.login({}) success后请求后端的登陆接口 将wx.login返回的 res.code 传给后端使用

    后端服务器的login接口 去请求微信接口(需要code参数),将返回的用户wx_token存储到数据库 用来当作用户的身份验证

    ​ 可以将wx_token进行编码或加密 md5或base64

    image-20201109113006182.png

    auth.js

      authLogin(nickName) {
        wx.login({
          success: (res) => {
            if (res.code) {
              //发起网络请求
              var backend_url = app.globalData.backend_url;
              var url = backend_url.base_url + backend_url.login;
              wx.request({
                url: url, //仅为示例,并非真实的接口地址
                data: {
                  code: res.code,
                  nickName: nickName,
                },
                header: {
                  "content-type": "application/json", // 默认值
                },
                success: (res) => {
                  if (res.data.code === 0) {
                    // 登陆成功
                  }
                },
              });
            }
          },
        });
      },
    

    auth.py

    def login(request):
        try:
            code = request.GET.get('code')
            nick_name = request.GET.get('nickName')
            url = "https://api.weixin.qq.com/sns/jscode2session?" \
                  "appid=%s&secret=%s&js_code=%s&grant_type=authorization_code" % ("xxxxxx",
                                                                                   "xxxxxx",
                                                                                   code)
            result = requests.get(url)
            result = result.json()
            open_id = result['openid']
    
            wx_token = "对open_id进行加密"
    
            session_key = result['session_key']
            user, _ = User.objects.update_or_create(wx_token=wx_token,
                                                    defaults={'session_key': session_key,
                                                              'username': wx_token,
                                                              'nick_name': nick_name,
                                                              'open_id': open_id})
    
        except Exception as e:
            logger.error(e)
            return JsonResponse({'code': 1, 'message': '服务器异常,请联系管理员'})
        return JsonResponse({'code': 0, 'wx_token': wx_token, 'user_id': user.id})
    
    19. 下载excel

    小程序发起下载请求,后端服务器生成excel 返回给小程序excel的网络地址

    然后小程序请求这个网络地址进行下载 wx.downloadFile( ) +wx.openDocument( )

    wx.downloadFile({
      // 示例 url,并非真实存在
      url: 'http://example.com/somefile.pdf',
      success: function (res) {
        const filePath = res.tempFilePath
        wx.openDocument({
          filePath: filePath,
          success: function (res) {
            console.log('打开文档成功')
          }
        })
      }
    })
    
    20. 七牛云接口存储图片
    from PIL import Image
    from qiniu import Auth, put_data
    from qiniu import BucketManager
    
    AK = "七牛云 ak"
    SK = "七牛云 secret_ky"
    # 构建鉴权对象
    q = Auth(AK, SK)
    # 要上传的空间
    bucket_name = 'aaaaa'
    
    
    # 七牛云上传图片
    def upload_file(localfile):
        try:
            m = hashlib.md5()  # 括号内也可以传值,类型也要求是bytes类型
            key = 'df' + str(int(time.time())) + str(random.randint(10000, 100000))
            m.update(key.encode('utf-8'))
    
            # 上传后保存的文件名
            key = m.hexdigest() + '.jpg'
            # 生成上传 Token,可以指定过期时间等
            token = q.upload_token(bucket_name, key, 3600)
            ret, info = put_data(token, key, localfile)
            if info.status_code == 200:
                sign_url = "http://qjbb5wdkg.hb-bkt.clouddn.com/" + key
                return sign_url
        except Exception as e:
            logger.error(e)
    
    
    # 七牛云删除图片
    def delete_file(key):
      """
      只需要传名字就行xxx.jpg 不需要传域名路径
      """
        try:
            # 初始化BucketManager
            bucket = BucketManager(q)
    
            # 你要测试的空间, 并且这个key在你空间中存在
            # 删除bucket_name 中的文件 key
            ret, info = bucket.delete(bucket_name, key)
    
            assert ret == {}
        except Exception as e:
            logger.error(e)
    
    # 视图函数
    def upload_view(request):
        sign_pic = request.FILES.get('sign_pic')
    
        im_pic = Image.open(sign_pic)
        # im_pic = im_pic.transpose(Image.ROTATE_90)  # 引用固定的常量值 旋转90度 非必须
        # 创建一个字节流管道
        img_bytes = io.BytesIO()
        # 将图片数据存入字节流管道, format可以按照具体文件的格式填写
        im_pic.save(img_bytes, format="PNG")
        # 从字节流管道中获取二进制
        image_bytes = img_bytes.getvalue()
        url = upload_file(image_bytes)
        
        delete_file(url.split('/')[-1])
    
    21. 盒子阴影

    直接在标签里加入css名 <div class="shadow"></div>

    /* 盒子阴影 */
    .shadow {
      position: relative;
      max-width: 100%;
      box-shadow: 0px 1.5px 3px rgba(0, 0, 0, 0.3),
        0px 0px 20px rgba(0, 0, 0, 0.1) inset;
    }
    
    .shadow::before,
    .shadow::after {
      content: "";
      position: absolute;
      z-index: -1;
    }
    
    .shadow::before,
    .shadow::after {
      content: "";
      position: absolute;
      z-index: -1;
      bottom: 15px;
      left: 10px;
      width: 50%;
      height: 20%;
    }
    
    .shadow::before,
    .shadow::after {
      content: "";
      position: absolute;
      z-index: -1;
      bottom: 15px;
      left: 10px;
      width: 50%;
      height: 20%;
      box-shadow: 0 10px 7px rgba(0, 0, 0, 0.7);
      transform: rotate(-3deg);
    }
    
    .shadow::after {
      right: 10px;
      left: auto;
      transform: rotate(3deg);
    }
    
    22. 点击订阅功能
    index.wxml
    <!-- 订阅开关 -->
    <image
      class="sub_status"
      src="xxxxxx"
      mode="widthFix"
      bindtap="subContentBtn"
      data-itemid="{{item.id}}"
      data-userid="{{item.user_id}}"
      data-idx="{{idx}}"
      data-endtime="{{item.end_time}}"
      data-subscribe="{{item.subscribe_status}}"
    ></image>
    
    index.js
    
    // 点击订阅
    subContentBtn(e) {
     wx.showModal({
          title: "提示",
          content: "订阅此条记录?",
          showCancel: true,
          cancelText: "取消",
          cancelColor: "#000000",
          confirmText: "确定",
          confirmColor: "#3CC51F",
          success: (result4) => {
            if (result4.confirm) {
              wx.requestSubscribeMessage({
                tmplIds: ["订阅模版id"],
                success: (res) => {
                  if (res["订阅模版id"] ==="accept") {
                    // 发送请求
                    this.sendSub(
                      url,
                      {
                        id: item_id,
                        subscribe_status: subscribe_status,
                      },
                      index
                    );
                  }
                },
                fail(err) {
                  console.error(err);
                },
              });
            }
          },
        });
    
      
      // 请求订阅接口
      async sendSub(url, params, index) {
        const result = await request({
          url: url,
          data: params,
        });
        if (result.code == 0) {
          wx.showToast({
            title: "操作成功",
            icon: "success",
            duration: 2000,
            mask: true,
            success: (result) => {},
          });
        } else {
          wx.showToast({
            title: result.message,
          });
        }
      },
    
    23. 保存图片到本地 和 图片预览
    //保存到相册
    async saveCanvasAsImg() {
      try {
        // 1 获取 权限状态
        const res1 = await getSetting();
        const scopewritePhotosAlbum = res1.authSetting["scope.writePhotosAlbum"];
        // 2 判断 权限状态
        if (scopewritePhotosAlbum === false) {
          await openSetting();
        }
    
        wx.canvasToTempFilePath({
          canvasId: "handWriting",
          fileType: "png",
          quality: 1, //图片质量
          success(res) {
            // console.log(res.tempFilePath, 'canvas生成图片地址');
            wx.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success(res) {
                wx.showToast({
                  title: "已保存到相册",
                  duration: 2000,
                });
              },
              fail: function (res) {
                console.log(res);
                if (res.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
                  console.log("打开设置窗口");
                }
              },
            });
          },
        });
      } catch (error) {
        console.log(error);
      }
    },
    
      //预览
      previewCanvasImg() {
        wx.canvasToTempFilePath({
          canvasId: "handWriting",
          fileType: "jpg",
          quality: 1, //图片质量
          success(res) {
            // console.log(res.tempFilePath, 'canvas生成图片地址');
    
            wx.previewImage({
              urls: [res.tempFilePath], //预览图片 数组
            });
          },
        });
      },
    
    24. 长按保存
    wxml文件
    
    <image
         wx:if="{{item.status!='审核中'}}"
         data-url="{{item.sign_url}}"
         bindlongpress="saveImage"
         bindtap="imagePreview"
         class="signUrl"
         src="{{item.sign_url}}"
         mode="widthFix"
        />
    
    js文件  
    
    //单击图片预览
    imagePreview: function (e) {
      var current = e.target.dataset.url; //这里获取到的是一张本地的图片
      wx.previewImage({
        current: current, //需要预览的图片链接列表
        urls: [current], //当前显示图片的链接
      });
    },
    
      // 长按保存图片
      saveImage(e) {
        let url = e.currentTarget.dataset.url;
        //用户需要授权
        wx.getSetting({
          success: (res) => {
            if (!res.authSetting["scope.writePhotosAlbum"]) {
              wx.authorize({
                scope: "scope.writePhotosAlbum",
                success: () => {
                  // 同意授权
                  this.saveImg1(url);
                },
                fail: (res) => {
                  console.log(res);
                },
              });
            } else {
              // 已经授权了
              this.saveImg1(url);
            }
          },
          fail: (res) => {
            console.log(res);
          },
        });
      },
    
        saveImg1(url) {
          wx.getImageInfo({
            src: url,
            success: (res) => {
              let path = res.path;
              wx.saveImageToPhotosAlbum({
                filePath: path,
                success: (res) => {
                  console.log(res);
                  wx.showToast({
                    title: "图片保存成功",
                    icon: "success",
                    duration: 2000,
                    mask: true,
                  });
                },
                fail: (res) => {
                  console.log(res);
                },
              });
            },
            fail: (res) => {
              console.log(res);
            },
          });
        },
    
    25. 获取用户信息

    必须指定 open-type="getUserInfo"

    wxml文件
    
    <button
      class="login_btn"
      type="primary"
      plain
      open-type="getUserInfo"
      bindgetuserinfo="handleGetUserInfo"
      >
    
      js文件
      
      handleGetUserInfo(e) {
        // console.log(e);
    
        const { userInfo } = e.detail;
        wx.setStorageSync("user_info", userInfo);
        this.setData({
          user_info: userInfo,
        });
        this.authLogin(userInfo.nickName);
      },
    
    26. 获取当前页面的route
    let pages = getCurrentPages();
    let currPage = null;
    // console.log(pages) 的到一个数组
    if (pages.length) {
    // 获取当前页面的对象(上边所获得的数组中最后一项就是当前页面的对象)
     currPage = pages[pages.length - 1];
     }
    // 获取当前页面的路由 /pages/index/index
    let route = currPage.route;
    
    27. app.js里添加定时任务 在小程序运行期间一直定时执行
    onLaunch: function () {
        var that = this;
        setInterval(that.showActionHistory, 5000);
      },
    
    28. 小程序设置tabBar右上角添加文本/移除文本样式
    wx.setTabBarBadge({
              index: 2,
              text: '设置文本内容',
            })
    
    //移除taBar右上角的文本
    wx.removeTabBarBadge({
              index: 2, //tabBar下标
            })        
    
    29. setTimeout 里无法调用this.setData问题

    使用that或箭头函数

    
    var that = this;
    setTimeout(function () {
          that.setData({
            is_todo_pk_btn_disabled: false,
            is_todo_pk_img: false,
            is_todo_result: true,
          });
        }, 8000);
    
    // 或者
    setTimeout(() => {
          this.setData({
            is_todo_pk_btn_disabled: false,
            is_todo_pk_img: false,
            is_todo_result: true,
          });
        }, 8000);
    
    30. 如果有用户自定义上传文本或图片的地方 需要进行内容的审核 否则上线不通过

    请求微信接口对内容进行审核, 但是文档有点坑

    1. 返回值是 errmsg 而不是文档写的 errMsg
    2. 不能直接requests.post(url, data=data) 这样会一直返回ok,要对data进行处理,如下代码可以正常运行
    data = {'content': '特3456书yuuo莞6543李zxcz蒜7782法fgnv级'}
    requests.post(url, data=json.dumps(data, ensure_ascii=False).encode(), headers={'content-type': 'application/json'})
    

    相关文章

      网友评论

          本文标题:小程序的总结和一些坑

          本文链接:https://www.haomeiwen.com/subject/twhliktx.html