微信小程序demo-码乎

前言

项目描述:
本项目的灵感来源于知乎APP和朵朵校友圈微信小程序,ZUCC的同学们在朵朵上分享校园日常等,那么可不可以按照知乎的模式,设计一个 属于ZUCC的专业知识相关的问答平台,但全校范围过广,于是我设计为我们基于我们计算学院的平台,也就是计算机相关专业知识的交流问答平台,这就是 码乎。今天,你码了吗?
本项目只是一个简单的微信小程序demo,使用微信小程序云开发,数据存储在数据库中。
设计思路:
1.完成全局配置,如顶部栏,底部tabBar,将计划中的5个基本页面形成大致框架,并引入所需素材。
2.首先在数据库存入所需数据,相应页面js文件引入data,然后逐个完成页面的排版布局,使页面完整。
3.完成基本交互,包括页面间的跳转,点击事件等。
4.整理代码,修改、弥补不足。
开发工具及环境:
微信开发者工具、VSCode

项目基本页面演示

(本博文所有图片均来自于真机调试)

全局配置

全局JOSN文件 app.jons

全局配置主要用于控制小程序页面以外的内容,如头部和底部导航栏的样式结构等,也决定了整个小程序的内容页数,我们在开始做一个小程序之前,应该先设计好大概的需要做的页面内容,制定好框架再进行,不然在做的过程中容易混乱,想加想改可能都会遇到麻烦。
pages:共5个基本页面,index(首页),answer(回答页),question(问题页),notify(消息页),my(个人页)
"pages":[
    "pages/index/index",
    "pages/answer/answer",
    "pages/notify/notify",
    "pages/question/question",
    "pages/my/my",
    "pages/logs/logs"
  ]

window:定义小程序所有页面的顶部背景颜色,文字颜色定义等

"window":{
    "backgroundTextStyle":"dark",
    "navigationBarBackgroundColor": "#0068C4",
    "navigationBarTitleText": "码乎",
    "navigationBarTextStyle":"white",
    "enablePullDownRefresh": true
  }

tabBar:底部导航栏组件,控制小程序底部导航栏的所有样式

"tabBar": {
    "color": "#aaa",
    "selectedColor": "#0068C4",
    "backgroundColor": "#ffffff",
    "position": "bottom",
    "borderStyle": "white",
    "list": [
      {
        "text": "首页",
        "pagePath": "pages/index/index",
        "iconPath": "images/tabBar/index.png",
        "selectedIconPath": "images/tabBar/index_focus.png"
      },
      {
        "text": "消息",
        "pagePath": "pages/notify/notify",
        "iconPath": "images/tabBar/ring.png",
        "selectedIconPath": "images/tabBar/ring_focus.png"
      },
      {
        "text": "我的",
        "pagePath": "pages/my/my",
        "iconPath": "images/tabBar/my.png",
        "selectedIconPath": "images/tabBar/my_focus.png"
      }
    ]
  }

全局js文件 app.js

下面的js代码为微信开发者工具原生自带,主要用于授权后获得微信用户信息,这点直接决定了后台数据的调用,数据库的一般分配给每个用户一个单独的id来调取数据,所以这个功能非常重要。在本小程序中,该功能从微信端简单调用登录用户的头像和名字等信息。
  wx.login({
    success: res => {
      // 发送 res.code 到后台换取 openId, sessionKey, unionId
    }
  })
  // 获取用户信息
  wx.getSetting({
    success: res => {
      if (res.authSetting['scope.userInfo']) {
        // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
        wx.getUserInfo({
          success: res => {
            // 可以将 res 发送给后台解码出 unionId
            this.globalData.userInfo = res.userInfo

            // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
            // 所以此处加入 callback 以防止这种情况
            if (this.userInfoReadyCallback) {
              this.userInfoReadyCallback(res)
            }
          }
        })
      }
    }
  })

各页面基本介绍

首页


基本局部 index.wxml
  <!-- 头部搜索框 -->
  <view class="search flex-wrp">
    <view class="search-left flex-item">
      <image src="../../images/search.png"></image>
      <input placeholder="搜索ZUCC码乎内容" placeholder-class="search-placeholder" />
    </view>
    <view class="search-right flex-item">
      <image src="../../images/lighting.png"></image>
    </view>
  </view>
  <!-- 用于解决头部被遮挡问题 -->
  <view class="vis-wrap">
    <view class="vis"></view>
  </view>
  <!-- 首页列表 -->
  <view class="show-list" wx:for="{{feed}}" wx:key="index">
      <!-- block01 -->
      <view class="list-head" bindtap="toQuestion">
        <text class="question">{{item.question}}</text>
      </view>
      <!-- block02 -->
      <view class="user-left">
        <image src="{{item.feed_source_img}}"></image>
        <text class="name">{{item.feed_source_name}}</text>
      </view>
      <!-- block03 -->
      <view class="answer" bindtap="toAnswer">
        <text>{{item.answer_ctnt}}</text>
      </view>
      <!-- block04 -->
      <view class="list-bottom">
        <text>{{item.good_num + "赞同 • " + item.comment_num + "评论"}}</text>
        <image src="../../images/more.png"></image>
      </view>
  </view>
</view>

index.js 存放本地数据和跳转功能。wx.navigateTo是非常重要的一个方法,用于页面间的跳转,在页面内多设置跳转,可以提高小程序的交互性。

  // 跳转至回答页面
  toAnswer: function () {
    wx.navigateTo({
      url: "../answer/answer"
    });
  },
  //跳转至问题页面
  toQuestion: function () {
    wx.navigateTo({
      url: "../question/question"
    });
  }

回答页

本页除了基本的样式排版外,实现了关注与取消关注,赞同与取消赞同,收藏与取消收藏功能,下面为演示gif(25s)

以关注和取消关注为例,只需要在data数据中设置一个用于判断当前关注状态的值isFocus,再给收藏标签设置一个bindtap,使之获得一个点击响应方法,该方法通过对当前的isFocus进行判断,从而改变关注标签的样式等。将isFocus保存在数据库,每次加载时即可调取上次保存的关注状态。
下面的收藏功能的部分js代码
focus: function (options) {
    console.log(options)
    let that = this;
    let isFocus = this.data.feed[0].isFocus;
    if (!isFocus) { //关注
      DB.doc("d6b130aa5fa2c865000c045b41a8468c").update({
        data: {
          isFocus: true,
          focus_text: "已关注",
        },
        success(res) {
          console.log("更新成功", res)
        },
        fail(res) {
          console.log("更新失败", res)
        }
      })
      wx.showToast({
        title: '关注成功',
        icon: 'none'
      })
    }
    else{ //取消关注
      DB.doc("d6b130aa5fa2c865000c045b41a8468c").update({
        data: {
          isFocus: false,
          focus_text: "关注"
        },
        success(res) {
          console.log("更新成功", res)
        },
        fail(res) {
          console.log("更新失败", res)
        }
      })
      wx.showToast({
        title: '已取消关注',
        icon: 'none'
      })
    }

问题页

一个朴实无华的问题页。这一页我完全模仿知乎APP的布局排版来设置,非常有意思,最终做出的效果还不错。做这种页面布局很有意义,从最外层一层一层往里挖掘,既需要细心,更需要大局观。

消息页

本页采用顶部栏切换形式,分为动态和消息两栏。实现方法为在js中设置一个判断值currentNavTab,通过点击事件SwitchTab得到当前用户选择的页面,然后修改判断值,通过判断值将另外的页面设置为hidden即可,同时,为了改变顶部栏的样式,也需要通过判断值修改顶部栏的class。
这个在同一页面内的扩展方式也非常常用,很好地将两个息息相关的页面放在同一个大页中,让用户获得良好的体验。

基本布局:
<!-- 顶部导航条 -->
<view class="top-tab">
  <view class="toptab {{currentNavtab==idx ? 'active' : ''}}" wx:for="{{navTab}}" 
    wx:for-index="idx" wx:for-item="itemName" data-idx="{{idx}}" bindtap="switchTab">
    {{itemName}}
  </view>
</view>
<view class="container">
  <!-- 动态栏 -->
  <view class="cnt0" hidden="{{currentNavtab==0 ? '' : true}}" wx:for="{{feed}}"
    wx:key="{{index}}">
    <view class="head">
      <view class="img">
        <image src="{{item.feed_source_img}}"></image>
      </view>
      <view class="text">
        <text class="name">{{item.feed_source_name}}</text>
        <text class="time" decode>收藏了回答&nbsp;·&nbsp;10/15</text>
      </view>
    </view>
    <view class="content">
      <view class="text">
        <view class="title">
          <text>{{item.question}}</text>
        </view>
        <view class="info">
          <text decode>{{item.feed_source_name + "的文章 · " + item.good_num 
              + " 赞同 · " + item.comment_num + " 评论"}}</text>
        </view>
      </view>
      <view class="img">
        <image src="{{item.feed_source_img2}}"></image>
      </view>
    </view>
  </view>
  <!-- 消息栏 -->
  <view class="cnt1" hidden="{{currentNavtab==1 ? '' : true}}">
    <view class="allread">
      <view class="list">
        <text>消息列表</text>
      </view>
      <view class="txt">
        <text>全部已读</text>
      </view>
    </view>
    <view class="notifylist" wx:for="{{notifyList}}" wx:key="{{index}}">
      <view class="img">
        <image src="{{item.img}}"></image>
      </view>
      <view class="info">
        <view class="name">
          <text>{{item.name}}</text>
        </view>
        <view class="text">
          <text>{{item.text}}</text>
        </view>
      </view>
      <view class="time">
        <view>
          <text>{{item.time}}</text>
        </view>
      </view>
    </view>
  </view>
</view>

js方法:

  switchTab: function(e){
    this.setData({ //修改判断值,从而改变样式
      currentNavtab: e.currentTarget.dataset.idx
    });
  }

我的页

本页便采用了微信小程序自带的微信授权功能,实现用户信息的交互功能,可在页面中直接展示用户的微信头像及用户昵称,js代码已在前面展示

my.wxml
<view class="container">
  <view class="userinfo">
    <button class="btn" wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" 
      bindgetuserinfo="getUserInfo"> 微信授权登录 </button>
    <view wx:else class="content">
      <view class="img">
        <image bindtap="bindViewTap" class="userinfo-avatar" 
          src="{{userInfo.avatarUrl}}" mode="cover"></image>
      </view>
      <view class="text">
        <text class="userinfo-nickname">{{userInfo.nickName}}</text>
        <text class="setting" decode>个人主页&nbsp;></text>
      </view>
    </view>
  </view>
  <view class="mylist" wx:for="{{myList}}" wx:key="{{index}}">
    <view class="idx">
      <view class="img">
        <image src="{{item.img}}"></image>
      </view>
      <view class="text">
        <text>{{item.text}}</text>
      </view>
    </view>
  </view>
</view>

问题与发现

1.最大的问题是功能还不完善,本demo只能做展示使用,而没有用户进行提问和回答等功能,有待开发.
2.我在首页做一个顶部固定的(用position:fix实现)的搜索框,然后我还想获得下拉刷新,那么搜索框下面的内容就会被覆盖起来,如果给下面的内容加一个margin-top,那么下拉刷新的白条就会变长,很难看,体验不佳,查了很多资料也没有得到解决方法,只好取消下拉刷新,而顶部固定的内容也有类似情况。
3.做项目时CSS代码非常重要,首先在布局上,总体一般使用flex布局会比较方便,很多时候调整位置会用到相对定位。由于flex布局的通用性和复用性,最好可以将css代码统一写到app.wxss中,那么就可以进行复用,不用再多次地敲重复的代码,很多其他的css样式也是同样的道理。我做这样一个简单的小程序就觉得重复率很高,更何况接下来体量大得多的大作业?很重要的一点,就是提前准备好全局的css代码,在项目前期完善这方面的功能和内容,将会为后面节省下大量的时间和精力,整个项目和代码的结构框架也更清晰,何乐而不为呢?
4.与第二点类似的,微信小程序为我们提供了一个很方便的component,可以用来自定义一些复用组件,也是很好地提高我们写小程序的效率,如果我们能充分利用,会非常有益。
5.软件工程项目需要面向客户,所以交互是非常重要的,而决定交互的一是界面的样式,这是由html和css决定的,而更重要的是小程序对用户操作的反应,这就是由js决定的了,可以说用好js才能做出出色的,功能可靠完全的小程序,因此对于js的学习应该加紧,特别是es6语法,能很大地提高写代码的水准。

总结

这是我第一个独立完成的微信小程序,虽然有很多不完善的地方,也有很多代码混乱、不知所措的地方,但通过这几天的摸索和努力,也找到了一点开发微信小程序的思路。接下去,我会学习更多软件工程方法和微信小程序的知识,来完善自己的不足,扩充小程序的内容和功能。软件工程是一门非常考验实践的课程,多学、多想、多写才能让人更上一层楼。

参考资料

https://github.com/RebeccaHanjw/weapp-wechat-zhihu 知乎小程序demo

https://juejin.im/post/6844903873497268231 微信小程序实战教程

posted @ 2020-10-19 11:35  原味YuAn  阅读(3833)  评论(0编辑  收藏  举报