微信小程序-滬江英語(資訊類)+商城商品列表切換功能

首先說段pi話,我是一個菜雞前端小白,我不只是菜雞前端我還沒過英語四級,如今大三了有點着急,可是我相信我會過的,因此我選擇仿了一個跟英語有關的小程序想着可以潛移默化的受到影響,這個小程序就是標題所說的「滬江英語」(黑體加粗)。這是我作的第一個小程序,可是大家不能由於我菜就不往下看了說不定就能有些收穫呢你說是吧(嘿嘿嘿嘿嘿)html

項目預覽及開始前的準備

項目預覽

開始前準備及使用工具

  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;
}
複製代碼

主題頁沒啥能夠介紹的因此就不介紹了node

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

數據的構建

Easy-Mock

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

正經的我要開始告訴大家了。首先我主頁的數據是在 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>
複製代碼

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

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

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

<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**格式,裏面的數據都用對象的形式敲出來,可是必定要注意格式(細心,必定要細心),不然導入時會失敗。數據格式及內容以下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> 
複製代碼

而後又傳了值給下一個頁面。本段結束。請聽下回分解。看累了的話您也去休息會兒

文章列表頁到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了能夠本身拿哦,隨便拿不要客氣

結語

GitHub地址 個人第一篇文章終於寫完了!!!(撒花撒花撒花~) 但願 天下無雙儀態萬千母儀天下活力四射魅力無邊婀娜多姿人間極品美得超越了凡間全部事物氣若幽蘭蓮步生花沉魚落雁閉月羞花國色天香傾國傾城花容月貌豔如桃李千嬌百媚如花似玉楚楚可人亭亭玉立絕世容顏眉清目秀清的小姐姐 和 一表人才博學多才彬彬有禮才貌雙全鶴立雞羣翩翩少年神機妙算儀表不凡氣宇軒昂眉清目秀玉樹臨風劍眉星眸清新俊逸挺鼻薄脣風流風倜儻瀟灑英俊古雕刻畫淡定優雅飄逸寧人探扇淺笑俊美無濤氣宇軒昂風度翩翩儀表堂堂的小哥哥 能給我一個star!!(加粗)也但願各位能不吝賜教,帶我和個人技術脫離底層走向巔峯 愛您!尊敬您!

相關文章
相關標籤/搜索