用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 資訊/觀點 查看內容

湖人vs马刺常规赛录像回放:微信小程序-滬江英語+商城tap切換功能

湖人vs爵士季后赛 www.nbgeh.club Rolan 2019-6-5 00:12

首先說段pi話,我是一個菜雞前端小白,我不僅是菜雞前端我還沒過英語四級,現在大三了有點著急,但是我相信我會過的,所以我選擇仿了一個跟英語有關的小程序想著能夠潛移默化的受到影響,這個小程序就是標題所說的“ ...

首先說段pi話,我是一個菜雞前端小白,我不僅是菜雞前端我還沒過英語四級,現在大三了有點著急,但是我相信我會過的,所以我選擇仿了一個跟英語有關的湖人vs爵士季后赛想著能夠潛移默化的受到影響,這個小程序就是標題所說的“ 滬江英語 ”(黑體加粗)。這是我做的第一個小程序,但是你們不能因為我菜就不往下看了說不定就能有些收獲呢你說是吧(嘿嘿嘿嘿嘿)

項目預覽及開始前的準備


開始前準備及使用工具
  • 申請賬號:進入微信公眾平臺根據指示申請注冊賬號
  • 開發工具:VScode和 微信開發者工具
  • 使用的文檔及第三方工具
  1. EasyMock(一個可視化,并且能快速生成模擬數據的第三方服務)
  2. 小程序云開發的數據庫功能和存儲功能(在這里我主要用來存儲圖片,利用其生成的圖片地址)
  3. VantWeapp以及其開發文檔
  4. 微信官方文檔
  5. markMan(可以進行圖片測量和標注的工具)
  6. iconfont(阿里巴巴矢量圖標庫,有大量icon資源)
  7. wxParse(富文本解析組件,能夠顯示富文本而且它的思路是將整個HTML String轉換成一個Node數組 一句話就是能夠把html直接渲染到小程序中)

項目完成過程

剛開始的時候看到原小程序如下圖所示

我的天,這些都可以點而且每個頁面都不一樣,我的天,是不是每個頁面都要跳轉,是不是要建好多個頁面,這也太煩了吧,我當時就想著有沒有別的方法可以在同一個頁面實現這個功能,一開始我沒有想出來,因為我連數據該怎么建都不知道,但是我沒有放棄,我思前想后頭皮發麻,終于我選擇了先切頁面下面這一段是介紹頁面結構的,再后面就是數據的構建以及邏輯了(不想看下面一段內容的請直接跳到下下段內容)

頁面結構

"pages": [
    "pages/index/index", //首頁
    "pages/theme/theme", //主題頁
    "pages/articlels/articlels", //文章列表頁
    "pages/content/content", //文章詳情頁
    "pages/search/search" //搜索頁面
  ],
復制代碼

首頁

<!-- index.wxml -->
<view class="container">
  <!-- 搜索 -->
  <view class="search" bindtap="toSearch">
    <van-search value="{{ value }}" placeholder="搜索" background="#49b849" />
  </view>
  <!-- 導航 -->
  <view class="weui-grids">
    <block wx:for="{{navigation}}" wx:key="{{item.id}}">
      <navigator url="" class="weui-grid" hover-class="none" url="../articlels/articlels?id={{item.id}}&navigationText={{item.navigationText}}">
        <image class="weui-grid__icon" src="{{item.typePic}}" />
        <view class="weui-grid__label">{{item.typeName}}</view>
      </navigator>
    </block>
  </view>
  <!-- 廣告 -->
  <swiper class="banner" indicator-dots="true" autoplay="true" interval="5000" duration="500">
    <block wx:for="{{advertPic}}" wx:key="index">
      <swiper-item>
        <image src="{{item}}" class="slide-image" />
      </swiper-item>
    </block>
  </swiper>
  <!--  -->
  <scroll-view scroll-y="true">
    <block wx:for="{{article}}" wx:key="index" wx:for-item="article">
      <view class="article">
        <view class="article-title">
          <view class="article-title__text">{{article.title}}</view>
          <view class="article-title__time">{{article.time}}</view>
        </view>
        <!--  -->
        <view class="article-column">
          <image class="article-column__img" src="{{article.imgUrl}}" />
          <view class="article-column__text">{{article.text}}</view>
        </view>
        <!--  -->
        <view class="article-content">
          <navigator wx:for="{{article.typeList}}" wx:key="{{typeList.lId}}" wx:for-item="typeList" url="../articlels/articlels?id={{typeList.lId}}&navigationText={{typeList.navigationText}}" class="article-list" hover-class="none">
            <view class="article-list__titlt">{{typeList.listTitle}}</view>
            <view class="article-list__des">{{typeList.listdes}}</view>
          </navigator>
        </view>
      </view>
    </block>
  </scroll-view>
</view>
復制代碼
/**index.wxss**/
page {
  height: 100%;
  background-color: #f8f8f8;
}
.contaner{
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
/* 搜索 */
.search{
  width: 100%;
  height: 108rpx;
}
.van-search{
  position: absolute;
  left: 0;
  right: 0;
}
.van-search__content{
  height: 54rpx;
  align-items: center;
}
/* 導航 */
.weui-grids{
  width: 100%;
  background-color: #ffffff;
  margin-bottom: 18.75rpx;
}
.weui-grid{
  width: 25%;   /*每份占父容器寬度的25%,一排可容納四個*/
  text-align: center; 
  display: inline-block; /*設置為行內塊級元素多個元素可在一排顯示且設置寬高*/
}
.weui-grid__icon{
  width: 54rpx;
  height: 46rpx;
  margin-top: 53rpx;
  margin-bottom: 21rpx;
}
.weui-grid__label{
  font-size: 22rpx;
  color: #333333;
  margin-bottom: 46rpx;
}
/* 廣告 */
.banner{
  width: 100%;
  height: 150rpx;
  margin-bottom: 21rpx;
}
.slide-image{
  width: 100%;
  height: 170rpx;
}
/*  */
.article{
  width: 100%;
  padding: 28rpx 37.5rpx 0;
  margin-bottom:21rpx;
  background:#fff;
  /* padding-top: 28rpx; */
  box-sizing: border-box;
}
.article-title{
  position: relative;
  width: 100%;
  height: 73rpx;
  color: #797979;
}
.article-title__text{
  font-size: 29rpx;
  position: relative;
  top: 0;
  left: 0;
}
.article-title__time{
  line-height: 29rpx;
  font-size: 20rpx;
  align-items: center;
  position: absolute;
  top: 0;
  right: 0;
}
/*  */
.article-column{
  width: 100%;
  margin-bottom: 53rpx;
  position: relative;
}
.article-column__img{
  width: 100%;
  height: 290rpx;
}
.article-column__text{
  position: absolute;
  font-size: 31rpx;
  color: #ffffff;
  left: 21rpx;
  bottom: 25rpx;
  padding-right: 21rpx;
}
/*  */
.article-content{
  width: 100%;
  display: flex;
  flex-flow: row  wrap;
  /* justify-content: space-around; */
  align-content: flex-start;
}
.article-list{
  width: 33.33%;
  flex: 0 0 auto;
  text-align: center;
  margin-bottom: 65.625rpx;
}
.article-list__titlt{
  color: #000000;
  line-height: 26rpx;
  font-size: 26rpx;
  margin-bottom: 15.625rpx;
}
.article-list__des{
  line-height: 20.79rpx;
  font-size: 20.79rpx;
  color: rgba(0,0,0,0.7);
}
復制代碼

文章列表頁

<view class="articlePage">
    <view class="articlesection">
        <navigator url="../content/content?id={{item.articleId}}&totalId={{totalId}}&typeListId={{typeListId}}" class="articlesection-list" hover-class="none" wx:for="{{articles}}" wx:key="articleId">
            <view class="list-Left">
                <view class="list-Left__title">{{item.articledesc}}</view>
                <view class="list-Left__num">{{item.num}}</view>
            </view>
            <view class="list-Right">
                <image class="list-ight__img" src="{{item.img}}" />
            </view> 
        </navigator> 
    </view>
</view>
復制代碼
/* miniprogram/pages/articlels/articlels.wxss */
page{
    width: 100%;
}
.articlePage{
    width: 100%;
    background-color: #fff;
}
.articlesection{
    padding: 21.857rpx 35.42rpx 0;
    box-sizing: border-box;
    width: 100%;
}
.articlesection-list{
    width: 100%;
    display: flex;
    justify-content: space-between;
    flex-direction: row;
    border-bottom: 1px solid #f3f3f3;
    padding-bottom: 37.5rpx;
    margin-top:37.5rpx ;
}
.list-Left{
    flex: 1;
}
.list-Left__title{
    width: 398rpx;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: 31.25rpx;
    color: #333333;
    margin-bottom: 90rpx;
}
.list-Left__num{
    font-size: 23.75rpx;
    color: #cccccc;
}
.list-Right{
    width: 200rpx;
    height: 151rpx;
}
.list-ight__img{
    width: 200rpx;
    height: 151rpx;
}
復制代碼

文章詳情頁

<import src="../../wxParse/wxParse.wxml" />
<view class="content">
    <scroll-view scroll-y="true"  enable-back-to-top="true" class="artContent">
        <view class="artContent_header">
            <text class="artContent_header--title">{{title}}</text>
            <view class="artContent_header--bottom">
                <view class="artContent_header--author">{{author}}</view>
                <view class="artContent_header--time">{{time}}</view>
            </view>
        </view>
        <view class="artContent-body">
            <template is="wxParse" data="{{wxParseData:content.nodes}}" />
        </view>
    </scroll-view>
    <view class="footer">
        <view class="footer-follow">
            <image class="footer-follow__icon" bindtap="backHome" src="../../images/back.png"/>
            <view class="footer-follow__text">回主頁</view>
        </view>
        <view class="footer-share" bindtap="nextArticle" data-id='{{id}}'>
            <image class="footer-share__icon" src="../../images/next.png"/>
            <view class="footer-share__text">下一篇</view>
        </view>
    </view>
</view>
復制代碼
/* miniprogram/pages/content/content.wxss */
@import"../../wxParse/wxParse.wxss";
.content{
    width: 100%;
}
.artContent{
    width: 100%;
    background-color: #fbfbfb;
    padding: 52rpx 36.45rpx 0;
    box-sizing: border-box;
}
.artContent_header{
    height: 198rpx;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    font-weight: 500;
    border-bottom: 1px solid #ededed;
}
.artContent_header--title{
    font-size: 40rpx;
    color: #333333;
}
.artContent_header--bottom{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    font-size: 22rpx;
    color: #d1d1d1;
    margin-bottom: 24rpx;
}
.artContent-body{
    margin-top: 59.375rpx;
    width: 100%;
    margin-bottom:  147rpx;
}
.footer{
    position: fixed;
    bottom: 0;
    width: 100%;
    background-color: #fff;
    padding: 16.67rpx 0;

}
 .footer{
    position: fixed;
    bottom: 0;
    width: 100%;
    display: flex;
    flex-direction: row;
    height: 94.79rpx;
    background-color: #fff;
    justify-content: space-around;
    align-items: center;

}
.footer-follow,.footer-share{
    text-align: center;
}
.footer-follow__icon,.footer-share__icon{
    width: 31.25rpx;
    height: 31.25rpx;
}
.footer-follow__text,.footer-share__text{
    font-size: 16.67rpx;
    color: #8a8a8a;
}

.langs_en{
  line-height: 57rpx;
  font-size: 31.25rpx;
  margin-bottom: 41.67rpx;
}
.langs_cn{
  color: #666666;
  font-size: 28.125rpx;
  line-height: 55.2rpx;
  margin-bottom: 41.67rpx;
}
復制代碼

搜索頁面

由動圖可知搜索頁面由四個部分組成:搜索框+搜索獲得內容列表+文章列表(完全引用了文章列表頁面的結構,但是沒有封裝成組件所以大家先將就著看)+ 搜索示例,我直接上代碼吧

<van-search value="{{ value }}" placeholder="請輸入搜索關鍵詞" show-action bind:search="onSearch" bind:cancel="onCancel" bind:change="searchInput" />
<scroll-view scroll-y class="search-list {{is_hidden?'hidden':''}}">
    <block wx:for="{{search_list}}" wx:key="{{item.articleId}}">
      <text class="search-item" bindtap="showItemDetail" data-articledesc="{{item.articledesc}}">{{item.articledesc}}</text>
    </block>
</scroll-view>
<block wx:if="{{articles==''}}">
  <view class="case">
    <view class="case-item" wx:for="{{word}}"  wx:key="index"  bindtap="showItemDetail" data-articledesc="{{item}}">
        <text>{{item}}</text>
    </view>
  </view>
</block>
<view class="articlePage">
    <view class="articlesection">
        <navigator url="../content/content?id={{item.articleId}}&totalId={{totalId}}&typeListId={{item.typeListId}}" class="articlesection-list" hover-class="none" wx:for="{{articles}}" wx:key="item.articleId">
            <view class="list-Left">
                <view class="list-Left__title">{{item.articledesc}}</view>
                <view class="list-Left__num">{{item.num}}</view>
            </view>
            <view class="list-Right">
                <image class="list-ight__img" src="{{item.img}}" />
            </view> 
        </navigator> 
    </view>
</view>
復制代碼
page {
    width: 100%;
}
.case{
    width: 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content:space-around;
    align-items: center;
}
.case-item{
    width: 30%;
    height: 70rpx;
    margin-bottom: 20rpx;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
}
.case-item text{
    font-size: 35rpx;
    width: 140rpx;
    background-color:#2cb62c;
    /* border-radius: 50%; */
    color:rgb(116, 18, 62);
    border: 1px solid rgba(0, 0, 0, .3);
    text-align: center;
    border-radius: 20rpx;
}

/*  */
/*  */
.search-list{
    width: 100%;
    height: 50vh;
    display: flex;
    flex-direction: column;
    position: fixed;
    z-index: 2;
    background: #fff;
    border-bottom: 1rpx solid #eee;
}
.search-list .search-item{
    display: inline-block;
    width: 100%;
    height: 80rpx;
    line-height: 80rpx;
    padding: 8rpx 30rpx;
    border-bottom: 1rpx solid #eee;
    font-size: 20rpx;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.search-list .search-item:last-child{
    border-bottom: none;
}
.search-list.hidden{
    display: none;
}

/*  */
/*  */
.articlePage{
    width: 100%;
    background-color: #fff;
}
.articlesection{
    padding: 21.857rpx 35.42rpx 0;
    box-sizing: border-box;
    width: 100%;
}
.articlesection-list{
    width: 100%;
    display: flex;
    justify-content: space-between;
    flex-direction: row;
    border-bottom: 1px solid #f3f3f3;
    padding-bottom: 37.5rpx;
    margin-top:37.5rpx ;
}
.list-Left{
    flex: 1;
}
.list-Left__title{
    width: 398rpx;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: 31.25rpx;
    color: #333333;
    margin-bottom: 90rpx;
}
.list-Left__num{
    font-size: 23.75rpx;
    color: #cccccc;
}
.list-Right{
    width: 200rpx;
    height: 151rpx;
}
.list-ight__img{
    width: 200rpx;
    height: 151rpx;
}
復制代碼

主題頁沒啥可以介紹的所以就不介紹了

接下來重點來了小程序數據的構建還有功能邏輯

數據的構建

Easy-Mock

一開始本小辣雞就說了連怎么建數據都不知道,后來每天盯著滬江英語小程序的頁面看,點了一遍又一遍,格物致知,終于,我想通了

正經的我要開始告訴你們了。首先我主頁的數據是在 Easy-Mock

里面創建的接口數據

主要由三部分組成: navigation 為首頁頂部的文章類型列表的數據, advertPic 為swiper廣告圖片數據, article 為flex布局部分的數據此數組內部還嵌套了數組 放上我建的EsayMock數據接口的鏈接可以點進去去看一眼。 每個 navigation 以及 article 中的每一項里面的 typeList

中的item都有一個id/lId,這個id主要是用來從云數據庫從取得文章列表內容(articlels頁面)中的數據的,其他的數據都是用來渲染頁面的。接下來講一下嵌套數據渲染的使用

<block wx:for="{{article}}" wx:key="index" wx:for-item="article">
      <view class="article">
        <view class="article-title">
          <view class="article-title__text">{{article.title}}</view>
          <view class="article-title__time">{{article.time}}</view>
        </view>
        <!--  -->
        <view class="article-column">
          <image class="article-column__img" src="{{article.imgUrl}}" />
          <view class="article-column__text">{{article.text}}</view>
        </view>
        <!--  -->
        <view class="article-content">
          <navigator wx:for="{{article.typeList}}" wx:key="{{typeList.lId}}" wx:for-item="typeList" url="../articlels/articlels?id={{typeList.lId}}&navigationText={{typeList.navigationText}}" class="article-list" hover-class="none">
            <view class="article-list__titlt">{{typeList.listTitle}}</view>
            <view class="article-list__des">{{typeList.listdes}}</view>
          </navigator>
        </view>
      </view>
    </block>
復制代碼

如上代碼,第一層的循環在上述代碼第一行

<block wx:for="{{article}}" wx:key="index" wx:for-item="article">
復制代碼

第二層循環在第......倒數第七行

<navigator wx:for="{{article.typeList}}" wx:key="{{typeList.lId}}" wx:for-item="typeList" 
復制代碼

我們將article中的typList遍歷了出來。 需要注意 的是我把兩處代碼中的item都通過wx:for-item="xxx*"將item改名,兩處不是都需要改,但必須通過wx:for-item="xxx"將一處的item更名,防止渲染時都使用item.xxx進行渲染導致混亂

云開發數據庫

第一次自己建數據庫中的數據的時候,我真的是一個加號一個加號的點,一個字段一個字段的敲,真的!是真的敲的我頭皮發麻,精神失常,差點放棄了這個小程序,直到我發現導入那兩個字。于是我在桌面上建了記事本把它改成了**.json**格式,里面的數據都用對象的形式敲出來,但是一定要注意格式(細心,一定要細心),否則導入時會失敗。數據格式及內容如下

此數據在集合名為 ShanghaiEnglish 當中所有數據都包含在articles中及下標為0的數據中

然后articles中有41條數據article為文章列表內容,id這個字段用于邏輯匹配

article里面的articleid時文章id,typeListId與上一個數據表中的id一致

云存儲

這個小程序中我主要用云存儲儲存圖片來獲取圖片地址

點擊第一張圖的左側文件名部分會出現第二張圖中的信息復制下載地址可以在瀏覽器中訪問圖片

由于數據實在太多手擼了幾千行假數據(爬蟲真的是很好的東西,可惜我還不太會,等我寫完這個再學),不想繼續造假了,所以我放過了自己,頁面有些地方不好看,你也放過我

頁面邏輯的實現

首頁跳轉至文章列表頁

我就直接上代碼

import {
  API_BASE 
 } from '../../config/api'
復制代碼

由于我把EasyMock的放在了config文件夾的api.js中首先在index.js中引入EasyMock

Page({
  data: {
    navigation:[],
    advertPic:[],
    article:[]
  },
  toSearch:function() {
    wx.navigateTo({
      url: '/pages/search/search',
    })
  },
  onPullDownRefresh() {
    wx.showLoading({
      title: '玩命加載中',
    })
    wx.request({
      url: API_BASE,
      success: (res) => {
        wx.hideLoading();
        wx.stopPullDownRefresh()
      }
    })
  },

  onLoad: function() {
    wx.showLoading({
      title: '玩命加載中',
    })
    self = this
    wx.request({
      url: API_BASE,
      data: {},
      method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 設置請求的 header
      success: function(res){
        // success
        console.log(res)
        self.setData({
          advertPic:res.data.data.advertPic,
          navigation:res.data.data.navigation,
          article:res.data.data.article
        })
        wx.hideLoading();
      },
      fail: function() {
       wx.showModal({
            title: '提示',
            content: 您的網絡狀態不佳,
            showCancel:false
        })
      },
      complete: function() {
        // complete
      }
    })
復制代碼

onPullDownRefresh實現下拉刷新,當數據沒有請求到的時候,現實玩命加載中,當數據請求成功以后消失。 在小程序onLoad(頁面加載)生命周期中,用 wx.request API請求easymock中的數據,并將數據放入data中,請求前進行 wx.showLoading請求成功 wx.hideLoading();失敗則顯示網絡狀況不佳(自從寫了這個小程序我就曉得了這些個小程序,要真的是數據有問題請求不到,就說我網不好,我可能以前都被騙到過,我太單純了)

<view class="article-content">
          <navigator wx:for="{{article.typeList}}" wx:key="{{typeList.lId}}" wx:for-item="typeList" url="../articlels/articlels?id={{typeList.lId}}&navigationText={{typeList.navigationText}}" class="article-list" hover-class="none">
            <view class="article-list__titlt">{{typeList.listTitle}}</view>
            <view class="article-list__des">{{typeList.listdes}}</view>
          </navigator>
        </view>
復制代碼

由于從首頁點進去以后標題不同所以在頁面跳轉中傳了navigationText, 又由于需要在下一個頁面判斷這是在首頁的哪個list上點進來的,所以又傳了個id到articlels頁面

// miniprogram/pages/articlels/articlels.js
const db = wx.cloud.database(); //獲取數據庫引用
復制代碼
data: {
  },

  /**
   * 生命周期函數--監聽頁面加載
   */
  onLoad: function(options) {
    wx.showLoading({
      title: '玩命加載中',
    })
    let that = this
    // console.log(options)
    wx.setNavigationBarTitle({ // 設置當前標題
      title: options.navigationText
    })
    db.collection("ShanghaiEnglish").get().then(res => {
       let data = res.data[0].articles.find((item) => {
        return item.id == options.id;
        // console.log(data.article)
      })
      that.setData({
        articles:data.article,
        totalId:data.article.length,
        typeListId:data.article.typeListId
      })
    })
    wx.hideLoading();
  },
復制代碼

在onLoad中 通過options.xxx獲取上一個頁面傳過來的值。如在

wx.setNavigationBarTitle({ // 設置當前標題
      title: options.navigationText
    })
復制代碼

通過options.navigationText獲取navigationTitle的值并通過 wx.setNavigationBarTitle這個API進行設置

db.collection("ShanghaiEnglish").get().then(res => {
       let data = res.data[0].articles.find((item) => {
        return item.id == options.id;
        // console.log(data.article)
      })
復制代碼

這段代碼主要獲取數據庫中下標為0的數據(所有數據)中的articles里的id字段與index頁面傳入的id值相等的整個article數組,即對應的文章列表 然后再通過

that.setData({
        articles:data.article,
        totalId:data.article.length,
        typeListId:data.article.typeListId
      })
復制代碼

將數據放入data中。articles是文章列表,用來渲染頁面的。totalId表示的是articles的文章總數(不寫文章不知道,一寫文章就發現應該把名字設置為total沒有Id的),typeListId就是文章屬于哪一個類型的id啦。

<navigator url="../content/content?id={{item.articleId}}&totalId={{totalId}}&typeListId={{typeListId}}" class="articlesection-list" hover-class="none" wx:for="{{articles}}" wx:key="articleId">
            <view class="list-Left">
                <view class="list-Left__title">{{item.articledesc}}</view>
                <view class="list-Left__num">{{item.num}}</view>
            </view>
            <view class="list-Right">
                <image class="list-ight__img" src="{{item.img}}" />
            </view> 
        </navigator> 
復制代碼

然后又傳了值給下一個頁面。本段結束。請聽下回分解??蠢哿說幕澳踩バ菹⒒岫?/p>

文章列表頁到content頁以及下一篇功能的實現


我好累啊我不想說了,但是我一得說完。 上回說到通過跳轉傳了值,來我們來看看怎么用的。

that.setData({
      id:options.id,
      totalId:options.totalId,
      typeListId:options.typeListId
      })
    db.collection("ShanghaiEnglish").get().then(res => {
      let data = res.data[0].articles.find((item) => {
        return item.id == options.typeListId;
      })
      that.setData({
        article:data.article
      })
      let id = that.data.id
      that.setData({
        author: that.data.article[id].author,
        time:that.data.article[id].day,
        title:that.data.article[id].articledesc,
        content:that.data.article[id].content,
      })
    var content = that.data.content;
    WxParse.wxParse('content', 'html', content, that, 5);
    wx.setNavigationBarTitle({ // 設置當前標題
      title: that.data.title
    })
復制代碼

又雙叒來接收傳過來的值了,又要從數據庫里取值了,然后你會發現取值的這部分和上個頁面一毛一樣,為什么呢,因為我這個小程序不是又了思路再寫的,是一個頁面一個頁面慢慢實現的。而我又懶得封裝了。所以只能騙自己你們這樣看不用去別的頁面找方法,理解起來更方便。 我們假裝以及將完了取數據。然后我們通過上個頁面傳過來的文章自己本身的id其實也就是下標去完數據源里面塞數據就像這樣。

let id = that.data.id
      that.setData({
        author: that.data.article[id].author,
        time:that.data.article[id].day,
        title:that.data.article[id].articledesc,
        content:that.data.article[id].content,
      })
復制代碼

然后內容部分就渲染出來了,然后講下一部分

下一篇功能的實現

<view class="footer-share" bindtap="nextArticle" data-id='{{id}}'>
            <image class="footer-share__icon" src="../../images/next.png"/>
            <view class="footer-share__text">下一篇</view>
        </view>
復制代碼
nextArticle: function(e) {
    let that = this
    let currentTargetID = e.currentTarget.dataset.id
    let totalId = that.data.totalId
    if(currentTargetID < totalId - 1){
      let nextTarget = Number(currentTargetID)+1
      wx.navigateTo({
        url: 'content?id=' + that.data.article[nextTarget].articleId + '&totalId=' + that.data.totalId + '&typeListId=' + that.data.article[nextTarget].typeListId
      })
    }
    else {
      wx.showModal({
        title: '提示',
        content: '別貪心哦~已經沒有內容了',
        showCancel: false,
        success: function (res) {
        } })
        return;
    }
復制代碼

我通過給下一篇的view綁定點擊事件然后還給了個data-id='{{id}}'用來點擊時獲取此文章的id屬性其實也就是下標。本來不用這個直接用that.data.id就行了,但是我覺得這樣洋氣一點就加了。 通過判斷currentTargetID也就是點擊下一篇時當時文章的id(下標)時候小于文章列表中總篇數減一。(為啥減一呢??因為我是先把下標加了一再進行跳轉操作的。),然后就像這樣

wx.navigateTo({
        url: 'content?id=' + that.data.article[nextTarget].articleId + '&totalId=' + that.data.totalId + '&typeListId=' + that.data.article[nextTarget].typeListId
      })
復制代碼

把下一篇文章的值傳到這個頁面。然后又進行上一階段的樸實的操作。最后呢就是沒有文章了給了個提示。這段結束。謝謝大家。下回再見

搜索頁面的實現

<van-search value="{{ value }}" placeholder="請輸入搜索關鍵詞" show-action bind:search="onSearch" bind:cancel="onCancel" bind:change="searchInput" />
復制代碼

首先我給這個組件綁定了三個bind:search="onSearch" bind:cancel="onCancel" bind:change="searchInput"事件,分別時搜索,取消還有輸入框改變。我們一個一個來看

再首先

onLoad: function (options) {
    let that = this
    db.collection("ShanghaiEnglish").get().then(res => {
      let data = res.data[0].articles
      const flatterArticle = data.reduce((pre, next) => {
        return pre.concat(next.article);
      }, [])
      that.setData({
        allAticle: flatterArticle
      })
      console.log(flatterArticle)
    })
  },
復制代碼

再onLoad中把所有articles中的所有article中的每一條數據都取了出來,并組成了一個新的數組allAticle。

// 輸入時匹配含有輸入內容的字段
 searchInput: function(e) {
    console.log(e.detail)
    // 將搜索內容存入緩存
    wx.setStorageSync('keywords', e.detail); 
    // 調用getList方法搜索數據
    let search_list = this.getList(e.detail);//通過getList方法查詢標題中包含此內容的所有文章
    if (e.detail == "") {
      search_list = [];
      this.data.is_hidden = true;
    } else {
      this.data.is_hidden = false;
    }
    this.setData({
      search_list,
      is_hidden: this.data.is_hidden
    });
  },
復制代碼

圖上注釋的挺詳細的,那么問題來了getList方法是啥?請往下看一丟丟

getList(attr) {
    let self = this
    return self.data.allAticle.filter(item => {
      return item.articledesc.toString().toLowerCase().indexOf(attr) > -1;
    });
  },
復制代碼

模糊查詢圈起來要考。這個代碼的意思就是在allArticle中查找標題中有這個attr的所有項。上面調用這個方法傳了個e.detail(輸入的內容)實參,所以也就是返回標題中含有輸入內容的所有項。

onSearch(e) {
  //  將緩存中的keywords值賦值給keywords
    const keywords = wx.getStorageSync('keywords');
    wx.showLoading({
      title: '請稍等',
    });
    setTimeout(() => {
      this.setData({
        articles: this.getList(keywords),//articles為所有包含這個keywords的項
        is_hidden: true
      });
      wx.hideLoading();
    }, 500);
  },
復制代碼

上面我覺得我標注的還蠻清楚的我就不講了

onCancel() {
    wx.switchTab({
      url: '/pages/index/index',
    })
  },
復制代碼

onCancel就是用來返回主頁面的,這里需要注意的就是,跳轉到tabbar頁面必須用wx.switchTab。

內容頁中的文章內容的完成

一開始看到內容頁里面沒篇文章結構都有不一樣的地點的時候我就佛了,不曉得怎么完成,直到我遇到了它 wxPaser它能將html的結構轉換為微信小程序的組件并渲染到頁面。先在 gitup 中下載wxPaser,然后放入目錄中做如下配置

<import src="../../wxParse/wxParse.wxml" />
復制代碼
@import"../../wxParse/wxParse.wxss";
復制代碼
var WxParse = require('../../wxParse/wxParse.js')
復制代碼

分別在content的wxml,wxss和js中引入wxPaser 然后再在js中

var content = that.data.content;
    WxParse.wxParse('content', 'html', content, that, 5);
復制代碼

WxParse.wxParse(bindName , type, data, target,imagePadding)

  • 1.bindName綁定的數據名(必填)
  • 2.type可以為html或者md(必填)
  • 3.data為傳入的具體數據(必填)
  • 4.target為Page對象,一般為this(必填)
  • 5.imagePadding為當圖片自適應是左右的單一padding(默認為0,可選)
  • 再在wxml中使用轉換過后的數據
<view class="artContent-body">
            <template is="wxParse" data="{{wxParseData:content.nodes}}" />
        </view>
復制代碼

還可以在wxss中給你的htmlclass類加上樣式

最后還沒完還另外加一個商城tap切換功能

看到很多人用是否hidden來操作,我覺得tab一多太麻煩了,所以發動了一下聰明的小腦袋瓜

<view class="list {{curIndex === index ? 'listActive' : ''}}" bindtap="toList" data-id="{{item.id}}">{{item.name}}</view>
復制代碼
toList: function (e) {
    let that = this
    let currentId = e.currentTarget.dataset.id
    that.setData({
      curIndex: e.currentTarget.dataset.id,
      typeList: that.data.typeLists[currentId].typeList
    })
  },
復制代碼

主要的代碼就上面幾行,代碼我放在gitup了可以自己拿哦,隨便拿不要客氣

分享至 : QQ空間
收藏
原作者: yuhan0927 來自: 掘金