zoukankan      html  css  js  c++  java
  • 微信小程序开发入门教程(四)---自己动手做个小程序

    前面已将基础知识准备的差不多了,下面实际做一个小程序。

    一、目标

    用于上传照片和文字。

    2个主要页面:我me,设置set

    二、开始制作

    1、打开微信开发者工具(我用的1.02.1907160 Windows 64版本),点+号,新建项目diary,选择目录E:wxDEVdiary,填入从微信开发平台申请到的AppID,开发模式默认为小程序,后端服务选择云开发,点新建,生成了云开发QuitStart示例模板。下面在此模板基础上制作。

    2、建立me   set页面,并给小程序增加tabBar。即修改E:wxDEVminishopminiprogramapp.json并保存。代码如下:

    {
      "pages": [
        "pages/index/index",
        "pages/me/me",
        "pages/people/people",
        "pages/set/set"
      ],
      "window": {
        "backgroundColor": "#F6F6F6",
        "backgroundTextStyle": "light",
        "navigationBarBackgroundColor": "#F6F6F6",
        "navigationBarTitleText": "日记",
        "navigationBarTextStyle": "black"
      },
      "tabBar": {
        "backgroundColor": "#eeeeee",
        "position": "bottom",
        "list": [
          {
            "pagePath": "pages/me/me",
            "text": "",
            "iconPath": "images/img.jpg",
            "selectedIconPath": "images/img.jpg"
          },     
          {
            "pagePath": "pages/set/set",
            "text": "设置",
            "iconPath": "images/img.jpg",
            "selectedIconPath": "images/img.jpg"
          }
        ]
      },
      "sitemapLocation": "sitemap.json"
    }
    同时,要在images目录中放置一张img.jpg图片(我自己画了一张)

    3、我打算将现有的index页作为将来的splash页。所以先修改E:wxDEVdiaryminiprogrampagesindexindex.js,以实现2秒后跳转me页,代码:

    //index.js
    
    Page({
      data: {},
    
      onLoad: function() {
        setTimeout(function() {
          wx.reLaunch({
            url: '../me/me',
          })
        }, 2000)
    
      }
    })

    4、修改me页(为方便调试,可更改app.json中pages值的顺序,将me调整到前面)。原本想在me页上用movable-view增加可拖动的按钮样式,如下: 

    <!--可拖动按钮-->
    <movable-area style="height:{{mHeight}}px;100%;position:fixed;z-index:999;pointer-events:none;">
      <movable-view direction="all" style="height: 30px; line-height:30px; 30px; margin-left:100%; border:2px solid lightblue;border-radius:50%;">
        <cover-view bindtap="writeDiary">      
          <cover-image  src='../../images/img.jpg'></cover-image>
        </cover-view>
      </movable-view>
    </movable-area>

    结果在安卓真机上出现兼容性问题,拖动时cover-view瞬间移动,而cover-image不跟随移动,无法正常工作。(谁知道解决办法给我讲一下?)只好弃用。 

    云开发的云函数的独特优势在于与微信登录鉴权的无缝整合,参考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/userinfo.html

    所以,对不同用户上传内容可以用openid区分。

    5.半成品的me.wxml ,代码如下:

    <!--pages/me/me.wxml-->
    <view style="display:flex;flex-direction: row-reverse;margin-right:20px;font-size:150%;"><text bindtap="writeDiary">{{inputCursor}}</text></view>
    
    <view style="100%;">
      <!-- 上传图片 -->
      <view class="uploader">
        <view class="uploader-text" bindtap="selPic">
          <text>拍照或选择图片(可选)</text>
        </view>
        <view class="uploader-container" wx:if="{{imgUrl}}">
          <image class="uploader-image" src="{{imgUrl}}" mode="aspectFit" bindtap="previewImg"></image>
        </view>
      </view>
      <!-- 表单 -->
      <form class="formpub" bindsubmit="formSubmit" bindreset="formReset">
        <!-- 保存图片临时路径 -->
        <view class="section">
          <input name="img" value="{{imgUrl}}" hidden="true" />
        </view>
    
        <view class="content">
          <view class="currentWordNumber">{{currentWordNumber|0}}/{{max}}</view>
          <!-- 别忘了给textarea加上name属性 -->
          <textarea name="diaryContent" bindblur="getText" bindinput="getValueLength" show-confirm-bar='true' value="{{editText}}" bindconfirm="getText" maxlength="{{max}}" minlength="{{min}}" placeholder="内容..." auto-focus>
            <text class="minWord">{{minWord}}</text>
          </textarea>
        </view>
        <view class="tips">在上面填写内容</view>
    
        <view class="btn-area">
          <button form-type="submit" style=" 80%; margin-top: 20rpx;background-color: beige;color: black;border:2px solid lightblue;">写完了</button>
        </view>
      </form>
    </view>
    
    <block wx:for="{{diarys}}" wx:key="{{index}}">
      <view style="display:flex;100%;min-height:50px;background:rgb(248, 248, 248);margin:8px;">
        <view style="border:20px;">
          <image wx:if='{{item["img"]}}' src='{{item["img"]}}'mode="widthFix" style="100px;"></image>
        </view>
        <view style="100%;border-bottom:solid 1px lightgrey;padding-left:10px;"> {{item["content"]}} </view>
      </view>
    </block>
    <view>
      <image src='../../images/img.jpg' mode="widthFix" style="50px"></image>
    </view>

    me.js

    // pages/me/me.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        //以下变量也可以不写在这里,可直接在代码中声明和使用,但推荐写在这里
        mHeight: 500,
        hiddenInput: true,
        inputCursor: '+',
        max: 2000, //限制最大输入字符数
        min: 10, //限制最小输入字符数
        minWord: '', //提示语句
        imgUrl: '', //要上传的图片的url
        editText: '', //textarea中编辑的内容
        diarys: {},
        curPage: 1
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function(options) {
    
      },
    
      //写日记
      writeDiary: function() {
        let tempCursor = ''
        if (this.data.inputCursor == '+') {
          tempCursor = '-'
        } else {
          tempCursor = '+'
        }
        this.setData({
          hiddenInput: !this.data.hiddenInput,
          inputCursor: tempCursor
        })
        //滚动视口,返回顶部
        wx.pageScrollTo({
          scrollTop: 0,
          duration: 300
        })
      },
      /****限制字数与计算 */
      getValueLength: function(e) {
        let value = e.detail.value
        let len = parseInt(value.length)
        //最少字数限制
        if (len <= this.data.min)
          this.setData({
            minWord: "至少填写10个字哦~"
          })
        else if (len > this.data.min)
          this.setData({
            minWord: " "
          })
        //最多字数限制
        if (len > this.data.max) return;
        this.setData({
          currentWordNumber: len //当前字数 
        })
      },
      formSubmit: function(e) {
        console.log('form发生了submit事件,携带数据为:', e.detail.value)
        let upDiaryContent = e.detail.value["diaryContent"]
        let upimgUrl = e.detail.value["img"]
        let len = parseInt(upDiaryContent.length)
        //最少字数限制
        if (len <= this.data.min) {
          this.setData({
            minWord: "至少填写10个字哦~"
          })
          return
        }
        wx.showLoading({
          title: '请等待',
        })
        //判断有无图片
        if (typeof upimgUrl == "undefined" || upimgUrl == null || upimgUrl == "") {
          //没有图片,直接上传文字
          const db = wx.cloud.database()
          db.collection('diarys').add({
            data: {
              content: upDiaryContent
            },
            success: res => {
              //无图,文字上传成功了    
              this.reset()
              console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
            },
            fail: err => {
              wx.showToast({
                icon: 'none',
                title: '新增记录失败'
              })
              console.error('[数据库] [新增记录] 失败:', err)
            }
    
          })
        } else { //有图片,则先上传图片               
          const timestamp = new Date().getTime();
          const relCloudPath = 'diarys/' + timestamp + upimgUrl.match(/.[^.]+?$/)[0]
          console.log(1)
          console.log(upimgUrl)
          console.log(relCloudPath)
          wx.cloud.uploadFile({
            cloudPath: relCloudPath,
            filePath: upimgUrl,
            success: res => {
              console.log('[上传文件] 成功:', res)
              let imgFileID = res.fileID
              //再上传文字
              const db = wx.cloud.database()
              db.collection('diarys').add({
                data: {
                  img: imgFileID,
                  content: upDiaryContent
                },
                success: res => {
                  //文字也上传成功了     
                  this.reset()
                  console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
                },
                fail: err => {
                  //文字上传失败
                  wx.showToast({
                    icon: 'none',
                    title: '新增记录失败'
                  })
                  console.error('[数据库] [新增记录] 失败:', err)
                }
              })
            },
            fail: e => {
              console.error('[上传文件] 失败:', e)
              wx.showToast({
                icon: 'none',
                title: '上传失败',
              })
            }
          })
        }
        //图片和文字全部上传了。
        wx.hideLoading()
      },
      // 选择图片
      selPic: function() {
        var that = this
        wx.chooseImage({
          count: 1,
          sizeType: ['compressed'],
          sourceType: ['album', 'camera'],
          success: function(res) {
    
            wx.showLoading({
              title: '请等待',
            })
    
            const imgfilePath = res.tempFilePaths[0]
            that.setData({
              imgUrl: imgfilePath
            })
    
          },
          fail: e => {
            this.setData({
              imgUrl: ''
            })
            //console.error(e)
          },
          complete: () => {
            wx.hideLoading()
          }
        })
      },
      //重置
      reset: function() {
        let tempCursor = ''
        if (this.data.inputCursor == '+') {
          tempCursor = '-'
        } else {
          tempCursor = '+'
        }
        this.setData({
          'imgUrl': '',
          'editText': '',
          'hiddenInput': !this.data.hiddenInput,
          minWord: '',
          inputCursor: tempCursor
        })
      },
      // 查询当前用户的数据库集合,暂时没用
      onQuery: function(p) {
        const db = wx.cloud.database()
        db.collection('diarys').skip(p)
          .get()
          .then(res => {
            console.log(res.data)
            console.log(res.data[0].img)
          })
          .catch(console.error)
      },
    
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function() {
        wx.getSystemInfo({
          success: res => {
            let h = res.windowHeight
            //取20条数据
            const db = wx.cloud.database()
            db.collection('diarys')
              .get()
              .then(res => {
                this.setData({
                  mHeight: h,
                  diarys: res.data
                })
                console.log(res.data)
                console.log(res.data[5].img)
              })
              .catch(console.error)
          },
        })
    
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function() {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function() {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload: function() {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function() {
    
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function() {
    
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function() {
    
      }
    })

    me.wxss

    /* pages/me/me.wxss */
    .currentWordNumber {
      height: 35px;
      line-height: 35px;
      font-size: 14px;
      float: right;
      margin-right: 15px;
      color: rgba(136, 136, 136, 1);
      margin-bottom: 10px;
    }
    .minWord {
      color: rgb(248, 248, 248);
      font-size: 14px;
      position: absolute;
      top: 30px;
    }
    .tips {
       96%;
      margin-left: 2%;
      height: 45px;
      color: rgba(136, 136, 136, 1);
      font-size: 14px;
      margin-top: 15px;
      text-align: left;
      font-family: PingFangSC-regular;
    }
    textarea {
      min-height: 500rpx;
      max-height: 500rpx;
      padding: 10rpx 10rpx;
      font-size: 100%;
       94%;
      margin-left: 3%;
      margin-top: 15px;
    }
    .content {
      border-top: 1px solid rgb(247, 247, 247);
       100%;
      margin: 0 auto;
      background-color: #ffff;
    }
    
    

    参考:授权 https://www.jianshu.com/p/480ff10bfb54

    textarea https://blog.csdn.net/ChibiMarukoChan/article/details/88659746

     ...

     

  • 相关阅读:
    爬虫案例
    伪静态
    HTTP0.9、HTTP1.0、HTTP1.1、HTTP2的区别
    正向代理和反向代理
    数据结构继承
    APP 爬虫
    算法基础
    matplotlib
    Java类加载机制及自定义加载器
    SpringBoot war包部署到Tomcat服务器
  • 原文地址:https://www.cnblogs.com/pu369/p/11398114.html
Copyright © 2011-2022 走看看