微信小程序開發入門教程(四)---自己動手做個小程序


前面已將基礎知識准備的差不多了,下面實際做一個小程序。

一、目標

用於上傳照片和文字。

2個主要頁面:我me,設置set

二、開始制作

1、打開微信開發者工具(我用的1.02.1907160 Windows 64版本),點+號,新建項目diary,選擇目錄E:\wxDEV\diary,填入從微信開發平台申請到的AppID,開發模式默認為小程序,后端服務選擇雲開發,點新建,生成了雲開發QuitStart示例模板。下面在此模板基礎上制作。

2、建立me   set頁面,並給小程序增加tabBar。即修改E:\wxDEV\minishop\miniprogram\app.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:\wxDEV\diary\miniprogram\pages\index\index.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;width:100%;position:fixed;z-index:999;pointer-events:none;">
  <movable-view direction="all" style="height: 30px; line-height:30px;width: 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="width: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="width: 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;width: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="width:100px;"></image>
    </view>
    <view style="width:100%;border-bottom:solid 1px lightgrey;padding-left:10px;"> {{item["content"]}} </view>
  </view>
</block>
<view>
  <image src='../../images/img.jpg' mode="widthFix" style="width: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 {
  width: 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%;
  width: 94%;
  margin-left: 3%;
  margin-top: 15px;
}
.content {
  border-top: 1px solid rgb(247, 247, 247);
  width: 100%;
  margin: 0 auto;
  background-color: #ffff;
}
 
        

參考:授權 https://www.jianshu.com/p/480ff10bfb54

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

 ...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM