小程序初體驗:仿好奇心雜誌小程序

小程序初體驗:仿好奇心雜誌小程序

1.前言

  最近在學習小程序,瞭解的越多,就越想本身也動手實現一個,所謂學以至用嗎,正巧最近也看到一個挺有趣,並且看起來也挺簡潔大方的一個小程序--"好奇心雜誌",便想着本身去模仿寫一個.結果還行,就是碰巧最近比較忙,因此最後寫的挺倉促的,不過整體仍是達到了我預計的目標.前端

1-1.這是最終的成果:

git項目地址:好奇心 git

2.目錄基本結構

|--Qdaily 項目名
    |--cloudfunctions 雲函數
        |--Dianzan 點贊函數
        |--addComment 增長評論函數
        |--addReply 增長回覆的評論函數
        |--getComment  得到評論的內容
        ......
    |--miniprogram 項目
        |--componenets  組件模塊
            |--LABSCover 話題的封面組件
            |--comment 評論組件
            |--vote 投票選項組件
            ......
        |--pages  頁面
            |--index 主界面
            |--votes 投票界面
            |--dataAnalysis 投票結果頁面
            |--comment-detail 二級評論頁面
            ......
        |--images 項目圖片
        app.js 全局設置
        app.json
        app.wxss
        ......
        
        
複製代碼

3.界面設計

  做爲一個前端學習者,切圖固然是必不可少的,因此我最早作的事就是把這個小程序的界面繪製出來: github

以上的頁面就基本是我這個小程序的全部頁面了,接下來給你們大概介紹一下每一個頁面的基本wxml介紹(因爲頁面大部分使用了組件,因此你們可能看不到太多的...,若是想看...能夠去個人 代碼倉庫查看對應的組件代碼):

3-1.入口頁面

<view class='main'>
  <view class='logo'>
    <image class='q' src='../../images/q.png'></image>
    <image class='text' src='../../images/ribao.png'></image>
  </view>
  
  <view class='btn'>
    <image class='left' src='../../images/left.png'></image>
    <button class='getuserinfoBtn' bindtap='goindex' wx:if="{{haveInfo}}">好奇驅動你的世界</button>
    <!--獲取用戶信息按鈕-->
    <button class='getuserinfoBtn' open-type='getUserInfo' bindgetuserinfo="bindGetUserInfo" wx:else>好奇驅動你的世界</button>
    <image class='right' src='../../images/right.png'></image>
  </view>
  
</view>
複製代碼

3-2.主頁面之文章列表頁面

<!--導航條-->
<view class="navbar">
  <text wx:for="{{navbar}}" data-idx="{{index}}" class="item {{currentTab==index ? 'active' : ''}}" wx:key="unique" bindtap="navbarTap">{{item}}</text>
</view>
<view hidden="{{currentTab!==0}}" >
    <!--調用swiper組件-->
    <mySwiper></mySwiper>
    <view class='msg' wx:for="{{message}}" wx:key="{{index}}">
      <!--調用文章列表組件-->
      <msg message="{{item}}" index="{{index}}" bindtap="goDesc" data-id="{{item._id}}"></msg>
    </view>
  </view>
複製代碼

3-3.文章詳情頁面

<!--頂部圖片-->
<image class='headImg' src='{{Msg.headImg}}'></image>
  <view class='text'>
    <!--標籤-->
    <view class='label'>
      <image class='labelImg' src='../../images/bicycle.png'></image>
      <view class='labelText'>{{Msg.label}}</view>
    </view>
    <!--文章標題-->
    <view class='title'>{{Msg.title}}</view>
    <!--做者信息-->
    <view class='author'>
      <image class='authorImg' src='../../images/authorImg.png'></image>
      <view class='authorName'>{{Msg.author}}</view>
      <view class='time'>{{Msg.time}}</view>
    </view>
    <!--文章描述-->
    <view class='msgdesc'>
      <view class='desc'>{{Msg.desc}}</view>
    </view>
    <!--文章內容-->
    <text class='message' space="emsp">{{Msg.msgDesc}}</text>
  </view>
  <!--按鈕-->
  <image bindtap='isShow'  class="menuImg {{isShow==true?'menu2':''}}" src='../../images/menu.png'></image>
  <view class="menu {{isShow==true?'menu1':''}}">
      <view class='pub' bindtap='goMsgComment'>
        想說說 <image class='Img' src='../../images/pinglun.png'></image>
      </view>
      <view class='pub' bindtap='dinazan'>
        還不錯 <image class='Img' wx:if="{{Msg.bool}}" src='../../images/dmz1.png'></image>
              <image class='Img' wx:else  src='../../images/dmz.png'></image>
      </view>
      <view class='pub'>
        給他(她)看 <image class='Img' src='../../images/share.png'></image>
      </view>
      <button class='share' open-type="share"> </button>
  </view>
複製代碼

3-4.主頁面之投票列表頁面

<view  hidden="{{currentTab!==1}}" wx:for="{{topic}}" wx:key="{{index}}">
    <!--調用投票列表組件-->
    <LABSCover bindtap='goVotes'
               userNum="{{item.userNum}}" 
               tpImg="{{tpImg}}" 
               coverImg="{{item.topicImage}}" 
               title="{{item.topicTitle}}" 
               desc="{{item.topicDesc}}" 
               data-id='{{item._id}}'
               data-index = '{{index}}'
               index = "{{index}}">
    </LABSCover>
  </view>
複製代碼

3-5.投票選項頁面

<!--投票封面組件-->
<LABSCover coverImg="{{oneTopic[0].topicImage}}" title="{{oneTopic[0].topicTitle}}" desc="{{oneTopic[0].topicDesc}}" userNum="{{oneTopic[0].userNum}}" index = "{{index}}"></LABSCover>
  <view class='options'>
    <view wx:for="{{voteOption}}" wx:key="{{index}}">
      <!--投票選項界面-->
      <vote bind:checked="_checked" data-id="{{item._id}}" optionDesc="{{item.optionDesc}}" optionImg="{{item.optionImg}}"></vote>
    </view>
    <!--投票圖片按鈕-->
    <image class="voteButton {{checked > 0 ? 'voteButtonAdd' : ''}}" src='../../images/tpbutton.png'
           bindtap="vote" data-id='{{topicId}}'
    ></image>
  </view>
  <view class='comment'>
      <view class='commentHead'>
        <view class='commentNum'>{{commentNum}}條評論</view>
        <view class='commentBtn' bindtap='discussAct'><image src='../../images/comment.png'></image></view>
      </view>

      <view wx:for="{{comment}}" wx:key="{{index}}"> 
        <!--評論數據-->
        <comment bind:dianzan="_dianzan" bind:twoComment="_twoComment" bool="{{item.bool}}" zan_num="{{item.DZ_num}}" headImg="{{item.avatarUrl}}" uesrname="{{item.nickName}}" commentTime="{{item.time}}" commentDesc="{{item.commentText}}" data-id="{{item._id}}" data-index="{{index}}">
        </comment>
      </view>
      
      <view class='nomore'>
        <text class='nomoreText'>沒有更多了</text>
      </view>
      <!--評論框-->
      <view class='inputComment' wx:if="{{discussShow}}">
        <textarea class='myComment' 
                  value='{{commentText}}'
                  bindinput="onCommentTextChange"
                  cursor-spacing='20rpx' 
                  fixed='true' maxlength='50' 
                  auto-focus='true' 
                  auto-height='true' 
                  placeholder='我要評論'>
        </textarea>
        <text class='sendBtn' bindtap='addComment' >評論</text>
      </view>
   </view>
複製代碼

3-6.投票結果頁面

<!--頭部圖片-->
<view class='head' >
    <image class='lastImg' src='{{lastImg}}'></image>
    <view class='text'>
      <text class='headTitle'>{{headTitle}}</text>
      <text class='commentTitle'>{{commentTitle}}</text>
    </view>
</view>
<!--分析結果展現-->
<view class='options'>
    <text class='title'>你們的態度</text>
    <view wx:for="{{voteOption}}" wx:key="{{index}}">
      <proportion proSelected="{{item.selected}}" proImg="{{item.optionImg}}" proNum="{{filter.numberToFix((item.optionNum / sum)*100)}}" voteDesc="{{item.optionDesc}}"></proportion>
    </view>
</view>
複製代碼

3-7.發表想法頁面

<view>
<!--調用封面組件-->
  <LABSCover coverImg="{{oneTopic[0].topicImage}}" title="{{oneTopic[0].topicTitle}}" desc="{{oneTopic[0].topicDesc}}" userNum="{{oneTopic[0].userNum}}" index = "{{index}}"></LABSCover>

  <view class='talk'>
    <!--當前用戶編輯框-->
    <view class='manage one' bindtap='goEdit'>
      <view class='user'>
        <image class='userImg' src='{{userInfo.avatarUrl}}'></image>
        <view class='userName'>{{userInfo.nickName}}</view>
      </view>
      <view class='edit'>
        <image class='pen' src='../../images/pen.png'></image>
        <view class='editText'>說點什麼</view>
      </view>
    </view>
    <!--全部用戶的話題展現框-->
    <talkBox wx:for="{{talkBox}}" wx:key="{{index}}" talk="{{item}}"></talkBox>
  </view>
</view>
複製代碼

3-8.編輯想法頁面

<view class='inputComment'>
  <!--文本編輯區-->
  <textarea style='height:500rpx;'
            class='myComment' 
            value='{{commentText}}'
            contenteditable="true" 
            bindinput="onCommentTextChange"
            cursor-spacing='20rpx' 
            fixed='true' maxlength='50' 
            auto-focus='true' 
            placeholder='我想說...'>
  </textarea>
  <!--存放要發表圖片的盒子-->
  <image class='photoImg' src='{{image}}'></image>
  <view class='icon'>
    <!--經過照相機上傳照片-->
    <image class='camera img' src='../../images/camera.png' bindtap='camera'></image>
    <!--經過本地相冊上傳照片-->
    <image class='photo img' src='../../images/photo.png' bindtap='photo'></image>
    <!--上傳按鈕-->
    <text class='sendBtn' bindtap='addspeak' >發表</text>
  </view>
</view>
複製代碼

3-9.二級評論點贊頁面

<!--調用評論組件-->
<twoComment bind:dianzan="_dianzan" bind:reply="discussAct" mainComment="{{mainComment}}" data-id="{{mainComment._id}}"></twoComment>
<!--回覆區內容-->
<view class='replyComment'>
  <view class='replyNum' wx:if="{{replyNum > 0}}">回覆({{replyNum}})</view>
  <view wx:for="{{replyComment}}" wx:key="{{index}}">
    <twoComment bind:dianzan="_dianzan" bind:reply="replydiscussAct" mainComment="{{item}}" data-id="{{item._id}}" data-name="{{item.nickName}}" data-index="{{index}}"></twoComment>
  </view>
</view>
<!--評論內容輸入框-->
<view class='inputComment' wx:if="{{discussShow}}">
  <textarea class='myComment' 
            value='{{commentText}}'
            bindinput="onCommentTextChange"
            cursor-spacing='20rpx' 
            fixed='true' maxlength='50' 
            auto-focus='true' 
            auto-height='true' 
            placeholder='回覆'>
  </textarea>
  <text class='sendBtn' bindtap='addComment' >回覆</text>
</view>
複製代碼

4.雲開發

  完成界面繪製以後,此時就須要用數據將頁面渲染出來,由於小程序自身就帶雲函數和雲數據庫等功能,且操做起來很簡單,讓開發者無需管理後端服務架構,便可輕鬆擁有各類後端能力,極大減輕開發過程當中繁雜的後端操做,使小程序開發更簡單。數據庫

4-1.雲數據庫

  數據庫的設計真的很重要,但願你們在最初設計的時候必定要細心考慮到每張表所須要的屬性,特別是有些表之間存在關聯的時候,否則後期發現某張表還缺乏一些屬性,再去添加,仍是有點難受的json

4-1-1.如下是我部分的數據庫設計

Qdaily-topic  投票話題表 用於存儲投票列表的信息
    |-id
    |-time    話題建立時間
    |-topicDesc    話題描述
    |-topicImage    話題封面圖片
    |-topicTitle    話題
    |-userNum     參與此話題人數
複製代碼
Qdaily-voter  參與用戶表 用於記錄參與投票的用戶
    |-id
    |-topicId    話題id
    |-userid     用戶id
複製代碼
Qdaily-comments  評論表 用於存儲用戶發表的評論內容
    |-id
    |-DZ_num      此評論得到的點贊總數
    |-avatarUrl     發表評論的用戶的頭像
    |-commentText    評論的內容
    |-nickName      發表評論的用戶的暱稱
    |-topicId      標誌是哪一個話題的評論內容
複製代碼
Qdaily-vote-option  選項表 用於每一個投票選項內容
    |-id
    |-optionDesc     選項文字內容
    |-optionImg     選項圖片
    |-optionNum    被選中的次數
    |-selected     標誌此話題是否被選中,默認false
    |-topicId      標誌是哪一個話題的選項內容
複製代碼

......小程序

4-2.雲函數

  在我看來,雲函數就是像是一門後臺語言,能夠接收前端發出的請求,而後對數據庫的數據進行操做,最後再把前端須要的數據返回給前端(我的理解,若是哪裏表述的不正確,還但願你們給我指正出來).所以,雲函數的重要性應該就不言而喻了吧後端

4-2-1.如下是我部分的雲函數設計:

添加評論雲函數數組

const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database();
// 雲函數入口函數
exports.main = async (event, context) => {
  const comment = await db.collection('Qdaily-comments').add({
    data:{
      commentText: event.commentText,
      nickName: event.info.nickName,
      avatarUrl: event.info.avatarUrl,
      time: new Date(),
      topicId: event.topicId,
      DZ_num:0
    }
  })
  return event;
}
複製代碼

添加話題參與者bash

// 雲函數入口文件
const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database();
// 雲函數入口函數
exports.main = async (event, context) => {
  // 獲取當前用戶的openId
  const openId = cloud.getWXContext().OPENID
  // 獲取當前選中的topic
  const topic = await db.collection('Qdaily-topic')
  .where({
    _id: event.topicId
  })
  .get()

  // 獲取當前參與此話題的人數
  const voters = await db.collection('Qdaily-voter')
  .where({
    topicId: event.topicId
  })
  .get()

  // 檢驗當前用戶是否已經參與過此話題
  const voter = await db.collection('Qdaily-voter')
  .where({
    userid: openId,
    topicId: event.topicId
  })
  .get()

  // 若是當前用戶沒有參與過此話題,則添加一條數據
  if(voter.data.length == 0){
    // 參與用戶表添加數據
    const voter =  await db.collection('Qdaily-voter').add({
      data:{
        userid: openId,
        topicId: event.topicId
      }
    })

    // 給當前選中的topic表中的參與人數userName 更新人數
    await db.collection('Qdaily-topic').doc(topic.data[0]._id)
    .update({
      data: {
        userNum: voters.data.length + 1
      }
    })
  }

  return topic.data[0]._id
}
複製代碼

獲取評論數據微信

// 雲函數入口文件
const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database();
// 雲函數入口函數
exports.main = async (event, context) => {
  // 獲取當前用戶的openId
  const openId = cloud.getWXContext().OPENID
  // 獲取當前話題的全部評論
  const comment = await db.collection('Qdaily-comments')
  .where({
    topicId: event.topicId
  })
  .get()
  // 判斷當前用戶是否對某條評論點贊過
  for(let i =0; i < comment.data.length; i++){
    let isDianzan = await db.collection('Qdaily-dianzan').where({ 
        commentId: comment.data[i]._id,
        userId: openId 
      })
      .get()

    if(isDianzan.data.length ==0){
     comment.data[i].bool = false;
    }
    else{
     comment.data[i].bool = true;
    }
  }
  // 根據評論的時間來排序 距離當前時間越短,越排在前面
  let newcomment = (comment.data).sort((a, b) => a.time < b.time ? 1 : -1);

  let mainComment = {};
  for (let i = 0; i < comment.data.length; i++) {
    if (comment.data[i]._id == event.commentId){
      mainComment = comment.data[i]
    }
  }

  
  return{
    newcomment: newcomment,
    mainComment: mainComment
  } 
}
複製代碼

......

5.功能設計

  好了,上面一大串的代碼,估計你們也都看得不肯意再看了吧!如今我給你們分享一下我這個小程序的一些主要功能吧!

5-1.投票功能

  投票功能算是這個小程序主要的功能,每一個用戶選擇本身一個感興趣的話題後,能夠進入詳情頁面投票,有個細節,沒選中以前,是不能夠投票的,且投票按鈕的顏色也是偏淡的,一旦用戶選中了某個話題或多個選項,顏色變得高亮,而且此時點擊按鈕能夠進入分析頁面,查看有多少比例的用戶和本身的選擇同樣.

//判斷是否有選項選中 同時找到選中選項的id
  _checked(e) {
    // 獲取裝用戶選中的選項id的盒子
    var arrOptionid = this.data.optionId;
    // 獲取當前的選項id
    var optionId = e.currentTarget.dataset.id
    // 當前選項選中後 check屬性變爲true 而且存入用戶選中的選項盒子optionId裏面
    if (e.detail.check == true) {
      arrOptionid.push(optionId)
      this.setData({
        // checked用來判斷用戶是否選擇了至少一個選項,當大於0時 則能夠進行投票
        checked: this.data.checked + 1,
        optionId: arrOptionid
      })
    } else if (e.detail.check == false){
      this.removeByValue(arrOptionid, optionId)
      this.setData({
        checked: this.data.checked - 1
      })
    }
    // console.log(this.data.checked)
    console.log(this.data.optionId)
  },
  //點擊投票後成功跳轉界面
  vote(e){
    const that = this
    if (that.data.checked > 0){
      wx.cloud.callFunction({
        // 調用雲函數,若是用戶是第一次進行投票,則會添加一個參與者信息
        name:'addVoter',
        data:{
          topicId: that.data.topicId
        },
        success(res){
          console.log(res)
          // 經過JSON.stringify(obj) 方法將數組轉化爲字符串進行傳遞
          const opId = JSON.stringify(that.data.optionId)
          // 帶參跳轉頁面
          wx.navigateTo({
            url: "../dataAnalysis/dataAnalysis?topicId=" + e.currentTarget.dataset.id + "&optionId=" + opId + "&topicTitle=" + that.data.oneTopic[0].topicTitle,
          })
        },
        fail(error){
          console.log(error)
        }
      })
    }else{
      wx.showToast({
        title: '沒有一項符合您嗎?',
        icon:'none',
        duration:2000
      })
    }
  },
複製代碼

5-2.評論功能

  因爲已進入頁面就會獲取用戶的信息,因此評論的時候就能夠把用戶數據以及評論的內容一塊兒放入數據庫,而後從數據庫拿出來從新渲染界面

// 往數據庫裏添加評論
  addComment() {
    let that = this;
    //判斷用戶是否輸入了內容
    if (that.data.commentText == ''){
      wx.showToast({
        title: '評論內容不能爲空',
        icon: 'none',
        duration: 2000
      })
    }else{
        // 調用添加評論雲函數
      wx.cloud.callFunction({
        name: 'addComment',
        data: {
          commentText: that.data.commentText,
          info: that.data.userInfo,
          topicId: that.data.topicId
        },
        success() {
          console.log('插入成功');
          wx.cloud.callFunction({
            // 調用獲取評論數據雲函數
            name: 'getComment',
            data: {
              topicId: that.data.topicId
            },
            success(res) {
              let newComment = that.newTime(res.result.newcomment)
              that.setData({
                comment: newComment,
                commentNum: res.result.newcomment.length
              })
              console.log(res.result.data)
            }
          })
          // 評論成功後清空數據,關閉評論框
          that.setData({
            discussShow: false,
            commentText: ''
          })
        }
      })
    }
  },
複製代碼

5-3.回覆功能

  這是一個二級評論頁面,若是是對下面的回覆再進行回覆,這條評論數據的最前面就會出現"@xxx",表示針對某個用戶的回覆,若是是對上面評論內容進行回覆,則不會有"@xxx"

addComment() {
    let that = this;
    //判斷用戶是否輸入了內容
    if (that.data.commentText == '') {
      wx.showToast({
        title: '評論內容不能爲空',
        icon: 'none',
        duration: 2000
      })
    } else {
      wx.cloud.callFunction({
        // 調用添加回複評論的雲函數
        name: 'addReply',
        data: {
          replyText: that.data.commentText,
          info: that.data.userInfo,
          mainCommentId: that.data.mainComment._id,
          mainCommentNickname: that.data.replyNickname,
          haveName: that.data.haveName
        },
        success() {
          console.log('插入成功');
          wx.cloud.callFunction({
            name: 'getReply',
            data: {
              mainCommentId: that.data.mainComment._id
            },
            success(res) {
              console.log('返回')
              console.log(res.result)
              let newReply = that.newTime(res.result.newreply)
              that.setData({
                replyComment: newReply,
                replyNum: newReply.length
              })

              console.log(that.data.replyComment)
            },
            fail(err) {
              console.log(err)
            }
          })
          // 評論成功後清空數據,關閉評論框
          that.setData({
            discussShow: false,
            commentText: ''
          })
        }
      })
    }
  },
複製代碼

5-4.點贊功能

  每一個用戶針對每條評論的點贊都是惟一的,因此我專門用了一張點贊表來裝點贊數據,每次點同意功,我就會往數據庫裏添加一條數據,同時修改這個評論的所獲點贊總數.最後根據返回的值來改變這個'♥'的樣式

//點贊功能
  _dianzan1(e){
    let that = this;
    //提早在頁面作好改變  
    // var thisComment = that.data.comment[e.currentTarget.dataset.index];
    if (that.data.comment[e.currentTarget.dataset.index].bool) {
      that.data.comment[e.currentTarget.dataset.index].bool = false;
      that.data.comment[e.currentTarget.dataset.index].DZ_num = that.data.comment[e.currentTarget.dataset.index].DZ_num - 1;
    } else {
      that.data.comment[e.currentTarget.dataset.index].bool = true;
      that.data.comment[e.currentTarget.dataset.index].DZ_num = that.data.comment[e.currentTarget.dataset.index].DZ_num + 1;
    }
    that.setData({
      comment: that.data.comment
    })
    // 調用點贊雲函數
    wx.cloud.callFunction({
      name: 'Dianzan',
      data: {
        // userId:
        commentId: e.currentTarget.dataset.id,
        topicId: that.data.topicId
      },
      // 成功後返回數據渲染界面
      success(res) {
        let newComment = that.newTime(res.result.newcomment)
        that.setData({
          comment: newComment
        })
      },
      fail(error){
        console.log(error)
      }
    })
  },
複製代碼

5-5.上傳本身想法功能 (相似於添加一個評論,不過多了一個圖片)

  每一個用戶不只能夠選擇投票話題,也能夠選擇發表想法的話題,能夠根據標題發表本身的想法

// 點擊不一樣的圖片會選擇相機或相冊內選擇圖片
  camera() {
    this.chooseImg('camera')
  },
  photo() {
    this.chooseImg('album')
  },
 // 選擇圖片
  chooseImg (temp) {
    const that = this;
    wx.chooseImage({
      count: 1, // 默認9
      sizeType: ['compressed'], // 能夠指定是原圖仍是壓縮圖,默認兩者都有
      sourceType: [temp], // 能夠指定來源是相冊仍是相機,默認兩者都有
      success: function (res) {
        // 返回選定照片的本地文件路徑列表,tempFilePath能夠做爲img標籤的src屬性顯示圖片
        var tempFilePaths = res.tempFilePaths;
        console.log(tempFilePaths[0]);
        // 提早把數據放進去
        that.setData({
          image: tempFilePaths[0]
        }) 
      }
    })
  },
  // 增長數據到數據庫
  addspeak() {
    wx.showLoading({
      title: '努力上傳中',
    })

    const that = this;
    //若是用戶上傳了圖片 此時把照片傳入數據庫
    if (that.data.image){
      let newFile = that.data.image.split('//')[1];
      console.log(newFile);
      wx.cloud.uploadFile({
        cloudPath: 'Qdaily/' + newFile,
        filePath: that.data.image, // 文件路徑
        success: res => {
          const fileId = res.fileID
          wx.cloud.getTempFileURL({
            fileList: [res.fileID],
            success: res => {
              const fileUrl = res.fileList[0].tempFileURL
              //插入數據
              wx.cloud.callFunction({
                name: 'addSpeak',
                data: {
                  topicId: that.data.topicId,
                  user: that.data.userInfo,
                  editText: that.data.commentText,
                  image: fileUrl,
                  imageID: fileId
                },
                success(res) {
                  wx.hideLoading();
                  wx.navigateTo({
                    url: '../speak/speak?topicId=' + that.data.topicId + "&index=" + that.data.index
                  })
                }
              })
            },
            fail: err => {
              // handle error
            }
          })
        },
        fail: err => {
          // handle error
        }
      })
    }
    // 用戶沒有上傳圖片 會使用默認的背景圖片
    else {
      //插入數據
      wx.cloud.callFunction({
        name: 'addSpeak',
        data: {
          topicId: that.data.topicId,
          user: that.data.userInfo,
          editText: that.data.commentText,
        },
        success(res) {
          wx.navigateTo({
            url: '../speak/speak?topicId=' + that.data.topicId + "&index=" + that.data.index
          })
        }
      })
    }
  },
複製代碼

  以上就是我這個小程序的主要功能了,其實主要的數據操做都在雲函數內,有興趣繼續瞭解的人能夠進入個人項目裏的雲函數看看

6.遇到的問題

  在寫這個小程序的時候,總有些地方的效果不讓人滿意,因此本身進行了一些修改,但願能給你們帶來一點小小的幫助

6-1.獲取用戶信息

因爲我這個程序須要得到用戶的信息,因此我最開始直接用了這個方法獲取用戶彈窗

//獲取用戶信息
    wx.getUserInfo({
        success: function (res) {
 
            console.log(res);
            that.data.userInfo = res.userInfo;
 
            that.setData({
                userInfo: that.data.userInfo
            })
        }
    })
複製代碼

結果自從微信接口有了新的調整以後 這個wx.getUserInfo()便再也不出現受權彈窗了,須要使用button按鈕

<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">受權登陸</button>

單獨一個按鈕獲取用戶信息,難免顯得太...突兀了把.因此我想到把個這個按鈕放在小程序的封面

只有在用戶贊成程序得到數據後才能夠進入程序,把封面那句 好奇驅動你的世界做爲按鈕,既不突兀,也能夠獲取到用戶的信息.在下次從新進入此程序的時候,若是用戶已經贊成過,則不會彈出獲取信息框,直接進入主頁面

// 當頁面已經獲取到用戶信息時,點擊按鈕直接跳轉
  goindex(){
    wx.redirectTo({
      url: '../index/index',
    })
  },
  bindGetUserInfo(e){
    if (e.detail.userInfo) {
      //用戶按了容許受權按鈕
      wx.redirectTo({
        url: '../index/index',
      })
    } else {
      //用戶按了拒絕按鈕
      wx.showToast({
        title: '用戶信息獲取失敗,請重試',
        duration:2000,
        icon:'none'
      })
    }
  },
複製代碼

6-2.點贊效果馬上顯示

  不知道寫小程序的大家是否也碰到這種狀況,就是對雲數據庫進行發送數據而後再返回數據,這個時間可能須要一兩秒,其餘的還好,但若是點個贊也須要一兩秒才能看到效果,這也太難受了!但我又不知道怎麼提高這個往雲數據庫裏存值取值的時間,因此只能在本地想辦法了.

  個人想法是這樣的: 每一個♥都有本身的一個bool屬性,若是爲true時,纔是紅色的,不然爲false,假設此時的這個♥是true狀態,當我點擊♥時,經過雲函數和雲數據庫,最後返回一個false狀態,此時的♥才被改成false狀態.

  由於♥的狀態只有兩種,因此我爲何不能夠在最開始點擊的時候就把它的狀態改成另一種,由於我知道此次點擊事後通過雲函數雲數據庫返回的狀態必定是另一種,先把狀態直接改了,讓用戶馬上能夠知道本身的點贊或取消點同意功了,而後等數據庫的操做進行完成後再返回數據渲染頁面,由於此時顯示的狀態已經和返回的結果同樣了,因此看不到變化的效果,但數據庫的更新也完成了.

let that = this;
    //提早在頁面作好改變
    // var thisComment = that.data.comment[e.currentTarget.dataset.index];
    if (that.data.comment[e.currentTarget.dataset.index].bool) {
      that.data.comment[e.currentTarget.dataset.index].bool = false;
      that.data.comment[e.currentTarget.dataset.index].DZ_num = that.data.comment[e.currentTarget.dataset.index].DZ_num - 1;
    } else {
      that.data.comment[e.currentTarget.dataset.index].bool = true;
      that.data.comment[e.currentTarget.dataset.index].DZ_num = that.data.comment[e.currentTarget.dataset.index].DZ_num + 1;
    }
    that.setData({
      comment: that.data.comment
    })
    
    .....
    調用點贊雲函數
    ......
複製代碼

  不過這個問題還有個小bug,就是當用戶點擊過快時,界面的確能夠當即更新,但由於數據庫的調用這些須要時間,可能頁面點擊了四次,但云函數還連一次的值都沒有返回,再等一兩秒後,四次結果依次返回:true->false->true->...這個時候,你就會發現頁面的♥會出現閃爍狀況😭,個人解決辦法是,設置點贊按鈕每隔一秒才能點擊一次(若是你有更好的解決辦法,或是別的點贊方法,但願給我留言啊😁)

_dianzan(e) {
    var that = this;
    let d = new Date();
    let nowtime = d.getTime();//獲取點擊時間
    if (nowtime - that.data.lasttime > 1000) {
      that._dianzan1(e);
    } else {
      wx.showToast({
        title: '您點擊的太快了',
        duration: 1000,
        icon: 'none'
      })
    }
    that.setData({
      lasttime: nowtime
    })
  },
複製代碼

6-3.一個組件顯示兩種樣式

不管是小程序仍是app,你們瀏覽一些新聞內容時,都會碰到外表樣式不同,但點進去的內容確是一種樣式的,若是說寫兩個組件,那麼wx:for循環渲染數據的時候就太麻煩了吧我想了想,以爲能夠這樣寫

<view class='msg' wx:if="{{index % 4 == 0}}">
......
<view class='msg1' wx:else>
......
複製代碼

在本來的組件裏在添加一種樣式,而後把wx:for 裏的index值傳入組件,當index值爲4的倍數時(能夠根據你本身需求設置),使用第一種樣式,其他的都使用第二種樣式,這樣就能夠達到我上面的效果了

  寫了這麼多總算是把整個小程序都給解構完了,可能不少地方講的仍是有點粗糙,若是您想對我這個小程序瞭解更多,能夠查看個人項目好奇心,但願能給您帶來幫助,也但願能留下您寶貴的意見

7.結語

  學習的過程是痛苦的,但結果是美好的,在這個簡單小程序最終出爐的時候,內心仍是有點開心的,寫這個小程序不只僅是一個把學習的結果展示出來,更是對本身所學內容的查漏補缺,瞭解到本身的不足之處,並去彌補纔是最重要的,代碼的學習之路還很長,還得繼續勤勤懇懇的學下去.

若是想一塊兒學習的小夥伴也能夠加我微信哦😁:zh1318226678

相關文章
相關標籤/搜索