心理カウンセリング_WeChatミニプログラムプロジェクトの実戦、含む:注釈図、効果図、ビデオ、ソースコード

1. プロジェクト概要

1.1 チュートリアルガイド

        この一連のチュートリアルはプロジェクト指向であり、静的ページの実装から、バックグラウンド データのモック サービスの構築、そして最後にフロントエンドとバックエンドのデータ相互作用まで、WeChat アプレット プロジェクトの完全なセットをゼロから構築します。

        この一連のチュートリアルは、オンラインの WeChat アプレット アプリケーションのシミュレーションです: Shifang Zhiyu の実現。

        この一連のチュートリアルに関連する資料、コード、ビデオが必要な場合は、私にプライベート メッセージを送信するか、コメント欄にメールを残してください。

1.2 群衆に適しています

        特定の HTML/CSS/JavaScript の基礎があり、習熟している必要はありません。

       一定の基礎を持っている学生は、チュートリアルのドキュメントに従ってプロジェクトを徐々に理解することができます.この一連のチュートリアルは、基礎がゼロの学生にも適しています.サポートビデオでは、説明はゼロベーシックの方法で提供されます.

1.3 プロジェクトのレンダリング

表紙

 相談ページ

コースページ

マイページ

 記事一覧ページ

 コンサルタント詳細ページ 

ログインページ

登録ページ

1.4 サポート情報

レンダリング

注釈付きマップ

切图素材

動画説明

2. プロジェクト環境構築

2.1 開発ツールのダウンロードとインストール

        1. WeChat 開発者ツールをダウンロードします:
                https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
        2. オペレーティング システムのバージョンに対応するツールをダウンロードします。

        3. インストールの注意事項:
                学習プロセス中に、さまざまなツールをインストールします;
                3.1 中国語のディレクトリを避けるようにしますが、国内の開発ツールは実際に中国語のディレクトリに表示される場合があります;
                3.2 スペース、特殊記号を避けてください (_特殊記号に要約されていません);
                3.3 C ドライブへのインストールを避けるようにしてください. ディスクが多い場合は、ディスクを使用してソフトウェアをインストールできます. ディスクが少ない場合は、フォルダを定義して、ソフトウェアを特別にインストールします. 4. インストール手順 4.1 ダブルクリック
    
        wechat_devtools_1
                . 05.2108130_x64.exe をインストールします
                4.2 インストール ウィザード インターフェイスに入り、直接 [次へ] をクリックします
                4.3 使用許諾契約インターフェイスに入り、[同意する] をクリックします
                4.4 インストール ディレクトリ (3 を参照)、私のインストール ディレクトリを選択します: D:\Tools\WeChat web開発者ツール で、[インストール] をクリックします
                4.5 インストールが完了するのを待ち、[完了] をクリックします

2.2 アカウント登録

        1. WeChat アカウントが必要です.WeChat 開発者ツールを使用するには、WeChat を通じてログインする必要があります。

        2. ミニ プログラム アカウントを持っている必要があり、最後にミニ プログラム アカウントを WeChat ユーザーにバインドする必要があります; バインド後、あなたの WeChat アカウントはミニ プログラムの管理者になります;

        3. 1 つの WeChat アカウントで、多数の WeChat ミニ プログラムをバインドできます。

        4. アプリケーションアドレス: https://mp.weixin.qq.com/cgi-bin/wx?token=&lang=zh_CN
                4.1 ページの下部にある [登録に進む] ボタンをクリックします
                4.2 ログイン用のメールアドレスが必要ですアカウント、QQ、126、163、Yahoo などを使用できます; 126
                    メールボックスを申請します;
                4.3 アカウント情報: アカウント番号、パスワード、確認コードおよびその他の情報を入力すると、アクティベーション リンクがメールボックスに送信されます;
                4.4 電子メールの有効化: メールボックスに移動して有効化;
                4.5 情報登​​録:
                        登録国/地域: 中国本土
                        サブジェクト タイプ: 個人
                        サブジェクト情報登録: ID カード名、ID カード番号、管理者の携帯電話番号など
                4.6 送信後完了したら、クリックしてポップアップのアプレットに移動します。

2.3 プロジェクトの構築

        1. デスクトップの WeChat 開発者ツール アイコンをダブルクリックします. 初めて使用する場合は、コードをスキャンして WeChat アカウントからログインする必要があります。

        2. 左側: [ミニ プログラム アイテム] -> [ミニ プログラム] を選択します。

        3. 右側: + 記号をクリックして WeChat アプレットを作成します。

        4. アプレットを作成するためのオプション:
                プロジェクト名: sfzy
                ディレクトリ: D:\WeChatProjects\sfzy
                AppID: 登録した AppID を貼り付けます;
                        左メニュー: 開発管理 -> 開発設定 -> AppID を見つけます
                開発モード: 小さなプログラム
                バックエンド サービス:クラウド サービス
                言語: JavaScript
    
        5. [OK] をクリックして、WeChat の小さなプログラム プロジェクトを作成します。すべての WeChat アプレットが作成されると、いくつかのデモ コードが付属します。

2.4 開発者ツール インターフェイスの紹介

2.4.1 3 つの主要地域

        シミュレータ エリア:実際のマシン環境、さまざまな携帯電話でのコードの基本的な効果をシミュレートします; 左上隅でモデル、パーセンテージ、フォント サイズなどを選択できます; モデル: 主に解像度に依存します
                ;対応するメーカーのブランドを見つけるため; 本当に混乱している場合は、カスタマイズできます;
                表示比率: 効果をより完全に見ることができます;
                フォント サイズ: 変更しないでください, 16 で十分です;
                注: WeChat アプレットを開発する場合、モデルの推奨はiphone6 / 7 / 8を選択することです

        エディタ領域:プロジェクト構造ディレクトリと編集コード;
                リソース マネージャとエディタの 2 つの部分が含まれます;
                リソース マネージャ: プロジェクト ディレクトリ構造

        デバッガー領域:コードのデバッグ。

2.4.2 メニューバー

        1. アバター: ログイン ユーザーの切り替えに使用されます。

        2. シミュレーター、エディター、デバッガー: 3 つの主要な領域を開いたり閉じたりするために使用される 3 つのボタン

        3. コンパイル モード: コンパイル モードを切り替えることができます.
                通常は、デフォルトで開いているプロジェクトのホームページをコンパイルします.
                コンパイル ドロップダウン メニューをクリックし、[コンパイル モードの追加] を選択します.
                        モード名: カスタム、中国語を表示できます;
                        開始ページ: モードに対応するページを選択し、
                        [OK] をクリックします。

        4. コンパイル ボタン: 手動コンパイル;

        5.プレビューボタン:QRコードが表示され、WeChatでコードをスキャンすると、携帯電話で効果を確認できます。

        6.実機のデバッグ:携帯電話でプレビューし、デバッグプラットフォームを通じて実際のフィードバックを確認します。

        7. キャッシュのクリア: キャッシュ データのクリア

        8. アップロード: コードを WeChat アプレット サーバーにアップロードします。

        9. 詳細: アプレットの基本情報設定が含まれます。

3. 静的ページの実装

3.1 ホームページ

3.1.1 ナビゲーションバーとタブバー

グローバル構成の概要

        WeChat アプレットでのナビゲーション バーと tabBar の実装は構成によって実現されますが、これはモバイル端末の開発とは異なります。

        参照ドキュメント: https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
        
        ミニ プログラムの構成は 3 つの部分に分かれています。
                グローバル構成: WeChat ミニ プログラムのグローバル構成。全体のビューポート (ビジュアル ウィンドウ) 設定です;
                ページ構成: このページのウィンドウ パフォーマンスを構成します。
                サイトマップ構成: WeChat アプレットのインデックス作成ルールの構成。

        ミニ プログラムのルート ディレクトリにある app.json ファイルは、WeChat ミニ プログラムをグローバルに構成するために使用されます。ファイルの内容は、次のプロパティを持つ JSON オブジェクトです。

entryPagePath

        アプレットのデフォルトの起動パス (ホームページ) を指定します。一般的なシナリオは、WeChat チャット リスト ページから開始する、アプレット リストを開始する、などです。pages 空白のままにすると、デフォルトでリストの最初の項目になります 。ページ パスを含むパラメーターはサポートされていません。

{
  "entryPagePath": "pages/index/index"
}

ページ

        アプレットがどのページから構成されているかを指定するために使用され、各項目はページのパス (ファイル名を含む) 情報に対応します。ファイル名にファイルサフィックスを付ける必要はありません。フレームワークは、処理 する場所に対応する、 、 .jsonの 4 つのファイルを自動的に見つけます  。.js.wxml.wxss

        指定されていない 場合entryPagePath 、配列の最初の項目はアプレットの最初のページ (ホームページ) を表します。

        アプレットでページを追加/削除するには、ページ配列を変更する必要があります。

        4 つの tabBar ページを定義します。

{
    "pages": [
        "pages/index/index",
        "pages/consult/consult",
        "pages/course/course",
        "pages/my/my"
    ]
}

        アプレットのステータス バー、ナビゲーション バー、タイトル、およびウィンドウの背景色を設定するために使用されます。

属性 タイプ デフォルト 説明 最小バージョン
ナビゲーションバー背景色 HexColor #000000 などのナビゲーション バーの背景色 #000000
ナビゲーションバーテキストスタイル ナビゲーション バーのタイトルの色、  black / のみをサポートwhite
ナビゲーションバーのタイトルテキスト ナビゲーション バーのタイトル テキストの内容
ナビゲーションスタイル デフォルト ナビゲーション バー スタイルは、次の値のみをサポートします:
default デフォルト スタイル
custom のカスタム ナビゲーション バー。右上隅のカプセル ボタンのみが予約されています。注 2 を参照してください。
iOS/Android WeChat クライアント 6.6.0、Windows WeChat クライアントはサポートしていません
背景色 HexColor #ffffff ウィンドウの背景色
backgroundTextStyle 暗い ドロップダウン ローディングのスタイルは、  dark / のみをサポートします。light
backgroundColorTop #ffffff トップ ウィンドウの背景色。iOS でのみサポートされています。 WeChat クライアント 6.5.16
backgroundColorBottom #ffffff 下部ウィンドウの背景色。iOS でのみサポートされています WeChat クライアント 6.5.16
enablePullDownRefresh ブール値 間違い グローバル プルダウン リフレッシュを有効にするかどうか。
onReachBottomDistance 番号 50 ページ プル ボトム イベントがトリガーされたときのページの下部からの距離 (px)。
ページの向き 肖像画 画面回転設定、  サポート auto // portraitlandscape
  • 注 1:「#ff00ff」などの HexColor (16 進数の色の値)
  • 注2:約navigationStyle
    • 7.0.0 未満の iOS/Android クライアント バージョンは、でnavigationStyle のみ app.json 有効です。
    • iOS/Android クライアント バージョン 6.7.2 以降、navigationStyle: custom Web ビュー コンポーネントに対しては無効です
    • カスタムを有効にした後、バージョンの低いクライアントに互換性を持たせる必要があります。古いビジュアルに簡単に切り替えるために、開発者ツールのベース ライブラリのバージョンを 1.7.0 に切り替えます (最小バージョンを表すものではありません。デバッグ用のみです)。
    • Windows クライアント 3.0 以降では、より多くのデスクトップ ソフトウェア エクスペリエンスをユーザーに提供するために、アプレット ウィンドウのナビゲーション バーが統合され、navigationStyle: custom 機能しなくなりました。

        グローバル ウィンドウの構成は次のとおりです。

{
    "window": {
        "backgroundTextStyle": "light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "十方智育",
        "navigationBarTextStyle": "black",
        "navigationStyle": "default",
        "backgroundColor": "#eee",
        "onReachBottomDistance": 60
    }
}

タブバー

        アプレットがマルチタブ アプリケーション (クライアント ウィンドウの下部または上部にページを切り替えるためのタブ バーがある) の場合、タブ バーのパフォーマンスと、タブが切り替えられたときに表示される対応するページを、 tabBar 構成アイテム。

属性 タイプ 必要 デフォルト 説明 最小バージョン
HexColor はい タブのテキストのデフォルトの色は、16 進数の色のみをサポートします
選択した色 HexColor はい タブ上のテキストが選択されているときの色は、16 進数の色のみをサポートします
背景色 HexColor はい タブの背景色は、16 進数の色のみをサポートします
ボーダースタイル いいえ タブバーの上枠の色は black / のみ対応white
リスト 配列 はい タブのリスト。 list 詳細については、プロパティの説明を参照してください。少なくとも 2 つ、最大で 5 つのタブ
位置 いいえ tabBar の位置は bottom / のみをサポートしますtop
カスタム ブール値 いいえ 間違い tabBar のカスタマイズ、詳細を参照

このうち、list は配列を受け入れ、最小 2 タブ、最大 5 タブのみ構成できますタブは配列順にソートされ、各項目はオブジェクトであり、そのプロパティ値は次のとおりです。

属性 タイプ 必要 例証する
ページパス はい ページ パス。ページの最初に定義する必要があります
文章 はい タブ上のボタンテキスト
アイコンパス いいえ 画像パス、アイコン サイズは 40 KB に制限されています。推奨サイズは 81px * 81px です。ネットワーク イメージはサポートされていません。
の場合 position 、 top アイコンは表示されません。
selectedIconPath いいえ 選択時の画像パス。アイコンのサイズは 40kb に制限されています。推奨サイズは 81px * 81px で、ネットワーク画像はサポートされていません。
の場合 position 、 top アイコンは表示されません。

TabBar は次のように構成されます。

{
  "tabBar": {
    "color": "#898989",
    "selectedColor": "#87cefa",
    "list": [{
        "pagePath": "pages/index/index",
        "text": "主页",
        "iconPath": "/images/@2x_home_line.png",
        "selectedIconPath": "/images/@2x_home.png"
      },
      {
        "pagePath": "pages/consult/consult",
        "text": "咨询",
        "iconPath": "/images/@2x_talk_line.png",
        "selectedIconPath": "/images/@2x_talk.png"
      },
      {
        "pagePath": "pages/course/course",
        "text": "课程",
        "iconPath": "/images/@2x_class_line.png",
        "selectedIconPath": "/images/@2x_class.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "/images/@2x_my_line.png",
        "selectedIconPath": "/images/@2x_my.png"
      }
    ]
  }
}

フル構成

{
  "entryPagePath": "pages/index/index",
  "pages": [
    "pages/index/index",
    "pages/consult/consult",
    "pages/course/course",
    "pages/my/my"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "十方智育",
    "navigationBarTextStyle": "black",
    "navigationStyle": "default",
    "backgroundColor": "#eee",
    "onReachBottomDistance": 60
  },
  "tabBar": {
    "color": "#898989",
    "selectedColor": "#87cefa",
    "list": [{
        "pagePath": "pages/index/index",
        "text": "主页",
        "iconPath": "/images/@2x_home_line.png",
        "selectedIconPath": "/images/@2x_home.png"
      },
      {
        "pagePath": "pages/consult/consult",
        "text": "咨询",
        "iconPath": "/images/@2x_talk_line.png",
        "selectedIconPath": "/images/@2x_talk.png"
      },
      {
        "pagePath": "pages/course/course",
        "text": "课程",
        "iconPath": "/images/@2x_class_line.png",
        "selectedIconPath": "/images/@2x_class.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "/images/@2x_my_line.png",
        "selectedIconPath": "/images/@2x_my.png"
      }
    ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

組み込みのログ ページを削除する

        1. アプレットのルート ディレクトリにある app.json ファイル内のページのログ パス構成を削除します;
        2. ログ ディレクトリを削除します;

3.1.2 検索ボックス

        エフェクト ダイアグラムと注釈ダイアグラムを組み合わせて分析し、結論を導き出すことができます: 検索ボックス領域は 2 つのコンテナー (外側のコンテナー
                と内側のコンテナー) で構成され、
                外側のコンテナーは内側のコンテナーを包み込み、内側のコンテナーはちょうど内側にあります。外箱の中心(横縦中心)位置

        WeChat アプレットのページは、js ファイル、json ファイル、wxml ファイル、wxss ファイル wxml ファイル → html ファイル
                wxss
                ファイル → css ファイル
                js ファイル → js ファイル
                json ファイル → 設定ファイル
                        app.json Globalの 4 つのファイルに対応しています。構成ファイル
                        index/my/course/..json ファイル ページ構成ファイル

ページ構造

        1. index.wxml のデモ コードを削除します。

        2. index.wxml ファイルで 2 つのネストされたビューを定義する レイアウト コンテナーの特性: 幅はビューポートの 100% を占めますが、高さはコンテンツに従います; WeChat アプレットでは、ビューはレイアウト コンテナーを定義するために使用され
                ます; コンテンツはビューで定義されます。

        3. 内部ビューに画像とテキストを導入する;
                WeChat アプレットで、画像コンポーネントを使用して画像を定義する; 画像コンポーネントの src 属性を介して画像をインポートする;
                WeChat アプレットで、いくつかのテキストを定義し、テキスト コンポーネントを使用できます;
    
        4. 構造を作成した後、期待どおりの効果が得られない場合は、装飾を追加する必要があります; 装飾を追加するには、さまざまな要素を区別する必要があり、コンポーネントに id 属性を追加できます。

<!-- 顶部搜索框的实现 -->
<view id="searchOuterView">
  <view id="searchInnerView">
    <image src="/images/@2x_find.png"></image>
    <text> 搜索</text>
  </view>
</view>

スタイルの実装

        WeChat アプレットのスタイルは、対応する wxss ファイルに書き込まれます;
        
        1. index.wxss のデモ スタイル コードを削除します。

        2. 検索画像が大きすぎるため、画像のサイズを設定できます;
                searchInnerView
                #searchInnerView > image -> id を searchInnerView コンポーネントの画像コンポーネントとして選択し
                、画像内の pt をマークして、画像を見つけます。 WeChat アプレットで使用される単位は rpx です;
                1pt = 1px = 2rpx;
    
        3. 検索テキストのサイズと色を設定します;
                検索テキストの前にスペースを追加して、画像とテキストの間に少しスペースを空けます;

        4. searchInnerView では、画像とテキストが中央に配置され、コンテンツが中央に配置されます。

        5. searchInnerView の幅、高さ、背景色、境界線、および丸みを帯びた角を設定します;
    
        6. 画像とテキストは垂直および水平方向に中央揃えされ、整列されます;    
                6.1 searchInnerView のテキストの行の高さを設定します
                6.2 垂直方向の配置を設定しますそれぞれ絵と文章

        7.
                searchOuterView の内側の余白を設定します。 内側の余白: 境界線とコンテンツの間の距離。

/* 顶部搜索框样式 */
#searchOuterView{
  /* 设置内边距 */
  padding: 15rpx;
}

#searchInnerView{
  /* 内容居中 */
  text-align: center;
  /* 设置宽高 */
  width: 720rpx;
  height: 58rpx;
  /* 设置背景颜色 */
  background: #EEEEEE;
  /* 设置边框 */
  border: 2rpx solid #ECECEE;
  /* 设置边框圆角 */
  border-radius: 8rpx;
  /* 设置行高 */
  line-height: 52rpx;
  /* 设置边框包含在宽高之内 */
  box-sizing: border-box;
}

#searchInnerView > image{
  /* 给图片设置宽和高 */
  width: 36rpx;
  height: 36rpx;
  /* 设置垂直对齐方式 */
  vertical-align: middle;
}

#searchInnerView > text{
  /* 给文字设置大小 */
  font-size: 24rpx;
  /* 给文字设置颜色 */
  color: #B2B2B2;
  /* 设置垂直对齐方式 */
  vertical-align: middle;
}

3.1.3 カルーセル画像

ページ構造


        WeChat アプレットのカルーセル マップは、WeChat がカルーセル マップコンポーネント        を提供するため、実装が特に簡単です
    
        。スワイパー コンポーネント ドキュメントの下部にある wxml から、スワイパー コンポーネントの関連コードをコピーします。

        2. swiper コンポーネント ドキュメントの下部にある JavaScript からデータ data をコピーして index.js の data に配置し、
                index.js 内の元のデータ data を削除します。

        3. 各スライダーには画像が表示されるため、swiper-item のビューを画像に変更します。

        4. swiper-item は、ブロック wx:for の構文で定義されます. wx:for は、参照される js 内のデータです. データに複数の対応する配列値がある場合、複数の swiper-item が生成されます; 4.1
                wx : 参照用の値を imgUrls に変更し、名前と意味を確認します
                4.2 使用する画像のパスを imgUrls 配列に記述します
                4.3 対応する画像パスを画像コンポーネントに導入します
    
        5.スワイパー関連の属性による自動カルーセル、カルーセル間隔、カルーセル方向など;
                インジケーター ドット パネルを表示するかどうか インジケーター インジケーター
                インジケーター アクティブな色 インジケーター アクティブな色 現在選択されているインジケーター ポイントの色 自動再生 間隔
                を自動的に切り替えるかどうか 自動
                切り替え 時間間隔 期間
                スライド アニメーションの継続時間
                円形 ジョイント スライドを使用するかどうか

<!-- 轮播图 -->
<!-- 
  swiper组件是用来定义滑块视图容器; swiper-item就是每一个滑块;
  我们需要展示三张图片,三张图片的轮播,那么也就是说需要三个swiper-item
-->
<swiper indicator-dots="{
   
   {indicatorDots}}" indicator-active-color="{
   
   {activeColor}}" autoplay="{
   
   {autoplay}}"
  interval="{
   
   {interval}}" duration="{
   
   {duration}}" circular="{
   
   {circular}}">
  <!-- 
    block是一个辅助性组件,它不会有任何展示效果; 
    wx:for 用来定义for循环,wx:for="数组"
    {
   
   {表达式}} wxml的插值表达式,从js的data里面引用值;
      {
   
   {background}},从js的data中获取background对应的值
    在wxml页面中需要使用的数据,我们最好都定义在data中
  -->
  <block wx:for="{
   
   {imgUrls}}" wx:key="*this">
    <swiper-item>
      <!-- swiper-item里面承载的是一张图片,不同的swiper-item承载的不同图片 -->
      <image src="{
   
   {item}}"></image>
    </swiper-item>
  </block>
</swiper>
data: {
    imgUrls: ['/images/img1.png', '/images/img2.png', '/images/img3.png'],
    indicatorDots: true,
    vertical: false,
    autoplay: true,
    interval: 3500,
    duration: 500,
    activeColor: "#fff",
    circular: true
  },

スタイルの実装

        1. アノテーションマップではカルーセル画像領域の高さを160ptと定義しているが、実際の開発ではより良い結果を示すために高さを調整したため、高さを200ptにし、スワイパーの高さを設定; 2.画像の幅を
    
        高に設定します。

/* 轮播图样式 */
swiper{
  height: 400rpx;
}

/* 选择swiper里面的后代元素image */
swiper image{
  width: 750rpx;
  height: 400rpx;
}

3.1.4 ナビゲーションメニュー

ページ構造

        アノテーション マップを分析した結果、大きなビューには 6 つの小さなビューが含まれ、各小さなビューには画像とテキストが含まれていることがわかりました。

        1. すべてのナビゲーション メニューを表示するビューを定義し、id を定義します: navView

        2. navView で 6 つのサブビューを定義し、それらのクラスを定義します: navItemView

        3. 各 navItemView で画像とテキストを定義します。

<!-- 导航菜单 -->
<view id="navView">
  <view class="navItemView">
    <image src="/images/@2x_ceping.png"></image>
    <text>心理测评</text>
  </view>
  <view class="navItemView">
    <image src="/images/@2x_yuyue.png"></image>
    <text>咨询预约</text>
  </view>
  <view class="navItemView">
    <image src="/images/@2x_dayi.png"></image>
    <text>心理答疑</text>
  </view>
  <view class="navItemView">
    <image src="/images/@2x_zhishi.png"></image>
    <text>心理知识</text>
  </view>
  <view class="navItemView">
    <image src="/images/@2x_FM.png"></image>
    <text>FM</text>
  </view>
  <view class="navItemView">
    <image src="/images/@2x_gongyi.png"></image>
    <text>公益中心</text>
  </view>
</view>

スタイルの実装

        WeChat アプレットでは、デフォルトですべての画像に指定された幅と高さが与えられます。

        1. navItemView ですべての画像の幅と高さを設定します。

        2. 画像の幅と一致する navItemView の幅を設定し、テキストが中央に配置されるように設定します;
                ビュー コンポーネントの特徴は、それが 1 行を占めることであり、幅と高さは時間で設定されます;
    
        3. navItemView が 1 行を占有しないようにする方法はたくさんありますが、モバイル側ではさらにフレックス レイアウトを使用する方法があります。フレックス レイアウトの
        チュートリアル: http://www.ruanyifeng.com/blog/2015/07/flex-grammar .html
                3.1 navView にフレックス レイアウトを適用し、フレックス レイアウトを採用した後、すべての子要素を 1 行に配置します; 3.2
                navView の折り返し表示を設定します; 3.3                 navItemView
                の左右の間隔を設定します。
navView の高さを設定します。
                3.5 navView の複数の軸の配置を設定します。

/* 导航菜单样式 */
#navView{
  /* 应用flex布局 */
  display: flex;
  /* 设置换行显示 */
  flex-wrap: wrap;
  height: 464rpx;
  /* 多轴线的垂直排列方式 */
  align-content:space-around;
  font-size: 26rpx;
  /* 字体加粗 */
  font-weight: bold;
}

.navItemView{
  width: 150rpx;
  text-align: center;
  /* 设置左右外边距 */
  margin: 0 50rpx;
}

.navItemView > image{
  width: 150rpx;
  height: 150rpx;
}

3.1.5 オンラインカスタマーサービス

        哲学: 無意味なコンポーネントやタグを追加しないでください。

        ページ全体に灰色の背景色を追加してから、必要なコンポーネントに白い背景色を追加します。

ページ構造

        1. オンライン カスタマー サービス関連のコンテンツを表示するビューを定義し、id を定義します。onlineView
    
        2. onlineView で画像とテキストを定義します。

<!-- 在线客服 -->
<view id="onlineView">
  <image src="/images/@2x_zixunpeixun.png"></image>
  <text> 咨询助理在线客服</text>
  <!-- 右箭头实现 -->
  <view class="arrow"></view>
</view>

スタイルの実装

        1. onlineView で画像の幅と高さを設定します。

        2. 高さ、背景色、上下の外側マージン、左右の内側マージンを設定し、onlineView の行の高さを設定します。

        3. onlineView テキストのフォント サイズとボールド フォントを設定します。
                設計図の 24pt は少し問題があります。必要なのは 26rpx だけです。
                ナビゲーション メニューのフォントを 26rpx ボールドに変更することを忘れないでください。

        4. 写真とテキストの配置。

右矢印が実装されました

        右矢印の実現: 正方形、上境界線と右境界線を定義し、45 度回転させてから、位置決めによって指定された位置に配置します。

        位置の設定: 矢印要素の絶対位置。親要素に位置属性が必要な場合は、親要素に対して相対的な絶対位置を使用します。
        Set position: relative for #onlineView; 親要素に position 属性を持たせます。

/* 在线客服样式 */
#onlineView{
  height: 88rpx;
  background: #fff;
  /* 设置上下外边距 */
  margin: 24rpx 0;
  /* 设置左右内边距 */
  padding: 0 30rpx;
  line-height: 88rpx;
  position: relative;
}

#onlineView > image{
  width: 60rpx;
  height: 60rpx;
  vertical-align: middle;
}

#onlineView > text{
  font-size: 26rpx;
  /* 字体加粗 */
  font-weight: bold;
  vertical-align: middle;
}

/* 右箭头的实现原理: 一个正方形,定义上/右边框,旋转45度 */
.arrow{
  width: 16rpx;
  height: 16rpx;
  border-top: 4rpx solid #999;
  border-right: 4rpx solid #999;
  /* 旋转45度 */
  transform: rotate(45deg);
  /* 调整位置 */
  position: absolute;
  right: 30rpx;
  top: 38rpx;
}

3.1.6 特集記事

ページ構造

        1. 記事のタイトル、すべての記事のリスト、その他の記事を表示するために使用されるビューを定義し、それに id: hotArticleView を追加します。

        2. 記事の一般的なタイトルを運ぶために使用されるビューを定義し、id を追加します: hotArticleTitleView

        3. 選択した 3 つの記事リストを表示する 3 つのビューを定義します. これらの 3 つのビューは同じ効果を持ちます. 違いは画像とテキストが異なることです. これらの 3 つのビューにクラスを追加します: articleView 4. articleView で左右の部分に分割され
    
        ます
                4.1 articleView に 2 つのサブビューを定義します.左側には画像が表示され、右側にはテキストが表示されます.右側のビューに class: articleContent を追加します. 4.2 articleContent を上下に分割し、2 つのサブビューを定義してクラスを追加します
                . : articleTitle、articleDesc;

        5. さらに表示することを示すために使用されるビューを定義し、それに id を追加します。moreView は、
                このビューのテキストと右矢印を定義します。

<!-- 精选文章 -->
<view id="hotArticleView">
  <!-- 文章总标题 -->
  <view id="hotArticleTitleView">
    精选文章
  </view>
  <!-- 文章列表 -->
  <view class="articleView">
    <view>
      <image src="/images/article01.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>
  <view class="articleView">
    <view>
      <image src="/images/article02.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>
  <view class="articleView">
    <view>
      <image src="/images/article03.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <!-- 查看更多 -->
  <view id="moreView"> 
    <text>查看更多</text>
    <view class="arrow"></view>
  </view>
</view>

 スタイルの実装

        1. 左右の内側の余白と背景色を hotArticleView に追加します。

        2. hotArticleTitleView の高さ、フォント サイズ、フォントの太さを設定し、境界線と行の高さを下げます。

        3. articleView で画像のサイズを設定します。

        4. フレックス レイアウト、上部と下部の内側のマージン、および下部の境界線を articleView に適用します。

        5. articleView で画像の右マージンを設定します。

        6. 右側の記事のタイトルと説明のテキスト サイズ、色、および行の高さを設定し、
                記事のタイトルを 28rpx に設定します。

        7. moreView の高さ、行の高さ、相対位置を設定します。

        8. moreView でテキストのサイズと色を設定します。

        9. hotArticleView に下マージンを追加します。

/* 精选文章 */
#hotArticleView{
  padding: 0 30rpx;
  background: #fff;
  margin-bottom: 24rpx;
}

#hotArticleTitleView{
  height: 88rpx;
  font-size: 30rpx;
  font-weight: bold;
  border-bottom: 1rpx solid #F1F1F1;
  line-height: 88rpx;
}

.articleView {
  display: flex;
  padding: 30rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
}

.articleView image{
  width: 120rpx;
  height: 120rpx;
  margin-right: 20rpx;
}

.articleTitle{
  font-size: 28rpx;
  font-weight: bold;
  line-height: 50rpx;
}

.articleDesc{
  font-size: 26rpx;
  color: #A9A9A9;
  line-height: 35rpx;
}

#moreView{
  height: 88rpx;
  line-height: 88rpx;
  font-size: 28rpx;
  color: #A6A6A6;
  position: relative;
}

3.1.7 回答要求

ページ構造

        ビューを定義し、id: askView を追加して、そこに画像を定義します。

<!-- 请求回答 -->
<view id="askView">
  <image src="/images/@2x_fudong.png"></image>
</view>

スタイルの実装

        1. 写真のサイズを設定する

        2. askView に固定位置を追加し (ページのコンテンツがどのようにスクロールされても、要素はウィンドウの指定された位置で一貫しています)、対応する位置を設定します。

/* 请求回答 */
#askView{
  position: fixed;
  bottom: 100rpx;
  right: 10rpx;
}

#askView > image{
  width: 100rpx;
  height: 100rpx;
}

3.2 相談ページ

3.2.1 ページタイトル

        以前に app.json でグローバル構成を作成し、タイトルを Shifang Zhiyu に設定しました。

        現在、相談予約ページのタイトルは Shifang Zhiyu ではないため、ページ構成を通じてグローバル構成をオーバーライドできます。
    
        ページ構成: https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html

        各アプレット ページは、.json ファイルを使用して、このページのウィンドウ パフォーマンスを構成することもできます。ページ内の構成項目は、現在のページの app.json のウィンドウ内の同じ構成項目を上書きします。ファイルの内容は、次のプロパティを持つ JSON オブジェクトです。

        グローバル構成のページ構成のすべての構成項目について説明しました。

        注: 書かれたページの効果を見やすくするために、編集モードを追加できます。

        Consult.json でページ タイトルを構成します。

{
  "usingComponents": {},
  "navigationBarTitleText":"咨询预约"
}

3.2.2 フィルターボックス

ページ構造

        1. ビューを定義し、それに id: filterView を追加します。

        2. filterView で画像とテキストを定義します。

<!-- 筛选框 -->
<view id="filterView">
  <image src="/images/@2x_touch.png"></image>
  <text> 点击筛选</text>
</view>

スタイルの実装

        1. filterView で画像のサイズを設定します。

        2. filterView でテキストのサイズとフォントの色を設定します。

        3. filterView のテキストの中央揃え、高さ、背景色、および行の高さを設定します。

        4. filterView で画像とテキストの垂直方向の配置を設定します。

/* 筛选框样式 */
#filterView{
  background: #87cefa;
  height: 88rpx;
  text-align: center;
  line-height: 88rpx;
}

#filterView > image{
  width: 48rpx;
  height: 48rpx;
  vertical-align: middle;
}

#filterView > text{
  font-size: 30rpx;
  color: #fff;
  vertical-align: middle;
}

3.2.3 コンサルタント一覧

ページ構造

        1. ビューを定義し、ID を指定します。consultListView は、すべてのコンサルタントをホストするために使用されます。

        2.consultListView でビューを定義し、class:consultView を定義します。

        3. ConsultView で 2 つのビューを定義します。左側のビューは写真を運ぶために使用され、右側のビューはコンサルタント情報を運ぶために使用されます。クラスを定義します: ConsultInfoView そのため、コンサルタント情報を 3 つのサブビューに入れます。コンサルタントの
                構造が実現され、残りはコピーして貼り付けることができます;
                将来データを結合する場合、実際には、ビューがループで使用され、データと同じ数のビューが使用されるため、必要なビュー構造は1つだけです;

    
        セレクター: ページ要素を選択し、それらにスタイルを追加するために使用;
                #xx は id に従って要素を選択します;
                .yy はクラスに従って要素を選択します;
                zz はコンポーネント名に従って要素を選択します
                親要素 > 子要素 親要素 親のすべての子要素を選択しますelement
                子要素の選択 親要素のすべての子孫要素 親
                要素 > 子要素:nth-child(num) 親要素の num 番目の子要素を選択します

<!-- 咨询师列表 -->
<view id="consultListView">
  <!-- 一个咨询师的结构 -->
  <view class="consultView">
    <view>
      <image src="/images/zxs01.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>张婧</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
  <view class="consultView">
    <view>
      <image src="/images/zxs02.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>憨豆</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
  <view class="consultView">
    <view>
      <image src="/images/zxs03.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>韩梅梅</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
  <view class="consultView">
    <view>
      <image src="/images/zxs04.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>李维嘉</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
  <view class="consultView">
    <view>
      <image src="/images/zxs05.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>刘诗诗</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
  <view class="consultView">
    <view>
      <image src="/images/zxs06.jpg"></image>
    </view>
    <view class="consultInfoView">
      <view>黎曼</view>
      <view>国家二级咨询师</view>
      <view>中国专业人才库全国心理学考评管理中心专家评委、中国全脑效能研能指导师...</view>
    </view>
  </view>
</view>

スタイルの実装

        1. ConsultListView の左右の内部マージンを設定します;
    
        2. ConsultView の上下の内部マージン、下の境界線、フレックス レイアウトを設定します;
    
        3. ConsultView の写真のサイズと右の外部マージンを設定します;
    
        4. 3 つのサブ要素を設定しますConsultInfoView、テキストのサイズ、太さ、色、行の高さをそれぞれ設定します。

/* 咨询师列表样式 */
#consultListView{
  padding: 0 10rpx;
}

.consultView{
  padding: 10rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
  display: flex;
}

.consultView image{
  width: 180rpx;
  height: 180rpx;
  margin-right: 10rpx;
}

.consultInfoView > view:nth-child(1){
  font-size: 34rpx;
  font-weight: bold;
  line-height: 50rpx;
}

.consultInfoView > view:nth-child(2){
  font-size: 30rpx;
  color: #5E5E5E;
  line-height: 50rpx;
}

.consultInfoView > view:nth-child(3){
  font-size: 24rpx;
  color: #A9A9A9;
  line-height: 40rpx;
}

3.2.4 ロード

ページ構造

        1. ビューを定義し、それに id を追加します: loadingView
    
        2. 画像とテキストを loadingView で定義するだけです;
    
        注: ローディング領域は、動的データと組み合わせて使用​​する必要があります. バックグラウンドからデータを取得する場合、データは取得されていませんまだ取得していない場合は、loadingView を表示し、データを取得した場合は、loadingView;

<!-- 正在加载 -->
<view id="loadingView">
  <image src="/images/loading.gif"></image>
  <text> 正在加载更多数据</text>
</view>

スタイルの実装

        1. loadingView で画像のサイズを設定します。

        2. loadingView でテキストのサイズを設定します。

        3. loadingView のテキストのセンタリング、高さ、背景色、行の高さを設定します。

        4. loadingView で画像とテキストの垂直方向の配置を設定します。

/* 正在加载样式 */

#loadingView{
  text-align: center;
  height: 88rpx;
  background: #F0EFF5;
  line-height: 88rpx;
}

#loadingView > image{
  width: 48rpx;
  height: 48rpx;
  vertical-align: middle;
}

#loadingView > text{
  font-size: 28rpx;
  vertical-align: middle;
}

3.3 コースページ

3.3.1 ページタイトルと検索ボックス

        ページ タイトルもページ構成によって実装されます。
    
        検索ボックスがコードの再利用を考慮していない場合は、ホームページのコードから関連する構造とスタイルを直接コピー アンド ペーストします。

3.3.2 ミニナビゲーション

ページ構造

        1. ビューを定義し、id を指定します: smallNavView;

        2. smallNavView で 3 つのサブビューを定義する

        3. サブビューは、それぞれ対応する画像とテキストを運ぶことができます。

<!-- 小导航 -->
<view id="smallNavView">
  <view>
    <image src="/images/@2x_online.png"></image>
    <text> 在线课程</text>
  </view>
  <view>
    <image src="/images/@2x_teacher.png"></image>
    <text> 师资团队</text>
  </view>
  <view>
    <image src="/images/@2x_gonggao.png"></image>
    <text> 咨询公告</text>
  </view>
</view>

スタイルの実装

        1. smallNavView ですべての画像のサイズを設定します;
    
        2. smallNavView でテキストのフォント サイズと色を設定します;

        3. smallNavView でビューの背景色、高さ、および行の高さを設定します。

        4. smallNavView でテキストと画像の垂直方向の配置を設定します。

        5. smallNavView のフレックス レイアウトを設定し、smallNavView のサブビューを 1 倍に拡大します。

        6. smallNavView のサブビューのテキスト センターを設定します。

        7. smallNavView の 2 番目のサブビューに対して、左右の境界線を設定します。

/* 小导航样式实现 */
/* 应用了flex布局的,我们称之为flex容器 */
#smallNavView {
  display: flex;
}

/* flex的子元素,我们称之为flex项目 */
#smallNavView > view{
  height: 88rpx;
  line-height: 88rpx;
  background: #87cefa;
  flex-grow: 1;
  text-align: center;
}

#smallNavView > view:nth-child(2){
  border-left: 2rpx solid #fff;
  border-right: 2rpx solid #fff;
}

#smallNavView image{
  width: 44rpx;
  height: 44rpx;
  vertical-align: middle;
}

#smallNavView text{
  font-size: 30rpx;
  color: #fff;
  vertical-align: middle;
}

3.3.3 カルーセル画像

        ホームページから関連する構造とスタイルをコピーして貼り付け、画像リソースを変更するだけです。

<!-- 轮播图 -->
<swiper indicator-dots="{
   
   {indicatorDots}}" indicator-active-color="{
   
   {activeColor}}" autoplay="{
   
   {autoplay}}"
  interval="{
   
   {interval}}" duration="{
   
   {duration}}" circular="{
   
   {circular}}">
  <block wx:for="{
   
   {imgUrls}}" wx:key="*this">
    <swiper-item>
      <!-- swiper-item里面承载的是一张图片,不同的swiper-item承载的不同图片 -->
      <image src="{
   
   {item}}"></image>
    </swiper-item>
  </block>
</swiper>
data: {
    imgUrls: ['/images/kc01.jpg', '/images/kc02.jpg', '/images/kc03.jpg'],
    indicatorDots: true,
    vertical: false,
    autoplay: true,
    interval: 3500,
    duration: 500,
    activeColor: "#fff",
    circular: true
  },

3.3.4 人気コース

ページ構造

        1. ビューを定義し、id を追加します: hotCourseView
    
        2. hotCourseView で hotCourseTitleView を定義して、一般的なタイトルを保持します
    
        3. hotCourseView で courseListView を定義して、4 つのコースを保持します。各コースはビューであり、それにクラスを追加します:
    
        courseView courseView の写真とテキスト。

<!-- 热门课程 -->
<view id="hotCourseView">
  <!-- 热门课程标题 -->
  <view id="hotCourseTitleView">
    热门课程
  </view>
  <!-- 课程列表 -->
  <view id="courseListView">
    <!-- 一门课程 -->
    <view class="courseView">
      <image src="/images/hotkc01.jpg"></image>
      <text>心理科普:巴纳姆效应</text>
    </view>

    <view class="courseView">
      <image src="/images/hotkc02.jpg"></image>
      <text>心理科普:巴纳姆效应</text>
    </view>

    <view class="courseView">
      <image src="/images/hotkc03.jpg"></image>
      <text>心理科普:巴纳姆效应</text>
    </view>

    <view class="courseView">
      <image src="/images/hotkc04.jpg"></image>
      <text>心理科普:巴纳姆效应</text>
    </view>
  </view>
    
  <!-- 查看更多 -->
  <view id="moreView"> 
    <text>查看更多</text>
    <view class="arrow"></view>
  </view>
</view>

スタイルの実装

        1. hotCourseView の左右の内側マージンを設定します。

        2. hotCourseTitleView の高さ、テキスト サイズ、ボールド、テキスト センター、行の高さを設定します。

        3. courseListView ですべての写真のサイズを設定します。

        4. courseView の幅を画像と一致するように設定します。

        5. courseListView の主軸上の項目のフレックス レイアウト、改行、配置を設定します。

        6. courseView の下マージンを設定し、テキストを中央に配置します。

/* 热门课程样式 */
#hotCourseView{
  padding: 0 20rpx;
}

#hotCourseTitleView{
  height: 108rpx;
  line-height: 108rpx;
  font-size: 30rpx;
  text-align: center;
  font-weight: bold;
}

#courseListView{
  display: flex;
  flex-wrap: wrap;
  /* 项目在主轴上的对齐方式 */
  justify-content: space-between;
}

.courseView{
  width: 346rpx;
  margin-bottom: 40rpx;
  text-align: center;
}

#courseListView image{
  width: 346rpx;
  height: 220rpx;
}

#moreView{
  height: 88rpx;
  line-height: 88rpx;
  font-size: 28rpx;
  color: #A6A6A6;
  position: relative;
}

.arrow{
  width: 16rpx;
  height: 16rpx;
  border-top: 4rpx solid #999;
  border-right: 4rpx solid #999;
  /* 旋转45度 */
  transform: rotate(45deg);
  /* 调整位置 */
  position: absolute;
  right: 30rpx;
  top: 38rpx;
}

3.4 マイページ

3.4.1 ユーザー情報表示

ページ構造

        1. ビューを定義し、id を与えます: userInfoView;

        2. userInfoView で 3 つのサブビューを定義します。これらのサブビューは、それぞれニックネーム、由来、およびポイントを保持するために使用されます。

<!-- 用户信息展示区域 -->
<view id="userInfoView">
  <view>昵称: 少年先锋队员</view>
  <view>来自: 河南·郑州</view>
  <view>积分: 1080</view>
</view>

スタイルの実装

        1. userInfoView の背景色、上下のパディング、およびテキストの中央揃えを設定します;
                パディングの異なる値の表現:
                * 上下左右のパディング
                ** 上下左右のパディング
                ** * 上、左、右、および下のパディング 距離
                **** 上、右、下、左のパディング (時計回り)
                注: 親要素のコンテンツに設定されたスタイルは、子要素に継承できます。例: font色、フォント サイズ、テキストのセンタリング。

        2. 3 つのサブビューのテキストのサイズと色を設定します。

        3. 2 番目のサブビューの上下のマージンまたは内側のマージンを設定します。

/* 用户信息展示样式 */
#userInfoView{
  background: #87cefa;
  padding: 30rpx 0 40rpx;
  text-align: center;
}

#userInfoView > view:nth-child(1){
  color: #fff;
  font-size: 34rpx;
}

#userInfoView > view:nth-child(2){
  color: #fff;
  font-size: 30rpx;
  padding: 30rpx 0;
}

#userInfoView > view:nth-child(3){
  color: #0f9ffb;
  font-size: 34rpx;
}

3.4.2 個人センターのリスト項目

ページ構造

         1. ビューを定義し、クラス userItemListView を追加します。

        2. userItemListView で対応する数のサブビューを定義します。

        3. 各サブビューで対応するテキストと矢印を定義します。

<!-- 用户列表选项 -->
<view class="userItemListView">
  <view>
    <text>我的测评</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>我的咨询</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>我的回答</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>我的通知</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>课程收藏</text>
    <view class="arrow"></view>
  </view>
</view>

<view class="userItemListView">
  <view>
    <text>绑定手机</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>修改密码</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>关于我们</text>
    <view class="arrow"></view>
  </view>
  <view>
    <text>退出登录</text>
    <view class="arrow"></view>
  </view>
</view>

スタイルの実装

        1. ページ全体の背景色を設定します。

        2. userItemListView の背景色、左右の内側マージン、および上下の外側マージンを設定します。

        3. サブビューの高さ、行の高さ、下の境界線、および相対的な位置を userItemListView に設定します。

        4. テキストのサイズと太さを設定します。

        5. 矢印のスタイルを設定します。

        注: 垂直外側マージンのマージ; 2 つの外側マージンが垂直に積み重ねられている場合、それは累積されませんが、2 つのうち大きい方がメインです。

/* 用户列表选项样式 */
.userItemListView{
  background: #fff;
  padding: 0 50rpx;
  margin: 24rpx 0;
}

.userItemListView > view{
  height: 88rpx;
  line-height: 88rpx;
  border-bottom: 1rpx solid #F1F1F1;
  position: relative;
}

/* 移除最后一个元素的下边框 */
.userItemListView > view:last-child{
  border: none;
}

.arrow{
  width: 16rpx;
  height: 16rpx;
  border-top: 4rpx solid #999;
  border-right: 4rpx solid #999;
  /* 旋转45度 */
  transform: rotate(45deg);
  /* 调整位置 */
  position: absolute;
  right: 30rpx;
  top: 38rpx;
}


.userItemListView text{
  font-size: 30rpx;
}

3.5 特集記事ページ

3.5.1 序文

        現在、ホームページ、相談ページ、コースページ、マイページの4ページを実現しており、この4ページにタブバーでジャンプでき、この4ページをタブバーページと呼んでいます
    
        。 -tabBar ページ、ジャンプする方法は? たとえば、これから作成する特集記事ページは、ホームページの特集記事エリアで [もっと見る] をクリックするとリダイレクトされますが、このジャンプをどのように実現するかがこのセクションの議論の焦点です。

        特集記事のページは、もはや誰にとっても難しいものではありません。

3.5.2 記事一覧

ページ構造

          1. app.json のページ構成で pages/hotArticle/hotArticle を定義します。

        2. hotArticle ページに編集モードを追加します。そうしないと、効果を表示できません。

        3. ビューを定義し、それに id を追加します: hotArticleView;

        4. hotArticleView に 6 つのサブビューを追加すると、構造はホームページで選択した記事に似ています; クラスを追加します: articleView を 6 つの ziviews に追加します; そして、ホームページの関連する構造を担当します; 注:ホームページからの構造
        ,
                しかし明らかにコードには多くの冗長性があります. テンプレートについては後で説明します.
                実際のデータでカバーするので、テンプレートのテキストコンテンツについてあまり心配する必要はありません.将来;

<!-- 文章列表区域 -->
<view id="hotArticleView">
  <view class="articleView">
    <view>
      <image src="/images/article01.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <view class="articleView">
    <view>
      <image src="/images/article02.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <view class="articleView">
    <view>
      <image src="/images/article03.png"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <view class="articleView">
    <view>
      <image src="/images/article04.jpg"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <view class="articleView">
    <view>
      <image src="/images/article05.jpg"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>

  <view class="articleView">
    <view>
      <image src="/images/article06.jpg"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        你活出自我的样子,真美
      </view>
      <view class="articleDesc">
        千百年来,古人总是把人的品格与自然之物相联系起来,以花草树木之品性喻人的精神情操。
      </view>
    </view>
  </view>
</view>

スタイルの実装

        1. hotArticleView の左右の内側マージンを設定します。

        2. articleView の関連するスタイルとそのサブ要素を index.css から割り当てます。

/* 文章列表区域*/
#hotArticleView{
  padding: 0 22rpx;
}

.articleView {
  display: flex;
  padding: 30rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
}

.articleView image{
  width: 120rpx;
  height: 120rpx;
  margin-right: 20rpx;
}

.articleTitle{
  font-size: 28rpx;
  font-weight: bold;
  line-height: 50rpx;
}

.articleDesc{
  font-size: 26rpx;
  color: #A9A9A9;
  line-height: 35rpx;
}

3.5.3 ロード

        相談予約ページと同様に、対応するコードをコピーするだけです。

3.5.4 ページジャンプ

        ホームページ - すばらしい記事 - をクリックすると、さらに表示され、注目の記事ページにジャンプします。

コンポーネントジャンプ方式

        HTML のハイパーリンクに似たコンポーネント ジャンプ モード。

        コンポーネント モードはナビゲーター コンポーネントに依存し、ナビゲーター コンポーネントはページ リンクです。
    
        コンポーネントのドキュメント: https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html

        このコンポーネントには多くのデータがありますが、一般的に使用されるいくつかのデータのみを使用する必要があり、他のデータについてはドキュメントを参照できます。

        ページの各領域をクリックしてジャンプするときは、通常、コンポーネント ジャンプを使用します。

属性 タイプ デフォルト 必要 例証する
目標 自己 いいえ ジャンプするターゲットで、デフォルトは現在のアプレットです
URL いいえ 現在のアプレットのジャンプ リンク
開放型 ナビゲートする いいえ ジャンプサイド

 ターゲットの正当な値

価値 例証する
自己 現在のアプレット
ミニプログラム その他のアプレット

開放型の正当な値

価値 例証する
ナビゲートする wx.navigateToまたはwx.navigateToMiniProgramの機能に対応して、現在のページを保持し、アプリケーション内の特定のページにジャンプします。しかし、タブバーページにジャンプできません。
リダイレクト wx.redirectToの機能に対応し、現在のページを閉じてアプリ内のページにジャンプします。ただし、タブバー ページへのジャンプは許可されていません。
スイッチタブ wx.switchTabの機能に対応して、tabBar ページにジャンプし、他のすべての非 tabBar ページを閉じます
再起動 wx.reLaunchに対応する関数
ナビゲート戻る 对应 wx.navigateBack 的功能
exit 退出小程序,target="miniProgram"时生效

        点击查看更多,跳转到精选文章页面,那么我们使用哪一种?第一种;

        1、把首页的查看更多的view,改为navigator组件;
    
        2、给navigator组件添加url属性,open-type属性;
                url: 精选文章的页面地址
                open-type:navigate

<navigator id="moreView" url="/pages/hotArticle/hotArticle" open-type="navigate"> 
    <text>查看更多</text>
    <view class="arrow"></view>
</navigator>

API跳转方式

        API跳转方式,类似于JS实现页面跳转;

        API跳转是需要结合事件,并且结合JS来实现;
    
        如果需要结合数据或逻辑来实现跳转的话,一般使用API跳转方式;比如登录成功跳转到我的页面;

        1、给查看更多view添加tap事件:手指触摸后马上离开;事件需要对应一个函数,当我们点击这个查看更多的时候,去执行函数里面的代码;

        2、在index.js里面添加goHotArticlePage函数,
                把index.js里面的bindViewTap、getUserProfile、getUserInfo函数都删除掉;把onload里面的代码也删除,但是onload留着;
        
        3、在goHotArticlePage函数里面写页面跳转的API即可;

<!-- 查看更多 -->
<view id="moreView" bindtap="goHotArticlePage"> 
    <text>查看更多</text>
    <view class="arrow"></view>
</view>
goHotArticlePage(){
    wx.navigateTo({
        url: '/pages/hotArticle/hotArticle',
    })
},

3.6 关于我们页面

3.6.1 页面效果实现

页面结构

        在app.json里面的pages里面定义"pages/aboutUs/aboutUs"

        1、定义一个view,给其添加id:qrCodeView,然后在其中定义图片和文字;

        2、定义一个view,给其添加id:companyView;

        3、在companyView里面定义5个子view,分别来承载公司名称、地址、电话、邮箱、简介,给这5个子view添加class=companyItemView;

        4、在companyItemView里面分别定义两个view,用来承载标题和文字;

        5、在第四个view和第五个view中间添加图片;

<!-- 二维码区域 -->
<view id="qrCodeView">
  <image src="/images/@2x_2weima.png"></image>
  <text>微信扫一扫关注我们</text>
</view>

<!-- 公司信息区域 -->
<view id="companyView">
  <view class="companyItemView">
    <view>公司名称</view>
    <view>河南十方心理咨询有限公司</view>
  </view>
  <view class="companyItemView">
    <view>公司地址</view>
    <view>河南自贸试验区郑州片区绿地新都会2号楼A座1007</view>
  </view>
  <view class="companyItemView">
    <view>联系电话</view>
    <view>0371-68105666</view>
  </view>
  <view class="companyItemView">
    <view>客服邮箱</view>
    <view>[email protected]</view>
  </view>

  <image src="/images/@2x_about.png"></image>
  
  <view class="companyItemView">
    <view>公司简介</view>
    <view>河南十方心理咨询有限公司成立于2017年5月23日, 是第一批有能力搭建社会心理服务体系的机构;是对企业全面实施EAP整体项目的专业供应商; 是为个体和企业提供个性化“心理测评”服务的心理健康机构;是对个体、团体进行心理咨询的心理服务机构; 是首个注重并开展青少年素质培养的心理教育机构。我们以“培育健康的人格素质” 为首要任务,一切以来访者的的个人成长和客户的收获为中心,在众多经验丰富的心理咨询专家的共同努力下,获得了社会。</view>
  </view>
</view>

样式实现

        1、给qrCodeView添加宽度、上下左右外边距;
    
        2、给qrCodeView里面的图片设置宽、高、下外边距(和文字拉开距离);给文字设置大小、居中即可;

        3、给companyView设置左右内边距;

        4、给companyItemView设置下外边距;

        5、给companyView里面的图片设置下外边距、宽、高;

        6、给companyItemView里面的子view设置文字大小和颜色;第一个子view添加下外边距/下内边距;

/* 二维码区域样式 */
#qrCodeView{
  width: 300rpx;
  margin: 20rpx auto 60rpx;
  font-size: 26rpx;
  text-align: center;
}

#qrCodeView > image{
  width: 300rpx;
  height: 300rpx;
  padding-bottom: 10rpx;
}


/* 公司信息区域 */
#companyView{
  padding: 0 40rpx;
}

.companyItemView{
  padding-bottom: 30rpx;
}

#companyView > image{
  width: 670rpx;
  height: 500rpx;
  margin-bottom: 40rpx;
}

.companyItemView > view:nth-child(1){
  font-size: 30rpx;
  color: #87cefa;
  padding-bottom: 20rpx;
}

.companyItemView > view:nth-child(2){
  font-size: 26rpx;
  color: #888;
}

3.6.2 关联跳转

        在我的页面中,把关于我们的view改为navigator,然后设置跳转路径和方式;

        注:把我的页面的每一项的view都换成navigator;然后样式稍微变更一下

<navigator url="/pages/aboutUs/aboutUs" open-type="navigate">
    <text>关于我们</text>
    <view class="arrow"></view>
</navigator>

...
.userItemListView > navigator{
  height: 88rpx;
  line-height: 88rpx;
  border-bottom: 1rpx solid #F1F1F1;
  position: relative;
}

/* 移除最后一个元素的下边框 */
.userItemListView > navigator:last-child{
  border: none;
}

3.7 咨询师详情页

3.7.1 咨询师信息

页面结构

         在app.json里面的pages里面定义"pages/consultDetails/consultDetails"

        1、定义一个view,给其添加id:consultInfoView;

        2、在consultInfoView定义4个view,分别承载咨询师头像、名称、等级、证书等;

        3、在第四个view里面定义两个view,分别承载已认证和查看证书的文本;给第四个view添加一个id:ccieView,是为了方便我们后续的样式添加;

<!-- 咨询师信息 -->
<view id="consultInfoView">
  <view>
    <image src="/images/zxs01.jpg"></image>
  </view>
  <view>
    张婧
  </view>
  <view>
    郑州市  国家二级心理咨询师
  </view>
  <view id="ccieView">
    <view>已认证</view>
    <view>查看证书</view>
  </view>
</view>

样式实现

        1、给consultInfoView设置背景色;
    
        2、给consultInfoView里面的第一个子view设置宽、高、外边距居中、上下外边距、背景色、圆角、文本居中;给第一个子view里面的图片设置大小、圆角、上外边距;
        注意:当我们给父元素的第一个子元素设置上外边距的时候,应用到了父元素,这叫上外边距的塌陷,给父元素设置overflow:hidden;

        3、给consultInfoView里面的第二个子view上设置文字大小、颜色、文本居中、加粗;

        4、给consultInfoView里面的第三个子view上设置文字大小、颜色、文本居中、下边框、上下内边距、宽度、居中;

        5、给ccieView设置上下左右内边距、flex布局、上下内边距;

        6、给ccieView里面的子view添加背景颜色、文字颜色、圆角、宽高、行高;

/* 咨询师信息样式 */
#consultInfoView{
  background: #87cefa;
  /* 解决上外边距的塌陷 */
  overflow: hidden;
  color: white;
}

#consultInfoView > view:nth-child(1){
  width: 200rpx;
  height: 200rpx;
  margin: 40rpx auto;
  border-radius: 100rpx;
  background: #fff;
  text-align: center;
}

#consultInfoView image{
  width: 160rpx;
  height: 160rpx;
  border-radius: 80rpx;
  margin-top: 20rpx;
}

#consultInfoView > view:nth-child(2){
    font-size: 36rpx;
    text-align: center;
    font-weight: bold;
}

#consultInfoView > view:nth-child(3){
  font-size: 30rpx;
  text-align: center;
  padding: 28rpx 0;
  border-bottom: 2rpx solid #fff;
  width: 690rpx;
  margin: 0 auto;
}

#ccieView {
  padding: 20rpx 76rpx;
  display: flex;
  justify-content: space-between;
}

#ccieView > view{
  width: 200rpx;
  height: 60rpx;
  height: 60rpx;
  background: #29AFF4;
  text-align: center;
  line-height: 60rpx;
  border-radius: 30rpx;
}

3.7.2 擅长领域

页面结构

        1、定义一个view,给其添加id:domainView;

        2、在domainView定义三个子view,分别来承载不同的文本;

<!-- 擅长领域 -->
<view id="domainView">
  <view>恋爱关系</view>
  <view>婚姻家庭</view>
  <view>情绪管理</view>
</view>

样式实现

        1、给domainView设置上下左右内边距、flex布局、水平排版、背景色;

        2、给domainView的三个子view设置背景色、宽、高、文字颜色、文本居中、行高、圆角、字体大小;

/* 擅长领域 */
#domainView{
  padding: 30rpx 76rpx;
  display: flex;
  justify-content: space-between;
  background: #fff;
}

#domainView > view{
  width: 150rpx;
  height: 50rpx;
  line-height: 50rpx;
  text-align: center;
  background: #87cefa;
  color: #fff;
  font-size: 24rpx;
  border-radius: 6rpx;
}

3.7.3 收费标准

页面结构

         1、定义view,给其添加class:consultItemView;

        2、在consultItemView里面定义view,给其添加class:titleView,用来承载标题;

        3、在consultItemView定义三个子view,给其添加class:chargeItemView;

        4、在chargeItemView里面定义三个子view,分别用来承载收费类型、收费金额、咨询人数等文本;

        5、在consultItemView定义一个view,用来承载查看更多和右箭头;

<!-- 收费标准 -->
<view class="consultItemView">
  <!-- 标题 -->
  <view class="titleView">
    收费标准
  </view>
  <!-- 收费项 -->
  <view class="chargeItemView">
    <view>语音咨询</view>
    <view>18人已咨询</view>
    <view>
      <text>500</text>/次(1小时)
    </view>
  </view>

  <view class="chargeItemView">
    <view>视频咨询</view>
    <view>18人已咨询</view>
    <view>
      <text>500</text>/次(1小时)
    </view>
  </view>

  <view class="chargeItemView">
    <view>倾诉咨询</view>
    <view>18人已咨询</view>
    <view>
      <text>500</text>/次(1小时)
    </view>
  </view>

  <!-- 查看更多 -->
  <view id="moreView" bindtap="goHotArticlePage"> 
    <text>查看更多</text>
    <view class="arrow"></view>
  </view>
</view>

样式实现

        1、给页面设置整体背景色;

        2、给consultItemView设置左右内边距和上下外边距、背景颜色;

        3、给titleView设置上下内边距、字体大小、粗细、下边框;

        4、给chargeItemView设置下边框、上下内边距、相对定位;

        5、给chargeItemView里面的三个子view分别设置字体大小、颜色;

        6、给chargeItemView第二个子view,设置绝对定位改变其位置;

        7、给chargeItemView第三个子view,设置上内边距;给它里面的text设置字体大小和颜色;

/* 收费标准 */
.consultItemView{
  margin: 24rpx 0;
  padding: 0 30rpx;
  background: #fff;
}

.titleView{
  padding: 30rpx 0;
  font-size: 30rpx;
  font-weight: bold;
  border-bottom: 1rpx solid #F1F1F1;
}

.chargeItemView{
  padding: 20rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
  position: relative;
  color: #9F9F9F;
}

.chargeItemView > view:nth-child(1){
  font-size: 30rpx;
}

.chargeItemView > view:nth-child(2){
  font-size: 24rpx;
  position: absolute;
  top: 20rpx;
  right: 30rpx;
}

.chargeItemView > view:nth-child(3){
  font-size: 30rpx;
}

.chargeItemView > view:nth-child(3) text{
  color: #fe3000;
  font-size: 30rpx;
  font-weight: bold;
  padding-top: 20rpx;
}

3.7.4 回复留言

页面结构

        1、定义view,给其添加class:consultItemView;

        2、在consultItemView里面定义view,给其添加class:titleView,用来承载标题;

        3、在consultItemView定义三个子view,给其添加class:replyItemView;

        4、在replyItemView里面定义两个子view,分别用来承载问、答;

        5、在consultItemView定义一个view,用来承载查看更多和右箭头;

<!-- 回复留言 -->
<view class="consultItemView">
  <!-- 标题 -->
  <view class="titleView">
    回复留言
  </view>
  <!-- 收费项 -->
  <view class="replyItemView">
    <view>问: 家庭矛盾,情绪抑郁,社交恐惧症,自卑,时长心慌不安,巴拉拉巴拉</view>
    <view>
      答: 这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
    </view>
  </view>

  <view class="replyItemView">
    <view>问: 家庭矛盾,情绪抑郁,社交恐惧症,自卑,时长心慌不安,巴拉拉巴拉</view>
    <view>
      答: 这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
    </view>
  </view>

  <view class="replyItemView">
    <view>问: 家庭矛盾,情绪抑郁,社交恐惧症,自卑,时长心慌不安,巴拉拉巴拉</view>
    <view>
      答: 这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
      这里是咨询师回答的相关问题,第一,第二,第三。这里是咨询师回答的相关问题,第一,第二,第三。
    </view>
  </view>

  <!-- 查看更多 -->
  <view id="moreView" bindtap="goHotArticlePage"> 
    <text>查看更多</text>
    <view class="arrow"></view>
  </view>
</view>

样式实现

        1、给replyItemView设置下边框、上下内边距;

        2、给replyItemView里面的两个子view分别设置字体大小、颜色;

        3、给replyItemView里面的第一个子view,设置文本不换行,超出部分隐藏,用省略号替代、宽、高、行高、文本加粗;

        4、给replyItemView里面的第二个子view,设置高度、超出部分隐藏,用省略号替代、两行文本显示、多余的内容省略号隐藏、宽、高;
        参考文档:https://blog.csdn.net/weixin_33910759/article/details/89760530
        注:一行省略和两行省略实现方式不太一样;

/* 回复留言 */
.replyItemView{
  padding: 30rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
}

.replyItemView > view:nth-child(1){
  font-size: 30rpx;
  width: 690rpx;
  height: 60rpx;
  line-height: 60rpx;
  font-weight: bold;
  /* 超出部分隐藏 */
  overflow: hidden;
  /* 文本不换行 */
  white-space: nowrap;
  /* 多余文本使用省略号替代 */
  text-overflow: ellipsis;
}

.replyItemView > view:nth-child(2){
  font-size: 24rpx;
  color: #9F9F9F;
  height: 80rpx;
  line-height: 40rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  align-content: center;
}

3.7.5 用户评价

        用户评价和收费标准结构类似,样式稍微有一定的差异,根据效果图和标注图进行简单的修改即可;

五角星实现:参考文档:https://blog.csdn.net/sxs161028/article/details/107512671

<!-- 用户评价 -->
<view class="consultItemView">
  <!-- 标题 -->
  <view class="titleView">
    用户评价
  </view>
  <!-- 用户评论项 -->
  <view class="reviewItemView">
    <view class="userNameView">
      匿名用户
      <view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star half_star">
          <view class="icon icon_gray">
            <view class="icon icon_gray"></view>
          </view>
        </view>
      </view>
    </view>
    <view>昨天</view>
    <view>
      老师很细心,主要声音好听,长得美!
    </view>
  </view>

  <view class="reviewItemView">
    <view class="userNameView">
      匿名用户
      <view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star half_star">
          <view class="icon icon_gray">
            <view class="icon icon_yellow"></view>
          </view>
        </view>
      </view>
    </view>
    <view>昨天</view>
    <view>
      老师很细心,主要声音好听,长得美!
    </view>
  </view>

  <view class="reviewItemView">
    <view class="userNameView">
      匿名用户
      <view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_yellow"></view>
        </view>
        <view class="star">
          <view class="icon icon_gray"></view>
        </view>
        <view class="star half_star">
          <view class="icon icon_gray">
            <view class="icon icon_gray"></view>
          </view>
        </view>
      </view>
    </view>
    <view>昨天</view>
    <view>
      老师很细心,主要声音好听,长得美!
    </view>
  </view>


  <!-- 查看更多 -->
  <view id="moreView" bindtap="goHotArticlePage">
    <text>查看更多</text>
    <view class="arrow"></view>
  </view>
</view>
/* 用户评价 */
.reviewItemView {
  padding: 20rpx 0;
  border-bottom: 1rpx solid #F1F1F1;
  position: relative;
}

.reviewItemView>view:nth-child(1) {
  font-size: 24rpx;
  color: #9F9F9F;
}

.reviewItemView>view:nth-child(2) {
  font-size: 24rpx;
  position: absolute;
  top: 20rpx;
  right: 30rpx;
  color: #9F9F9F;
}

.reviewItemView>view:nth-child(3) {
  font-size: 30rpx;
  padding-top: 20rpx;
}

@font-face {
  font-family: 'FontAwesome';
  src: url('https://netdna.bootstrapcdn.com/font-awesome/3.2.1/font/fontawesome-webfont.woff?v=3.2.1') format('woff');
}

.userNameView {
  position: relative;
}

.userNameView > view{
  display:flex;
  position: absolute;
  left: 130rpx;
  top: 6rpx;
}

/*五角星之间的间距*/
.star {
  margin-right: 4rpx;
}

/*五角星*/
.star .icon:before {
  content: '\f005';
  font-family: FontAwesome;
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  overflow: hidden;
}

.star .icon {
  display: block;
  font-size: 24rpx;
  text-align: center;
  width: 24rpx;
  height: 24rpx;
  line-height: 24rpx;
  position: relative;
  white-space: pre;
}

/*灰色五角星*/
.star .icon_gray {
  color: #DDDDDD;
}

/*黄色五角星*/
.star .icon_yellow:before {
  color: #FED300;
}

3.7.6 底部区域

页面结构

        1、定义一个view,然后给其添加id:bottomView;
    
        2、在bottomView定义两个子view,分成承载发私信和咨询;

<!-- 底部 -->
<view id="bottomView">
  <view>发私信</view>
  <view>咨询</view>
</view>

样式实现

        1、给bottomView使用flex布局;
    
        2、给bottomView里面的子view设置高度、等比放大、设置背景、设置文字大小颜色;

/* 底部样式 */
#bottomView{
  display: flex;
  text-align: center;
  border-top: 2rpx solid #F1F1F1;
}

#bottomView > view{
  flex-grow: 1;
  height: 98rpx;
  font-size: 36rpx;
  line-height: 98rpx;
}

#bottomView > view:nth-child(1){
  background: #F7F7FA;
  color: #979798;
  
}

#bottomView > view:nth-child(2){
  background: #87cefa;
  color: #fff;
}

注:点击咨询师列表中咨询师,跳转到对应的咨询师详情页,咨询师详情页就这一个页面,这是该页面中展示不同的动态数据,我们在后面结合数据的时候讲解;

3.8 登录页面

3.8.1 表单相关组件

button

        button 按钮。

        常用属性如下:

属性 类型 默认值 必填 说明
size string default 按钮的大小
type string default 按钮的样式类型
plain boolean false 按钮是否镂空,背景色透明
disabled boolean false 是否禁用
loading boolean false 名称前是否带 loading 图标
form-type string 用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件
open-type string 微信开放能力
<button size="default">default</button>
<button size="mini">mini</button>
<button size="default" type="primary">primary</button>
<button size="default" type="default">default</button>
<button size="default" type="warn">warn</button>
<button size="default" plain="true">plain</button>
<button size="default" disabled>disabled</button>
<button size="default" loading>loading</button>

checkbox

        checkbox 多选项目。

        常用属性如下:

属性 类型 默认值 必填 说明
value string checkbox标识,选中时触发checkbox-group的 change 事件,并携带 checkbox 的 value
disabled boolean false 是否禁用
checked boolean false 当前是否选中,可用来设置默认选中
color string #09BB07 checkbox的颜色,同css的colo
<!-- 组件之间的文本是给用户看的,value是要提交的数据 -->
<checkbox value="足球">足球</checkbox>
<checkbox value="篮球" checked>篮球</checkbox>
<checkbox value="羽毛球">羽毛球</checkbox>
<checkbox value="禁用" disabled>禁用</checkbox>
<checkbox value="指定颜色" color="#87cefa">指定颜色</checkbox>

form

        表单。将组件内的用户输入的switch input checkbox slider radio picker 提交。

        当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key。

        常用属性如下:

属性 类型 默认值 必填 说明
bindsubmit eventhandle 携带 form 中的数据触发 submit 事件,event.detail = {value : {'name': 'value'} , formId: ''}
bindreset eventhandle 表单重置时会触发 reset 事件

input

        输入框。该组件是原生组件,使用时请注意相关限制。

        常用属性如下:

属性 类型 默认值 必填 说明
value string 输入框的初始内容
type string text input 的类型
password boolean false 是否是密码类型
placeholder string 输入框为空时占位符
placeholder-style string 指定 placeholder 的样式
placeholder-class string input-placeholder 指定 placeholder 的样式类
disabled boolean false 是否禁用
maxlength number 140 最大输入长度,设置为 -1 的时候不限制最大长度
cursor-spacing number 0 指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离
auto-focus boolean false (即将废弃,请直接使用 focus )自动聚焦,拉起键盘
focus boolean false 获取焦点
<!-- 一般输入框不需要定义value,单选框和复选框经常需要使用value -->
<!-- 输入框输入的文本就是value的值,但是单选框和复选框需要指定value提交给服务器 -->
文本输入键盘:
<input type="text" value="张三123"/>
数字输入键盘:
<input type="number"/>
身份证输入键盘:
<input type="idcard"/>
带小数点的数字键盘:
<input type="digit"/>
密码安全输入键盘:
<input type="safe-password"/>
密码输入键盘:
<input type="text" password/>
带提示文本的输入框:
<input type="text" placeholder="请输入用户名"/>

picker

        从底部弹起的滚动选择器。

<view class="section">
  <view class="section__title">普通选择器</view>
  <picker bindchange="bindPickerChange" value="{
   
   {index}}" range="{
   
   {array}}">
    <view class="picker">
      当前选择:{
   
   {array[index]}}
    </view>
  </picker>
</view>
<view class="section">
  <view class="section__title">多列选择器</view>
  <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{
   
   {multiIndex}}" range="{
   
   {multiArray}}">
    <view class="picker">
      当前选择:{
   
   {multiArray[0][multiIndex[0]]}},{
   
   {multiArray[1][multiIndex[1]]}},{
   
   {multiArray[2][multiIndex[2]]}}
    </view>
  </picker>
</view>
<view class="section">
  <view class="section__title">时间选择器</view>
  <picker mode="time" value="{
   
   {time}}" start="09:01" end="21:01" bindchange="bindTimeChange">
    <view class="picker">
      当前选择: {
   
   {time}}
    </view>
  </picker>
</view>

<view class="section">
  <view class="section__title">日期选择器</view>
  <picker mode="date" value="{
   
   {date}}" start="2015-09-01" end="2017-09-01" bindchange="bindDateChange">
    <view class="picker">
      当前选择: {
   
   {date}}
    </view>
  </picker>
</view>
<view class="section">
  <view class="section__title">省市区选择器</view>
  <picker mode="region" bindchange="bindRegionChange" value="{
   
   {region}}" custom-item="{
   
   {customItem}}">
    <view class="picker">
      当前选择:{
   
   {region[0]}},{
   
   {region[1]}},{
   
   {region[2]}}
    </view>
  </picker>
</view>
Page({
  data: {
    array: ['美国', '中国', '巴西', '日本'],
    objectArray: [
      {
        id: 0,
        name: '美国'
      },
      {
        id: 1,
        name: '中国'
      },
      {
        id: 2,
        name: '巴西'
      },
      {
        id: 3,
        name: '日本'
      }
    ],
    index: 0,
    multiArray: [['无脊柱动物', '脊柱动物'], ['扁性动物', '线形动物', '环节动物', '软体动物', '节肢动物'], ['猪肉绦虫', '吸血虫']],
    objectMultiArray: [
      [
        {
          id: 0,
          name: '无脊柱动物'
        },
        {
          id: 1,
          name: '脊柱动物'
        }
      ], [
        {
          id: 0,
          name: '扁性动物'
        },
        {
          id: 1,
          name: '线形动物'
        },
        {
          id: 2,
          name: '环节动物'
        },
        {
          id: 3,
          name: '软体动物'
        },
        {
          id: 3,
          name: '节肢动物'
        }
      ], [
        {
          id: 0,
          name: '猪肉绦虫'
        },
        {
          id: 1,
          name: '吸血虫'
        }
      ]
    ],
    multiIndex: [0, 0, 0],
    date: '2016-09-01',
    time: '12:01',
    region: ['广东省', '广州市', '海珠区'],
    customItem: '全部'
  },
  bindPickerChange: function(e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      index: e.detail.value
    })
  },
  bindMultiPickerChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      multiIndex: e.detail.value
    })
  },
  bindMultiPickerColumnChange: function (e) {
    console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
    var data = {
      multiArray: this.data.multiArray,
      multiIndex: this.data.multiIndex
    };
    data.multiIndex[e.detail.column] = e.detail.value;
    switch (e.detail.column) {
      case 0:
        switch (data.multiIndex[0]) {
          case 0:
            data.multiArray[1] = ['扁性动物', '线形动物', '环节动物', '软体动物', '节肢动物'];
            data.multiArray[2] = ['猪肉绦虫', '吸血虫'];
            break;
          case 1:
            data.multiArray[1] = ['鱼', '两栖动物', '爬行动物'];
            data.multiArray[2] = ['鲫鱼', '带鱼'];
            break;
        }
        data.multiIndex[1] = 0;
        data.multiIndex[2] = 0;
        break;
      case 1:
        switch (data.multiIndex[0]) {
          case 0:
            switch (data.multiIndex[1]) {
              case 0:
                data.multiArray[2] = ['猪肉绦虫', '吸血虫'];
                break;
              case 1:
                data.multiArray[2] = ['蛔虫'];
                break;
              case 2:
                data.multiArray[2] = ['蚂蚁', '蚂蟥'];
                break;
              case 3:
                data.multiArray[2] = ['河蚌', '蜗牛', '蛞蝓'];
                break;
              case 4:
                data.multiArray[2] = ['昆虫', '甲壳动物', '蛛形动物', '多足动物'];
                break;
            }
            break;
          case 1:
            switch (data.multiIndex[1]) {
              case 0:
                data.multiArray[2] = ['鲫鱼', '带鱼'];
                break;
              case 1:
                data.multiArray[2] = ['青蛙', '娃娃鱼'];
                break;
              case 2:
                data.multiArray[2] = ['蜥蜴', '龟', '壁虎'];
                break;
            }
            break;
        }
        data.multiIndex[2] = 0;
        break;
    }
    console.log(data.multiIndex);
    this.setData(data);
  },
  bindDateChange: function(e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      date: e.detail.value
    })
  },
  bindTimeChange: function(e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      time: e.detail.value
    })
  },
  bindRegionChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  }
})

switch

        开关选择器。

        常用属性如下:

属性 类型 默认值 必填 说明
checked boolean false 是否选中
disabled boolean false 是否禁用
type string switch 样式,有效值:switch, checkbox
color string #04BE02 switch 的颜色,同 css 的 color
bindchange eventhandle checked 改变时触发 change 事件,event.detail={ value}
<switch >开关</switch>
<switch checked>开关</switch>
<switch disabled>开关</switch>
<switch type="checkbox">开关</switch>

3.8.2 页面实现

页面结构

        在app.json里面的pages里面定义"pages/login/login"    

        1、定义一个form组件,form组件是表单。将组件内的用户输入的switch input checkbox slider radio picker 提交。
        
        2、定义view,给其添加id:inputView,在inputView里面定义文本框和密码框;无论是文本框还是密码框都依赖于input组件,input组件是输入框。该组件是原生组件,使用时请注意相关限制;

        3、定义view,给其添加id:buttonView,在buttonView里面定义提交按钮和注册按钮;无论是什么按钮,都是依赖于button组件。

        4、在buttonView里面添加一个view,用来承载忘记密码;

<!-- 定义form组件 -->
<form>
  <!-- 输入框区域 -->
  <view id="inputView">
    <!-- 文本框 -->
    <input type="text" placeholder="手机号/用户名"></input>
    <!-- 密码框 -->
    <input type="text" placeholder="密码" password></input>
  </view>

  <!-- 按钮区域 -->
  <view id="buttonView">
    <button>登录</button>
    <button>注册</button>
    <view>忘记密码</view>
  </view>
</form>

样式实现

        1、给页面添加整体背景色;

        2、给inputView添加白色背景,左右内边距;

        3、给inputView里面的input设置高度,第一个input设置下边框;

        4、给buttonView设置宽度、上外边距、左右居中;

        5、给buttonView里面的第一个按钮,设置背景颜色、宽、高、字体大小、颜色;

        6、给buttonView里面的第二个按钮,设置上下外边距、背景颜色、边框、文字颜色、大小;

        7、给buttonView里面的子view设置文字大小、颜色、右对齐;


/* 给页面设置整体背景色 */
page{
  background: #F0EFF5;
}

/* 输入框区域样式 */
#inputView{
  background: #fff;
  padding: 0 30rpx;
}

#inputView > input{
  height: 88rpx;
}

#inputView > input:nth-child(1){
  border-bottom: 1rpx solid #F1F1F1;
}

/* 按钮区域样式 */
#buttonView{
  width: 690rpx;
  margin: 80rpx auto 0;
}

#buttonView > button{
  width: 690rpx;
  height: 88rpx;
  font-size: 36rpx;
}

#buttonView > button:nth-child(1){
  background: #87cefa;
  color: #fff;
}

#buttonView > button:nth-child(2){
  background: #fff;
  color: #87cefa;
  border: 2rpx solid #87cefa;
  margin: 36rpx 0;
}

#buttonView > view{
  font-size: 28rpx;
  color: #87cefa;
  text-align: right;
}

3.8.3 表单数据提交

        什么时候(怎么样)提交数据?
                当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key。

        1、给form组件添加bindsubmit事件,在js里面定义对应的事件函数;

        2、给button按钮添加form-type属性,值:submit,提交表单;

        3、在事件函数里面获取要提交的数据;
                3.1 需要给input组件添加name属性;
                3.2 通过事件函数的事件对象获取值;
    
        4、后续我们可以通过API发送请求;

<!-- 定义form组件 -->
<form bindsubmit="toLogin">
  <!-- 输入框区域 -->
  <view id="inputView">
    <!-- 文本框 -->
    <input type="text" placeholder="手机号/用户名" name="userName"></input>
    <!-- 密码框 -->
    <input type="text" placeholder="密码" password name="userPwd"></input>
  </view>

  <!-- 按钮区域 -->
  <view id="buttonView">
    <button form-type="submit">登录</button>
    <button>注册</button>
    <view>忘记密码</view>
  </view>
</form>
// 登录函数
toLogin(e){
    // 获取要提交的用户名和密码,用变量存储
    var userName = e.detail.value.userName;
    var userPwd = e.detail.value.userPwd;
    console.log("要提交给服务器的用户名和密码是:",userName,userPwd);
},

3.9 注册页面

3.9.1 页面实现

        注册页面和登录页面,无非就是换一下组件;

<!-- 定义form组件 -->
<form bindsubmit="toRegister">
  <!-- 输入框区域 -->
  <view id="inputView">
    <!-- 文本框 -->
    <input type="text" placeholder="用户名" name="userName"></input>
    <!-- 密码框 -->
    <input type="text" placeholder="输入6-12位字母、数字组合" password name="userPwd"></input>
    <input type="text" placeholder="确认密码" password name="userPwd1"></input>
    <!-- 昵称 -->
    <input type="text" placeholder="昵称" name="nickName"></input>
    <!-- 真实姓名 -->
    <input type="text" placeholder="真实姓名" name="realName"></input>
    <!-- 手机号 -->
    <input type="number" placeholder="手机号" name="phone"></input>
    <!-- 地址 -->
    <picker mode="region" bindchange="bindRegionChange" value="{
   
   {region}}" custom-item="{
   
   {customItem}}">
      <view class="picker">
        {
   
   {region[0]}} - {
   
   {region[1]}} - {
   
   {region[2]}}
      </view>
    </picker>
  </view>

  <!-- 按钮区域 -->
  <view id="buttonView">
    <button form-type="submit">注册</button>
    <view>已有账号,去登录</view>
  </view>
</form>

/* 给页面设置整体背景色 */
page{
  background: #F0EFF5;
}

/* 输入框区域样式 */
#inputView{
  background: #fff;
  padding: 0 30rpx;
}

#inputView > input{
  height: 88rpx;
  border-bottom: 1rpx solid #F1F1F1;
}

#inputView > picker{
  height: 88rpx;
  line-height: 88rpx;
}

/* 按钮区域样式 */
#buttonView{
  width: 690rpx;
  margin: 80rpx auto 0;
}

#buttonView > button{
  width: 690rpx;
  height: 88rpx;
  font-size: 36rpx;
}

#buttonView > button:nth-child(1){
  background: #87cefa;
  color: #fff;
}

#buttonView > view{
  font-size: 28rpx;
  color: #87cefa;
  text-align: right;
  margin-top: 36rpx;
}
/**
   * 页面的初始数据
   */
  data: {
    region: ['河南省', '郑州市', '中原区'],
    customItem: '全部'
  },
  bindRegionChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  },
  toRegister(e){
    console.log(e)
  },

3.9.2 页面跳转

        1、登录页面,当我们点击tabBar的时候,如果用户没有登录,那么我们跳转到登录页面;目前暂且实现不了,需要结合后面的动态数据来实现登录功能;
    
        2、在登录页面,点击注册,跳转到注册页面;

<button bindtap="toRegPage">注册</button>
toRegPage(){
    wx.navigateTo({
        url: '/pages/register/register',
    })
},

四、数据交互

        实现小程序数据交互,需要对微信小程序概念、代码构成、宿主环境、生命周期等有一定的了解,具体介绍见:深入理解小程序

        实现小程序数据交互,需要掌握微信小程序WXML语法,具体介绍见:WXML语法详解

        实现小程序数据交互,是基于json-server实现的数据mock,json-server环境搭建与使用见:json-server详解

4.1 首页

4.1.1 前置

        把十方智育的图片资源、视频资源等都放在json-server的public目录下面的指定文件夹中;
                public    json-server的静态资源目录
                        images    所有的图片资源
                        audio    所有的音频资源
                        video    所有的视频资源
    
        我们在实际开发中,图片、视频、音频等资源都是放在外部服务器上的,tabBar对应的图片必须是本地图片;因为微信小程序的代码包必须控制在2M以内;

        既然我们的json-server服务器已经搭建完成,那么我们肯定要进行数据交互;我们页面中需要的图片、数据都从json-server中获取;

        注:把除tabBar图片外的所有图片,都放在json-server public文件夹的images文件夹中;

        数据交互三步:
                1、数据定义,在json-server定义所需数据
                2、数据操作,在微信小程序的对应的js文件中,发送请求操作数据(查询/更新/删除/修改)
                3、数据处理,把得到的反馈数据进行对应的处理

        对于页面中无需改变的图片,我们直接在wxml写路径即可,比如:搜索框里面的放大镜;但是对于需要改变的图片,我们最后不要在wxml中直接写路径,而是通过数据的方式引入图片的地址(图片的路径是定义在json-server的data中),比如导航菜单、轮播图;

4.1.2 搜索框图片

        1、搜索框的图片不怎么会改变,我们可以直接写图片路径;
                <image src="http://localhost:3004/images/@2x_find.png"></image>
                上述写法的问题: 如果整个项目中有1000张图片都是这么写的路径,如果将来把存储图片的服务器给换了一个,那么ip地址肯定发生了改变,那么我们需要把1000张图片的路径都改了; 
                代码可维护性太低;
                把ip地址和端口号路径都定义成变量,然后在页面中引入变量即可;将来只需要改变这个变量即可;
                但是这个最好定义成全局的,因为所有的页面都要使用;
    
        2、在app.js的globalData里面定义baseUrl:"http://localhost:3004/"

        3、哪个页面需要用到baseUrl,就在对应的js通过app对象获取得到即可;
                3.1 怎么获取全局唯一app实例? const app = getApp()
                3.2 通过app实例获取得到baseUrl
                3.3 把baseUrl赋值给当前页面的某个变量

app.js代码:

// app.js
App({
  onLaunch (options) {
    // 生命周期回调——监听小程序初始化。
    console.log("监听小程序初始化 - 小程序启动了...");
  },
  onShow (options) {
    // 生命周期回调——监听小程序启动或切前台
    console.log("小程序切换到前台");
  },
  onHide () {
    // 生命周期回调——监听小程序切后台。
    console.log("小程序切换到后台");
  },
  onError (msg) {
    console.log(msg)
  },
  globalData: {
    userInfo: null,
    baseUrl:"http://localhost:3004/"
  }
})

index.js代码:

// 获取应用实例
const app = getApp()

data: {
    baseUrl:"",
}

onLoad() {
	// 获取baseUrl,赋值给当前页面的data里面的baseUrl变量
	var baseUrl = app.globalData.baseUrl;

	// 把获取得到的baseUrl赋值给当前页面的baseUrl
	// this表示当前页面的page对象
	this.setData({
		baseUrl:baseUrl
	})
}

index.wxml代码:

<!-- 顶部搜索框的实现 -->
<view id="searchOuterView">
  <view id="searchInnerView">
    <image src="{
   
   {baseUrl}}images/@2x_find.png"></image>
    <text> 搜索</text>
  </view>
</view>

4.1.3 轮播图

        轮播图是可以点击的,点击跳转到对应的详情页去;轮播图详情页和热门文章的详情页是类似的,我们目前仅使用动态数据,后面我们实现具体的详情展示;

        1、定义轮播图所需的数据;在db.json里面定义news数组,用来存储轮播图所需的数据;
                id                新闻编号
                news_title        新闻标题
                news_info        新闻内容,新闻都是通过PC端的后台来添加的,使用的是富文本,但是富文本微信小程序不识别,后续的课程,会给大家讲解富文本解析;
                image            新闻展示图片
                source            新闻来源
                cjsj            新闻创建时间

"news":[
    {
        "id": "2c9065246df6837f016e8d29c47f0082",
        "news_title": "社会心理服务体系建设试点工作方案",
        "news_info": "略...",
        "image": "images/img1.png",
        "source": "十方智育",
        "cjsj": 1574325884000
    },
    {
        "id": "2c9065246df6837f016e8d2298280081",
        "news_title": "关于加强心理健康服务的指导意见 ",
        "news_info": "略...",
        "image": "images/img2.png",	
        "source": "十方智育",
        "cjsj": 1574325884000
    },
    {
        "id": "2c90652467500e6801685fa5514b0035",
        "news_title": "加强社会心理服务体系建设",
        "news_info": "略...",
        "image": "images/img3.png",
        "source": "十方智育",
        "cjsj": 1547792896000
    }
]

        2、在index.js的onload函数,获取json-server中news的数据(目前news的数据我们指定要了三条,就当成轮播图来用即可,也不用考虑分页了);
        wx.request(Object object)    发起 HTTPS 网络请求。

属性 类型 默认值 必填 说明
url string 开发者服务器接口地址
data string/object/ArrayBuffer 请求的参数
header Object 设置请求的 header,header 中不能设置 Referer。 content-type 默认为 application/json
timeout number 超时时间,单位为毫秒
method string GET HTTP 请求方法
dataType string json 返回的数据格式
responseType string text 响应的数据类型
enableHttp2 boolean false 开启 http2
enableQuic boolean false 开启 quic
enableCache boolean false 开启 cache
enableHttpDNS boolean false 是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId 。 HttpDNS 用法详见 移动解析HttpDNS
httpDNSServiceId boolean HttpDNS 服务商 Id 。 HttpDNS 用法详见 移动解析HttpDNS
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

object.method 的合法值

说明 最低版本
OPTIONS HTTP 请求 OPTIONS
GET HTTP 请求 GET
HEAD HTTP 请求 HEAD
POST HTTP 请求 POST
PUT HTTP 请求 PUT
DELETE HTTP 请求 DELETE
TRACE HTTP 请求 TRACE
CONNECT HTTP 请求 CONNECT

        报错信息:
                http://localhost:3004 不在以下 request 合法域名列表中,请参考文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html(env: Windows,mp,1.05.2108130; lib: 2.19.5)

        错误解析:
                微信小程序不推荐http,推荐https;我们可以在详情-》本地设置-》不校验合法域名....

        3、把获取的数据展示在index.wxml中,那么就在data中定义news,把获取得到是数据赋值给news;然后在页面中遍历展示即可;
                注:我们只需要res里面的data数据即可;
                this表示当前页面对象,可以在page对象的函数中使用,但是不能在函数的函数中使用;我们可以在当前页面的函数中通过_this变量来存储this值;

index.js代码:

data: {
    ...
    news:"",
    ...    
}
    
onLoad() {
    var _this = this;

    // 获取baseUrl,赋值给当前页面的data里面的baseUrl变量
    var baseUrl = app.globalData.baseUrl;
    /*
      把获取得到的baseUrl赋值给当前页面的baseUrl
      this表示当前页面的page对象
    */
    _this.setData({
        baseUrl:baseUrl
    })

    // 获取得到news的数据
    wx.request({
        url: baseUrl+"news",
        method: "GET",
        header: {
            'content-type': 'application/json'
        },
        success (res) { // res是服务器响应的数据
            _this.setData({
                news: res.data
            })
        }
    })

}

index.wxml代码:

<swiper indicator-dots="{
   
   {indicatorDots}}" indicator-active-color="{
   
   {activeColor}}" autoplay="{
   
   {autoplay}}"
  interval="{
   
   {interval}}" duration="{
   
   {duration}}" circular="{
   
   {circular}}">
  <block wx:for="{
   
   {news}}" wx:key="*this">
    <swiper-item>
      <!-- 跳转路径目前可以空置,后续我们讲解富文本解析的时候,再说 -->
      <navigator open-type="navigate" url="...">
        <image src="{
   
   {baseUrl + item.image}}"></image>
      </navigator>
    </swiper-item>
  </block>
</swiper>

4.1.4 导航菜单

        导航菜单图片可以定义成动态的,因为很多app或pc端网站,在某个节日,比如春节、三八妇女节等都会改变图片的图标,那么我们也通过数据来定义;

        1、定义导航菜单所需的数据;在db.json里面定义navs数组,用来存储导航菜单所需的数据;
                navImg        导航菜单的图片
                navText        导航菜单的文本

"navs":[
    {
        "navImg":"images/@2x_ceping.png",
        "navText":"心理测评"
    },
    {
        "navImg":"images/@2x_yuyue.png",
        "navText":"咨询预约"
    },
    {
        "navImg":"images/@2x_dayi.png",
        "navText":"心理答疑"
    },
    {
        "navImg":"images/@2x_zhishi.png",
        "navText":"心理知识"
    },
    {
        "navImg":"images/@2x_FM.png",
        "navText":"FM"
    },
    {
        "navImg":"images/@2x_gongyi.png",
        "navText":"公益中心"
    }
]

        2、在index.js的onload中请求navs数据,然后复制给data的中navs,然后遍历到index.wxml中;

index.js代码:

data:{
    ...
    navs:"",
    ...    
}

// 获取得到navs的数据
wx.request({
    url: baseUrl+"navs",
    method: "GET",
    header: {
        'content-type': 'application/json'
    },
    success (res) { // res是服务器响应的数据
        _this.setData({
            navs: res.data
        })
    }
})

index.wxml代码:

<!-- 导航菜单 -->
<view id="navView">
  <view class="navItemView" wx:for="{
   
   {navs}}" wx:key="*this">
    <image src="{
   
   {baseUrl + item.navImg}}"></image>
    <text>{
   
   {item.navText}}</text>
  </view>
</view>

4.1.5 在线客服/请求回答

        在线客服和请求回答直接使用图片路径即可;

<!-- 在线客服 -->
<view id="onlineView">
  <image src="{
   
   {baseUrl}}/images/@2x_zixunpeixun.png"></image>
  <text> 咨询助理在线客服</text>
  <!-- 右箭头实现 -->
  <view class="arrow"></view>
</view>

<!-- 请求回答 -->
<view id="askView">
  <image src="{
   
   {baseUrl}}/images/@2x_fudong.png"></image>
</view>

4.1.6 精选文章

        首页的精选文章获取的是访问量前3的数据;

        1、定义精选文章所需的数据;在db.json里面定义hotArticles数组,用来存储精选文章所需的数据;

"hotArticles":[
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "失眠—你失控情绪的另一个出口",
        "CJSJ": 1585708931000,
        "ID": "2c9065246e96ad950171339e1a1f07b1",
        "IMAGE": "/images/rmwz01.jpg",
        "INFO": "失眠,已经成为当下许多年轻人的困扰。正如一句网络流行语调侃的那样,许多人的现状就是“也不是不困,就是想再等等……到底等什么呢?不知道,就是想再等等。”失眠造成的困扰不言而喻,有时会伴随着焦虑、抑郁、烦躁等情绪问题。尤其在隔离环境当中,突然没有平日忙碌的工作来填补时间的情况下,那些",
        "pv":9999
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "最易让人生病的八种心理情绪",
        "CJSJ": 1572253623000,
        "ID": "2c9065246df6837f016e119e63b6002a",
        "IMAGE": "/images/rmwz02.jpg",
        "INFO": "  生活中总是伴随着各种情绪,反映着我们的喜怒哀乐。不过丰富的情绪并不是件好事,有时还会影响我们的身心健康。下面是男人常见的八种心理情绪,小心这些情绪也会让你生病!  恶劣情绪NO.1:敌意  这是个讲究TEAMWORK的社会,不能和他人积极合作更容易引发敌意。专家发现:“敌视情",
        "pv":996
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "成人磨牙暗示着心理压力大",
        "CJSJ": 1572253453000,
        "ID": "2c9065246df6837f016e119bccf90029",
        "IMAGE": "/images/rmwz03.jpg",
        "INFO": "在入睡后磨牙,医学上称为“磨牙症”,磨牙症多见于儿童。不过成年磨牙也逐渐增多趋势,据了解,这与成人的心理状况有关,属于潜意识中的心理压力。 磨牙意味潜意识中的压力  口腔生理学与心理学认为,口腔是人体首先兴奋的源点,是与外界交流的渠道,且口腔具有表示紧张、悲观等情绪的功能。当今人",
        "pv":38
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "职场解压的15个心理技巧",
        "CJSJ": 1572253333000,
        "ID": "2c9065246df6837f016e1199f6e80028",
        "IMAGE": "/images/rmwz04.jpg",
        "INFO": "练习日常用来减压的技巧职场人士必须学会用简单方法放松自己,这是能够有效地减轻各种压力所导致的紧张不安的一种重要途径。 下面列出了日常放松自己或者减轻压力的一些简单方法,只要你稍加练习就可以掌握。  1、当面对繁重压力时,小睡一会。打盹被认为是减少和预防压力最有效的办法之一。  2",
        "pv":10
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "从性格判断你的健康状况",
        "CJSJ": 1572253131000,
        "ID": "2c9065246df6837f016e1196e18c0027",
        "IMAGE": "/images/rmwz05.jpg",
        "INFO": "从一个人的性格能判断其健康状况吗?答案是“能”,而且性格还会很大程度上影响到人的健康。健康心理学家表示,人的个性受到遗传基因和生活环境的双重影响。个性基本上可以分为以下八类,同时它们也能分别映射出不同疾病。虽然人们不能绝对对号入座,但它至少能提醒我们身边存在的潜在风险。  1",
        "pv":1088
    }
]

        2、在index.js的onload函数中,获取得到访问量前三的文章,赋值给data里面的hotArticles变量,然后遍历在wxml精选文章列表中;

        3、模版图片展示问题:我们引入模版,不会走模版的js文件,并且引入过来之后,当前页面的baseUrl识别不出来;那么我们可以对获取的数据进行操作,把数据的url拼接上baseUrl;

articleTemplate.wxml代码:

<!-- 文章列表结构模版 -->
<template name="articleTemplate">
  <!-- 一个文章列表结构,肯定对应的是一个对象数据,所以插值表达式在引用数据的时候,使用对象写法 -->
  <!-- 模版中的动态数据,只需要使用对象的key即可 -->
  <view class="articleView">
    <view>
      <image src="{
   
   {IMAGE}}"></image>
    </view>
    <view class="articleContent">
      <view class="articleTitle">
        {
   
   {ARTICLES_TITLE}}
      </view>
      <view class="articleDesc">
        {
   
   {INFO}}
      </view>
    </view>
  </view>
</template>

articleTemplate.wxss代码:

.articleTitle{
  font-size: 28rpx;
  font-weight: bold;
  line-height: 50rpx;
  height: 50rpx;
  /* 超出部分隐藏 */
  overflow: hidden;
  /* 文本不换行 */
  white-space: nowrap;
  /* 多余文本使用省略号替代 */
  text-overflow: ellipsis;
}

.articleDesc{
  font-size: 26rpx;
  color: #A9A9A9;
  line-height: 35rpx;
  height: 70rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  align-content: center;
}

index.js代码:

data:{
    ...
    hotArticles:""
    ...
}

// 获取得到hotArticles的数据
wx.request({
    url: baseUrl+"hotArticles?_sort=pv&_order=desc&_limit=3",
    method: "GET",
    header: {
        'content-type': 'application/json'
    },
    success (res) { // res是服务器响应的数据
        // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
        for(var i = 0;i < res.data.length;i++){
            res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
        }

        _this.setData({
            hotArticles: res.data
        })
    }
})

index.wxml代码:

<!-- 文章列表 - 使用模版 -->
<block wx:for="{
   
   {hotArticles}}" wx:for-item="article" wx:key="*this">
    <template is="articleTemplate" data="{
   
   {...article}}"></template>
</block>

4.1.7 报错处理

        控制台会报渲染层错误,加载本地图片失败;但是页面显示正常;

        原因:当渲染层渲染wxml的时候,碰到images/xxx.png,肯定先从根目录的images文件夹中查找,然而images里面并没有这张图片,所以报错;后续加载js里面的data的数据,又从外部服务器获取了图片地址,找到了,就显示图片;这就是为什么控制台会报渲染层错误,加载本地图片失败;但是页面显示正常;

        我们可以把图片也定义成动态的,解决报错信息;

 index.wxml代码:

<!-- 顶部搜索框的实现 -->
<view id="searchOuterView">
  <view id="searchInnerView">
    <image src="{
   
   {baseUrl + findImg}}"></image>
    <text> 搜索</text>
  </view>
</view>

<!-- 在线客服 -->
<view id="onlineView">
  <image src="{
   
   {baseUrl + kefuImg}}"></image>
  <text> 咨询助理在线客服</text>
  <!-- 右箭头实现 -->
  <view class="arrow"></view>
</view>

<!-- 请求回答 -->
<view id="askView">
  <image src="{
   
   {baseUrl + fudongImg}}"></image>
</view>

index.js代码:

data: {
    findImg:"",
    kefuImg:"",
    fudongImg:"",
}

_this.setData({
    baseUrl:baseUrl,
    findImg:"images/@2x_find.png",
    kefuImg:"images/@2x_zixunpeixun.png",
    fudongImg:"images/@2x_fudong.png"
})

4.2 登录页面

4.2.1 数据定义

        登录和注册使用的是一套数据,无非登录是进行了用户数据的查询,注册是用户数据的添加;
                id            用户编号
                userName    用户名
                userPwd        密码
                nickName    昵称
                realName    真实姓名
                integral    积分
                address        地址
                phone        手机号

"users":[
    {
        "id": 1,
        "userName": "zhangsan",
        "userPwd": "123456",
        "nickName": "奔放的三哥",
        "realName": "张三",
        "integral": 100,
        "address": "河南-郑州",
        "phone": 17600000012
    },
    {
        "id": 2,
        "userName": "lisi",
        "userPwd": "123456",
        "nickName": "嚣张的李四",
        "realName": "李四",
        "integral": 960,
        "address": "河南-郑州",
        "phone": 17600000011
    }
]

4.2.2 登录验证

        所谓的登录验证,就是就说从json-server查询是否有对应键值对的用户名和密码;我们之前已经给表单绑定了提交事件,并且在事件函数里面已经获取得到了提交给服务器的用户名和密码;
    
        用户名是唯一的,所以根据用户名和密码查找,如果匹配到了,那么肯定找到的是一条数据(json-server反馈的是一个数组,数组里面是一条数据,只要判定数组长度>0即可);如果错误,没有数据(数组长度为0);

        判断数组的长度,如果大于0,表示登录成功!否则登录失败,登录失败给其弹框提示;
                消息提示框:见下文
        其实有很多种情况,如果没有登录,都需要跳转到登录页面; 比如请求回答,视频收藏,我的页面;
        实际开发的情况: 访问哪个页面,需要登录的,那么登录成功之后,跳转之前的页面;
        但是我们目前不做这种业务了,直接跳转到我的页面

// pages/login/login.js

// 获取应用实例
const app = getApp()

Page({

  /**
   * 页面的初始数据
   */
  data: {
    baseUrl: ""
  },

  // 登录函数
  toLogin(e) {
    var _this = this;

    // 获取要提交的用户名和密码,用变量存储
    var userName = e.detail.value.userName;
    var userPwd = e.detail.value.userPwd;
    console.log("要提交给服务器的用户名和密码是:", userName, userPwd);

    // 根据用户名和密码从json-server服务器查询数据
    wx.request({
      url: _this.data.baseUrl + "users?userName=" + userName + "&userPwd=" + userPwd,
      method: "GET",
      header: {
        'content-type': 'application/json'
      },
      success(res) { // res是服务器响应的数据
        // 判断数组的长度,如果大于0,表示登录成功!否则登录失败,登录失败给其弹框提示
        if (res.data.length > 0) {
          // 其实有很多种情况,都需要跳转到登录页面; 比如请求回答,视频收藏,我的页面;
          // 实际开发的情况: 访问哪个页面,需要登录的,那么登录成功之后,跳转之前的页面;
          // 但是我们目前不做这种业务了,直接跳转到我的页面
          wx.switchTab({
            url: '/pages/my/my',
          })
        } else {
          wx.showToast({
            title: '用户名或密码错误!',
            icon: 'none',
            duration: 1500
          })
        }
      }
    })

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 获取baseUrl
    var _this = this;
    var baseUrl = app.globalData.baseUrl;
    _this.setData({
      baseUrl: baseUrl
    })

  }
  ....
})

4.2.3 消息提示框

        wx.showToast(Object object)        显示消息提示框

Object object参数

属性 类型 默认值 必填 说明 最低版本
title string 提示的内容
icon string success 图标
image string 自定义图标的本地路径,image 的优先级高于 icon 1.1.0
duration number 1500 提示的延迟时间
mask boolean false 是否显示透明蒙层,防止触摸穿透
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

object.icon 的合法值

说明 最低版本
success 显示成功图标,此时 title 文本最多显示 7 个汉字长度
error 显示失败图标,此时 title 文本最多显示 7 个汉字长度
loading 显示加载图标,此时 title 文本最多显示 7 个汉字长度
none 不显示图标,此时 title 文本最多可显示两行,1.9.0及以上版本支持

4.2.4 本地缓存

        我们在使用app的时候,经常会输入账号和密码,下次打开,之前输入的账号和密码会显示在输入框中;那么想要实现该功能,需要使用本地缓存;

存储用户名和密码

        把输入的用户名和密码放在本地缓存;
        wx.setStorage(Object object)    将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
        wx.setStorageSync(string key, any data)        wx.setStorage 的同步版本
        
        同步:按照顺序执行;
            1 -> 2 -> 3
        异步:同时执行;
            1 ->
            2 ->
            3 ->
        我们存储数据到本地缓存,使用wx.setStorage(Object object);

// 登录函数
toLogin(e) {
    var _this = this;

    // 获取要提交的用户名和密码,用变量存储
    ...

    // 只要输入了用户名和密码,都缓存在本地缓存
    // 如果不存在该key,那么就是创建;如果存在该key,那么就是更新
    wx.setStorage({
        // 本地缓存的key
        key: "loginUserInfo",
        data: {
            userName: userName,
            userPwd: userPwd
        }
    })

    // 根据用户名和密码从json-server服务器查询数据
    ...
},

获取用户名和密码

        在onload函数中获取本地缓存数据,然后把缓存的用户名和密码显示到输入框中;
                wx.getStorage(Object object)        从本地缓存中异步获取指定 key 的内容。
                wx.getStorageSync(string key)        wx.getStorage 的同步版本
        
                我们获取缓存数据,使用wx.getStorageSync(string key);

login.js代码:

/**
   * 生命周期函数--监听页面加载
   */
onLoad: function (options) {
    // 获取baseUrl
    var _this = this;

    // 获取本地缓存数据
    wx.getStorage({
        key: 'loginUserInfo',
        success(res) {
            console.log("onload函数中,从本地缓存获取得到的数据:",res.data)
            // 把本次缓存获取得到的数据放到data里面
            _this.setData({
                loginUserInfo:res.data
            })
        }
    })

},

login.wxml代码:

<!-- 输入框区域 -->
<view id="inputView">
    <!-- 文本框 -->
    <input type="text" placeholder="手机号/用户名" name="userName" value="{
   
   {loginUserInfo.userName}}"></input>
<!-- 密码框 -->
<input type="text" placeholder="密码" password name="userPwd" value="{
   
   {loginUserInfo.userPwd}}"></input>
</view>

4.2.5 登录状态保存

        在项目中,很多页面都是需要登录之后才能访问,比如:我的页面,请求回答页面,咨询客服页面,收藏课程页面等,但是如果已经登录,那么这些页面还需要跳转登录页面;
    
        那么我们登录成功之后,肯定要保存登录状态,让其他页面知道已经登录成功了;那么登录状态数据肯定要全局唯一实例App中,可以在app.js的globalData的userInfo中存储登录用户的数据;
        如果没有登录,那么userInfo是null,如果登录,把登录成功的用户的信息赋值给userInfo,那么userInfo就不为null,那么我们就可以通过判定userInfo来考量是否登录;

app.js代码:

// app.js
App({
  // 略
  globalData: {
    userInfo: null,
    baseUrl:"http://localhost:3004/"
  }
})

login.js代码:

if (res.data.length > 0) {
    // 把登录成功的用户数据放到globalData的userInfo中
    console.log(res.data);
    app.globalData.userInfo = res.data[0];

    // 其实有很多种情况,都需要跳转到登录页面; 比如请求回答,视频收藏,我的页面;
    // 略
} else {
   ...
}

4.3 我的页面

        1、如果用户没有登录,那么跳转到登录页面;如果已经登录,则进入我的页面;

        2、在我的页面,展示用户的动态信息;

my.js代码:

// pages/my/my.js

// 获取应用实例
const app = getApp()

Page({

  /**
   * 页面的初始数据
   */
  data: {
    userInfo:""
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var _this = this;

    // 判断用户是否登录,就是判断app.globalData.userInfo是否为null
    var userInfo = app.globalData.userInfo;
    if(userInfo == null){
      // 如果userInfo为null,没有登录
      wx.redirectTo({
        url: '/pages/login/login',
      })
    }else{
      // 如果不为null,表示已经登录
      _this.setData({
        userInfo:userInfo
      })
    }
  },

})

my.wxml代码:

<!-- 用户信息展示区域 -->
<view id="userInfoView">
  <view>昵称: {
   
   {userInfo.nickName}}</view>
  <view>来自: {
   
   {userInfo.address}}</view>
  <view>积分: {
   
   {userInfo.integral}}</view>
</view>

4.4 注册页面

        关于注册,我们不对数据进行校验了,大家在填写数据的时候,尽量避免已经存在的用户名;

        我们在前静态页面阶段,已经绑定了提交事件,并且可以通过事件对象,获取得到表单提交的数据;
        表单提交过来的数据要和json-server里面的数据格式保持一致;
                缺少:
                        id:id不需要写,json-server会自动给我们创建id;
                        integral:积分我们自己添加,刚注册的用户,我们给其定义0;
                        address:address的值在picker对应的数组;
                多余:
                        userPwd1:正常来说,需要userPwd和userPwd1保持一致;但是我们不做校验,直接删除userPwd1即可;

        我们把数据整理好之后,发送给json-server,如果数据添加成功,则表示注册成功;注册成功去登录页面,注册失败,提示;

register.js代码:

// pages/register/register.js
// 获取应用实例
const app = getApp()

Page({

  /**
   * 页面的初始数据
   */
  data: {
    baseUrl: "",
    region: ['河南省', '郑州市', '中原区'],
    customItem: '全部'
  },
  bindRegionChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  },
  toRegister(e){
    var _this = this;
    
    // 要提交给服务器的数据
    var submitData = e.detail.value;
    // 删除userPwd
    delete submitData.userPwd1;
    // 添加integral
    submitData.integral = 0;
    // 添加address,把region数组转换为字符串
    submitData.address = _this.data.region.join("-");

    // 把数据添加json-server
    wx.request({
      url: _this.data.baseUrl + "users",
      method: "POST",
      header: {
        'content-type': 'application/json'
      },
      data:submitData,
      success(res) { // res是服务器响应的数据
        if(res.data){ // 注册成功
            wx.navigateTo({
              url: '/pages/login/login',
            })
        }else{
          wx.showToast({
            title: '注册失败!',
            icon: 'none',
            duration: 1500
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 获取baseUrl
    var _this = this;
    var baseUrl = app.globalData.baseUrl;
    _this.setData({
      baseUrl: baseUrl
    })
  },
})

4.5 精选文章列表页

4.5.1 数据定义

        精选文章页面的数据结构之前我们已经定义过了,在首页的精选文章部分,之前我们只定义了5条,现在无非弄多一点数据而已,因为我们要做上提加载(分页);

    怎么获取数据?
                1、进入官网,访问对应的页面,比如精选文章:    
                        https://www.hnsfxlzx.com/sf/p/view/article/rmwz
        
                2、打开浏览器控制台(谷歌浏览器->右键->检查),NetWork,刷新页面,在控制台搜索框里面搜索page,一般都是要使用的数据;点击路径,右侧Response,复制数据;

                3、通过https://www.sojson.com/页面,格式化json;从中拿需要的数据;

"hotArticles": [
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "失眠—你失控情绪的另一个出口",
        "CJSJ": 1585708931000,
        "ID": "2c9065246e96ad950171339e1a1f07b1",
        "IMAGE": "/images/rmwz01.jpg",
        "INFO": "失眠,已经成为当下许多年轻人的困扰。正如一句网络流行语调侃的那样,许多人的现状就是“也不是不困,就是想再等等……到底等什么呢?不知道,就是想再等等。”失眠造成的困扰不言而喻,有时会伴随着焦虑、抑郁、烦躁等情绪问题。尤其在隔离环境当中,突然没有平日忙碌的工作来填补时间的情况下,那些",
        "pv": 9999
    },
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "最易让人生病的八种心理情绪",
        "CJSJ": 1572253623000,
        "ID": "2c9065246df6837f016e119e63b6002a",
        "IMAGE": "/images/rmwz02.jpg",
        "INFO": "  生活中总是伴随着各种情绪,反映着我们的喜怒哀乐。不过丰富的情绪并不是件好事,有时还会影响我们的身心健康。下面是男人常见的八种心理情绪,小心这些情绪也会让你生病!  恶劣情绪NO.1:敌意  这是个讲究TEAMWORK的社会,不能和他人积极合作更容易引发敌意。专家发现:“敌视情",
        "pv": 996
    },
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "成人磨牙暗示着心理压力大",
        "CJSJ": 1572253453000,
        "ID": "2c9065246df6837f016e119bccf90029",
        "IMAGE": "/images/rmwz03.jpg",
        "INFO": "在入睡后磨牙,医学上称为“磨牙症”,磨牙症多见于儿童。不过成年磨牙也逐渐增多趋势,据了解,这与成人的心理状况有关,属于潜意识中的心理压力。 磨牙意味潜意识中的压力  口腔生理学与心理学认为,口腔是人体首先兴奋的源点,是与外界交流的渠道,且口腔具有表示紧张、悲观等情绪的功能。当今人",
        "pv": 38
    },
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "职场解压的15个心理技巧",
        "CJSJ": 1572253333000,
        "ID": "2c9065246df6837f016e1199f6e80028",
        "IMAGE": "/images/rmwz04.jpg",
        "INFO": "练习日常用来减压的技巧职场人士必须学会用简单方法放松自己,这是能够有效地减轻各种压力所导致的紧张不安的一种重要途径。 下面列出了日常放松自己或者减轻压力的一些简单方法,只要你稍加练习就可以掌握。  1、当面对繁重压力时,小睡一会。打盹被认为是减少和预防压力最有效的办法之一。  2",
        "pv": 10
    },
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "从性格判断你的健康状况",
        "CJSJ": 1572253131000,
        "ID": "2c9065246df6837f016e1196e18c0027",
        "IMAGE": "/images/rmwz05.jpg",
        "INFO": "从一个人的性格能判断其健康状况吗?答案是“能”,而且性格还会很大程度上影响到人的健康。健康心理学家表示,人的个性受到遗传基因和生活环境的双重影响。个性基本上可以分为以下八类,同时它们也能分别映射出不同疾病。虽然人们不能绝对对号入座,但它至少能提醒我们身边存在的潜在风险。  1",
        "pv": 1088
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "这个救赎,因校园霸凌而起",
        "CJSJ": 1547801589000,
        "ID": "2c90652467500e6801686029f76b006e",
        "IMAGE": "/images/rmwz06.jpg",
        "INFO": "继《你的名字》之后,日本又出现了一个现象级的动漫电影---《声之形》。《你的名字》讲述关于爱情的缘分与奇妙,《声之形》则引起对友谊和成长的人性思考。 这是一个有关于听觉障碍的少女和曾经伤害过她的少年石田将也的成长故事。 作为小学转校生的女主角西宫硝子来到了男主角石田将也的班上,由"
        ,"pv": 1188
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "张韶涵从落魄走向开挂:所谓自由,就是被人讨厌",
        "CJSJ": 1547801545000,
        "ID": "2c90652467500e68016860294c97006d",
        "IMAGE": "/images/rmwz07.jpg",
        "INFO": "前几天看了一本书《被讨厌的勇气》,关于阿德勒的个体心理学,看完以后感触颇多。 书的副标题是:“所谓的自由,就是被人讨厌”。像裴多菲说的那样:生命诚可贵,爱情价更高,若为自由故,两者皆可抛,这个时代的每个人更是都在捶胸顿足的渴望着自由。 他们是上学的孩子、上班的职员、已婚的父母、有"
        ,"pv": 18
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "在你不知道的时候,你已经被美食毒害了",
        "CJSJ": 1547801504000,
        "ID": "2c90652467500e6801686028ac13006c",
        "IMAGE": "/images/rmwz08.jpg",
        "INFO": "是不是有点奇怪,为什么你会一直吃零食,根本管不住自己的嘴?实际上,你可能是能管住自己的。但是我想你一定已经看过了电视纪录片里讲的有些人管不住自己的嘴,哪怕他们已经胖得没法出门,仍然无法控制自己。为什么会这样?他们就是所谓的食物成瘾者?或者说这些食物成瘾者没有足够的意志力?你是怎么"
        ,"pv": 112
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "原生家庭的苦,怎样才能不白受?",
        "CJSJ": 1547801446000,
        "ID": "2c90652467500e6801686027ca0c006b",
        "IMAGE": "/images/rmwz09.jpg",
        "INFO": "培养安全依恋需要父母的热情、稳定和心理健康,那么,被原生家庭伤害过的人能不能培养安全依恋的孩子呢? -01-“妈妈酗酒、爸爸躁郁症,但我没有疯” 丽的妈妈酗酒,爸爸有躁郁症,她从来无法确定每天家中会是什么状态,也许妈妈会暴跳如雷,爸爸会拒绝服药,一会忧郁、一会躁狂。 但是,丽并没"
        ,"pv": 96
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "优秀的你,是不是个优秀的家长",
        "CJSJ": 1547801396000,
        "ID": "2c90652467500e680168602705c8006a",
        "IMAGE": "/images/rmwz10.jpg",
        "INFO": "在怎么教养孩子这方面,没有人可以给出来标准答案。每个孩子都不一样,做的少了怕不够,做得多了怕太过。 之前有一个朋友问我:是不是所有的父母都是爱他们的孩子的? 我告诉他,是的,确实所有的父母都爱他们的孩子,但不是所有的父母都是无条件爱孩子的。会有家长说:你要学习好,有才艺,要听话…"
        ,"pv": 168
    },
    {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "永不消失的爱",
        "CJSJ": 1547801366000,
        "ID": "2c90652467500e68016860268e210069",
        "IMAGE": "/images/rmwz11.jpg",
        "INFO": "听一个女孩儿讲她与父母的事,我却觉得,我们每个人的父母也是如此。 如果你觉得岁月静好,那一定是有人为你负重前行。 01 在我还没有开始工作的时候,我总觉得我是家里最累的那个人——每天都在上课,走的最早,回的最晚,在家还要写作业到半夜。我理所当然的觉得家里的事情就应该是父母在操心,"
        ,"pv": 54
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "抑郁症与抑郁情绪",
        "CJSJ": 1547801334000,
        "ID": "2c90652467500e680168602612d80068",
        "IMAGE": "/images/rmwz12.jpg",
        "INFO": "什么是抑郁症? 抑郁症是一种常见的精神疾病,主要表现为情绪低落,兴趣减低,悲观,思维迟缓,缺乏主动性,自责自罪,饮食、睡眠差,担心自己患有各种疾病,感到全身多处不适,严重者可出现自杀念头和行为。主要表现为:心境低落主要表现为显著而持久的情感低落,抑郁悲观。轻者闷闷不乐、无愉快感、"
        ,"pv": 99
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "研究生被导师压迫跳楼:“人际弱势者”如何自救?",
        "CJSJ": 1547801295000,
        "ID": "2c90652467500e68016860257c490067",
        "IMAGE": "/images/rmwz13.jpg",
        "INFO": "这两天看到一条新闻:武汉理工大学,研三的学生陶崇园,长期受到其导师的精神压迫。在长期的压力之下,陶崇园最终不堪重负,选择了跳楼自杀。看到这个新闻我非常的痛心。为陶崇园在重负之下选择终结自己的生命,感到非常的惋惜。但陶崇园绝非个例,这世上还有不知多少如陶崇园一样的人,在承受着来自别"
        ,"pv": 9
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "心理咨询的作用之一——在情绪中存活",
        "CJSJ": 1547801256000,
        "ID": "2c90652467500e6801686024e1dd0066",
        "IMAGE": "/images/rmwz14.jpg",
        "INFO": "当我们意外的掉入一条河里,这时候我们可能会先让自己浮出水面,深呼吸让自己镇定下来,观察下周围最近的岸边,是否需要喊人帮忙……有读者会说了,这种情况是基于你会游泳,没错。如果你在水里处在一个沉溺淹没的状态,我们根本不可能做出更多思考,以及采取对自己最有利的选择。 有时候我们甚至都没"
        ,"pv": 20
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "心理史上最大骗局:“星座测试太准啦!”",
        "CJSJ": 1547801193000,
        "ID": "2c90652467500e6801686023ec1c0065",
        "IMAGE": "/images/rmwz15.jpg",
        "INFO": "-01- “他要和我分手,嫌弃我是个处女!”He Broke Up With Me Coz I'm a Virgin话说,电视剧《龙门镖局》里有个四处留情的风流男子 —— 恭叔。这一天,镖局来了个恭叔的前女友 —— 露露。镖局的小伙伴们都在八卦:“你和恭叔当初是为啥分手哒?”下面"
        ,"pv": 618
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "小心!微表情泄露了你的秘密",
        "CJSJ": 1547801105000,
        "ID": "2c90652467500e680168602295500064",
        "IMAGE": "/images/rmwz16.jpg",
        "INFO": "小心!微表情泄露了你的秘密当下,随着许许多多影视资源的问世,越来越多的人将目光投向了心理学中的微表情。在众多影视剧中,微表情表现得神秘、莫测,仿佛掌握了微表情就征服了全世界。很多人慢慢开始崇拜掌握着这一技之长的人。那么,什么是微表情?你对微表情究竟了解多少?下面,就让我们一起走进"
        ,"pv": 982
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "我们为什么说脏话",
        "CJSJ": 1547800979000,
        "ID": "2c90652467500e6801686020a8020063",
        "IMAGE": "/images/rmwz17.jpg",
        "INFO": "这是一篇脏话百科全书,不谢,我也知道今天我巨他妈好看! 脏话,一种神奇的语言系统你能想象,一个没有脏话的世界,将如何生存吗?反正我不能。脏话,现在已经成为中国语言中非常发达的一项语言分支,它可以用来简化语言,规避歧义,提高语言效率。比如,“这个解释他妈的不清楚”和“这个他妈的解释"
        ,"pv": 138
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "为什么上班都是坐着,还会感觉疲惫不堪?",
        "CJSJ": 1547800887000,
        "ID": "2c90652467500e680168601f41010062",
        "IMAGE": "/images/rmwz18.jpg",
        "INFO": "有很多人上班疲惫回家之后就躺在沙发上休息看电视或者玩手机;在午后或者下午三四点之后分心注意力难以集中接着就走出去抽一口烟又或者刷刷微信放松一下,这些方式都无法解除大脑的疲劳。所以这一次跟焦糖Pan选择了这本日本畅销榜上的《最高休息法》,用正确的方式让大脑得到休息。如果大脑得到休息"
        ,"pv": 962
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "为什么你记不住别人的名字",
        "CJSJ": 1547800736000,
        "ID": "2c90652467500e680168601cf49c0061",
        "IMAGE": "/images/rmwz19.jpg",
        "INFO": "我们经常在聚会或是会议上听到别人说:“我擅长记人的脸,但是记不住人的名字。”这种常见的说法正确吗?现在,让我们开始一场关于记忆心理的旅程。我要告诉你,我们关于脸部、名字的记忆,并不像它看起来的那么简单。人类确实是识别面孔的专家。我们中的大都数人都能识别出成千上万张的脸,一切都是这"
        ,"pv": 28
    }, {
        "SOURCE": "十方智育",
        "ARTICLES_TITLE": "完美主义与自杀风险 ▎无法满足的期望与标准",
        "CJSJ": 1547800627000,
        "ID": "2c90652467500e680168601b4aba0060",
        "IMAGE": "/images/rmwz20.jpg",
        "INFO": "根据世界卫生组织(WHO)的统计,每45秒就有一个人自杀。为了防止悲剧发生,我们需要了解更多影响某些个体容易产生自杀想法以及自杀行为的因素。其中一个风险因素就是完美主义:一种强迫自己时刻达到超过自身能力标准的倾向或/和满足或超越他人过高期望的自我需要。 1995年,心理学家Sid"
        ,"pv": 118
    }	
]

4.5.2 获取所有的数据

hotArticle.wxml代码:

<!-- 引入模版 -->
<import src="/pages/template/articleTemplate/articleTemplate.wxml"></import>

<!-- 文章列表区域 -->
<view id="hotArticleView">
    <!-- 文章列表 - 使用模版 -->
    <block wx:for="{
   
   {hotArticles}}" wx:for-item="article" wx:key="*this">
        <template is="articleTemplate" data="{
   
   {...article}}"></template>
    </block>
</view>

<!-- 正在加载 -->
<view id="loadingView">
    <image src="{
   
   {baseUrl + lodingImg}}"></image>
    <text> 正在加载更多数据</text>
</view>

<!-- 最后一页 -->

hotArticle.js代码:

// pages/hotArticle/hotArticle.js
// 获取应用实例
const app = getApp()
Page({

    /**
   * 页面的初始数据
   */
    data: {
        baseUrl: "",
        hotArticles: "",
        lodingImg:""
    },

    /**
   * 生命周期函数--监听页面加载
   */
    onLoad: function (options) {
        // 获取baseUrl,赋值给当前页面的data里面的baseUrl变量
        var _this = this;
        var baseUrl = app.globalData.baseUrl;
        _this.setData({
            baseUrl: baseUrl,
            lodingImg:"/images/loading.gif"
        })

        // 获取所有文章
        wx.request({
            url: baseUrl + "hotArticles",
            method: "GET",
            header: {
                'content-type': 'application/json'
            },
            success(res) { // res是服务器响应的数据
                // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
                for (var i = 0; i < res.data.length; i++) {
                    res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
                }
                _this.setData({
                    hotArticles: res.data
                })
            }
        })

    },
})

hotArticle.wxss代码:

/* 引入模版所需样式 */
@import '/pages/template/articleTemplate/articleTemplate.wxss';


/* 文章列表区域*/
#hotArticleView{
    padding: 0 22rpx;
}

/* 正在加载样式 */

#loadingView{
    text-align: center;
    height: 88rpx;
    background: #F0EFF5;
    line-height: 88rpx;
}

#loadingView > image{
    width: 48rpx;
    height: 48rpx;
    vertical-align: middle;
}

#loadingView > text{
    font-size: 28rpx;
    vertical-align: middle;
}

4.5.3 上提加载

        1、打开精选文章页面,我们要显示一部分数据;假定打开精选文章页面,我们要先显示8条数据;无非就是向后台发送请求,获取文章的前8条数据;_page=1&_limit=8

        2、在上提加载函数里面,发送请求去获取第x页的数据(上提加载的时候,要查询的_page要动态改变),但是我们获取的数据是要累加的,而不是覆盖;怎么实现:在hotArticles的基础上进行数据的追加

// pages/hotArticle/hotArticle.js
// 获取应用实例
const app = getApp()
Page({

    /**
   * 页面的初始数据
   */
    data: {
        baseUrl: "",
        hotArticles: [],
        lodingImg:"",
        // pageNum变量: 要请求的页码
        pageNum: 1
    },

    /**
   * 生命周期函数--监听页面加载
   */
    onLoad: function (options) {
        // 获取baseUrl,赋值给当前页面的data里面的baseUrl变量
        var _this = this;
        var baseUrl = app.globalData.baseUrl;
        _this.setData({
            baseUrl: baseUrl,
            lodingImg:"/images/loading.gif"
        })

        // 肯定不能一次性获取所有文章,应该是初始显示部分数据,上提的时候再加载更多数据
        // 显示第一页的数据
        wx.request({
            url: baseUrl + "hotArticles?_page="+_this.data.pageNum+"&_limit=8",
            method: "GET",
            header: {
                'content-type': 'application/json'
            },
            success(res) { // res是服务器响应的数据
                console.log("第"+_this.data.pageNum+"页的数据:",res.data);

                // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
                for (var i = 0; i < res.data.length; i++) {
                    res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
                }
                _this.setData({
                    hotArticles: _this.data.hotArticles.concat(res.data)
                })
            }
        })

    },

    /**
   * 页面上拉触底事件的处理函数
   */
    onReachBottom: function () {
        var _this = this;
        var baseUrl = _this.data.baseUrl;

        // 每次上提,原有的页码+1,pageNum + 1
        _this.setData({
            pageNum: _this.data.pageNum + 1
        })

        wx.request({
            url: baseUrl + "hotArticles?_page="+_this.data.pageNum+"&_limit=8",
            method: "GET",
            header: {
                'content-type': 'application/json'
            },
            success(res) { // res是服务器响应的数据
                console.log("第"+_this.data.pageNum+"页的数据:",res.data);

                // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
                for (var i = 0; i < res.data.length; i++) {
                    res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
                }
                _this.setData({
                    hotArticles: _this.data.hotArticles.concat(res.data)
                })
            }
        })
    },
})

        3、代码重用性;

// 封装请求数据的代码,提高代码复用性
// getData里面需要this对象,那么我们通过that参数传递进来
function getData(that){
    // 通过参数that获取baseUrl和pageNum
    var baseUrl = that.data.baseUrl;
    var pageNum = that.data.pageNum;

    wx.request({
        url: baseUrl + "hotArticles?_page="+pageNum+"&_limit=8",
        method: "GET",
        header: {
            'content-type': 'application/json'
        },
        success(res) { // res是服务器响应的数据
            console.log("第"+pageNum+"页的数据:",res.data);

            // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
            for (var i = 0; i < res.data.length; i++) {
                res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
            }
            that.setData({
                hotArticles: that.data.hotArticles.concat(res.data)
            })
        }
    })
}

// 在onload 和 onReachBottom分别调用getData(this)

        4、最下面:友好的提示

        需求:
                1、如果服务器还没有反馈回来数据,提示:正在加载更多数据...
                2、如果没有更多数据,提示:已经是最后一页啦!

        实现:
                1、默认情况下,正在加载数据...和已经是最后一页啦!,都是隐藏起来的;

                2、上提的时候,向服务器获取数据,让正在加载数据...显示,数据返回了,让正在加载数据...隐藏;

                3、如果没有数据了,那么显示已经是最后一页啦! 先获取得到总数量,当我们每次请求的时候,判断data里面的hotArticles是否和总数量相等,如果相等,则不再发送请求获取数据,显示最后一页;

                注:在实际开发环境里面,后台会把总数量和当前页的数据都封装给你,但是在json-server里面,必须得发送请求单独获取总数量;

<!-- 正在加载 -->
<view id="loadingView" wx:if="{
   
   {isLoading}}">
    <image src="{
   
   {baseUrl + lodingImg}}"></image>
    <text> 正在加载更多数据</text>
</view>

<!-- 最后一页 -->
<view id="loadingView" wx:if="{
   
   {noData}}">
    已经是最后一页啦!
</view>
// pages/hotArticle/hotArticle.js
// 获取应用实例
const app = getApp()

// 封装请求数据的代码,提高代码复用性
// getData里面需要this对象,那么我们通过that参数传递进来
function getData(that){
    // 通过参数that获取baseUrl和pageNum
    var baseUrl = that.data.baseUrl;
    var pageNum = that.data.pageNum;
    // 获取总数量
    var count = that.data.count;

    // 判断是否到最后一页
    if(count == that.data.hotArticles.length){
        that.setData({
            isLoading: false,
            noData: true
        })
    }else{
        wx.request({
            url: baseUrl + "hotArticles?_page="+pageNum+"&_limit=8",
            method: "GET",
            header: {
                'content-type': 'application/json'
            },
            success(res) { // res是服务器响应的数据
                console.log("第"+pageNum+"页的数据:",res.data);

                // 把响应过来的数据的IMAGE的路径之前拼接上baseUrl
                for (var i = 0; i < res.data.length; i++) {
                    res.data[i].IMAGE = baseUrl + res.data[i].IMAGE;
                }
                that.setData({
                    hotArticles: that.data.hotArticles.concat(res.data),
                    isLoading: false
                })
            }
        })
    }
}

Page({

    /**
   * 页面的初始数据
   */
    data: {
        baseUrl: "",
        hotArticles: [],
        lodingImg:"",
        // pageNum变量: 要请求的页码
        pageNum: 1,
        isLoading:false,
        noData:false,
        count:""
    },

    /**
   * 生命周期函数--监听页面加载
   */
    onLoad: function (options) {
        // 获取baseUrl,赋值给当前页面的data里面的baseUrl变量
        var _this = this;
        var baseUrl = app.globalData.baseUrl;
        _this.setData({
            baseUrl: baseUrl,
            lodingImg:"/images/loading.gif"
        })

        // 肯定不能一次性获取所有文章,应该是初始显示部分数据,上提的时候再加载更多数据
        // 获取总数量: 获取所有文章,通过数组长度得到总数量;
        wx.request({
            url: baseUrl + "hotArticles",
            method: "GET",
            header: {
                'content-type': 'application/json'
            },
            success(res) { // res是服务器响应的数据
                _this.setData({
                    count: res.data.length
                })

                // 显示第一页的数据
                getData(_this);
            }
        })

    },

    /**
   * 页面上拉触底事件的处理函数
   */
    onReachBottom: function () {
        var _this = this;

        // 每次上提,原有的页码+1,pageNum + 1
        _this.setData({
            pageNum: _this.data.pageNum + 1,
            isLoading: true
        })

        getData(this);
    },
})

4.5.4 下拉刷新

        1、本页面开启下拉刷新;

{
  "usingComponents": {},
  "navigationBarTitleText": "精选文章",
  "enablePullDownRefresh":true
}

        2、每次下拉页面,都会触发onPullDownRefresh函数,在onPullDownRefresh函数进行数据重置即可;

/**
   * 页面相关事件处理函数--监听用户下拉动作
   */
onPullDownRefresh: function () {
    var _this = this;
    // 正常情况下,需要重新获取一次count,但是我们这里就不写
    _this.setData({
        hotArticles: [],
        pageNum: 1,
        isLoading:false,
        noData:false
    })

    // 获取第一页的数据
    getData(_this);
},

4.6 文章详情页

4.6.1 页面传参和数据获取

        文章详情页只有一个页面,里面的数据都是动态获取的,根据点击文章列表的id来获取对应的数据;

        1、定义文章详情页,在app.json里面定义

"pages/articleDetail/articleDetail",

        2、当我们点击文章列表的时候,跳转到文章详情页,并且把文章的id传递到文章详情页

<template name="articleTemplate">
    <navigator class="articleView" url="/pages/articleDetail/articleDetail?id={
   
   {ID}}" open-type="navigate">
        <view>
            <image src="{
   
   {IMAGE}}"></image>
        </view>
        <view class="articleContent">
            <view class="articleTitle">
                {
   
   {ARTICLES_TITLE}}
            </view>
            <view class="articleDesc">
                {
   
   {INFO}}
            </view>
        </view>
    </navigator>
</template>

        3、在文章详情页获取到传递过来的id值;

        4、根据id值去后台查询数据,查询得到的数据给data里面的articleDetail

        https://www.hnsfxlzx.com/www/article/get/获取得到的id值

onLoad: function (options) {
    var _this = this;
    // 获取文章详情
    wx.request({
        url: 'https://www.hnsfxlzx.com/www/article/get/'+options.id,
        header: {
            'content-type': 'application/json' // 默认值
        },
        success: function (res) {
            console.log(res);
            _this.setData({
                articleDetail:res.data.page
            })
        }
    })
},
<!--pages/articleDetail/articleDetail.wxml-->
<view class="articleTitle">
    {
   
   {articleDetail.articles_title}}
</view>
<view class="articleAuthor">
    来源:{
   
   {articleDetail.source}}
</view>
<view class="articleImg">
    <image src="https://www.hnsfxlzx.com/{
   
   {articleDetail.image}}"></image>
</view>
<view>
    {
   
   {articleDetail.articles_info}}
</view>
/* pages/articleDetail/articleDetail.wxss */
page{
    padding: 0 20rpx;
}

.articleTitle{
    height: 88rpx;
    line-height: 88rpx;
    font-size: 30rpx;
    font-weight: bold;
}

.articleAuthor{
    font-size: 26rpx;
    color: #A8A8A8;
    line-height: 36rpx;
}

.articleImg{
    text-align: center;
    margin: 20rpx 0;
}

4.6.2 富文本解析

        1、把富文本解析成微信小程序可以识别的代码,使用wxParse插件解析;

        参考文档:

小さなプログラム wxParse は、バックエンドからのリッチ テキスト コンテンツを解析しますhttps://blog.csdn.net/weixin_42065713/article/details/95043631

wx.parse は、リッチ テキスト html を wxml に解析します https://www.cnblogs.com/xiaoxiaoxun/p/12465053.html

        これを使用する場合、ディレクトリ構造を 1 つ少ないレイヤーで記述する必要があります。

<!--pages/articleDetail/articleDetail.wxml-->
<import src="../../wxParse/wxParse.wxml"/> 

<view class="articleContent">
    <template is="wxParse" data="{
   
   {wxParseData:content.nodes}}" />
</view>
var WxParse = require('../../wxParse/wxParse.js');

success: function (res) {
    console.log(res.data.page);
    // WxParse.wxParse(bindName , type, data, target,imagePadding)
    // * 1.bindName绑定的数据名(必填),解析成功之后的内容绑定到该数据名上;
    // * 2.type可以为html或者md(必填)
    // * 3.data为传入的具体数据(必填)
    // * 4.target为Page对象,一般为this(必填)
    // * 5.imagePadding为当图片自适应是左右的单一padding(默认为0,可选)
    let result = res.data.page;
    WxParse.wxParse('content', 'html', result.articles_info, _this, 5);
    _this.setData({
        articleDetail:res.data.page
    })
}

        2. フォントサイズ処理

@import "../../wxParse/wxParse.wxss";

.articleContent{
  width: 710rpx;
}

.wxParse-span{
  font-size: 24rpx!important;
  color: #353535!important;
}

.wxParse-p{
  line-height: 48rpx!important;
}

多様性チュートリアル ディレクトリ

環境構築記事:

01_WeChat ミニ プログラム プロジェクトをゼロから作成する_プロジェクトの概要

02_ゼロからWeChatミニプログラムプロジェクトを構築_プロジェクト環境構築

静的ページの記事:

03_WeChat ミニ プログラム プロジェクトをゼロから構築_ホームページの静的効果の実現

04_WeChat ミニ プログラム プロジェクトをゼロから構築_コンサルティング ページでの静的効果の実現

05_WeChat ミニ プログラム プロジェクトをゼロから構築_コース ページでの静的効果の実現

06_微信ミニプログラムプロジェクトをゼロから構築_マイページの静的効果実現

07_ゼロから WeChat ミニ プログラム プロジェクトを構築_注目の記事ページへの静的効果の実装

08_ゼロから WeChat アプレット プロジェクトを構築する_About us ページの静的効果の実現

09_WeChat ミニ プログラム プロジェクトをゼロから構築_コンサルタントの詳細ページでの静的効果の実現

10_WeChat ミニ プログラム プロジェクトを最初から作成する_ログイン ページでの静的効果の実装

11_WeChat ミニ プログラム プロジェクトをゼロから構築_登録ページでの静的効果の実装

データ操作に関する記事:

12_スクラッチからの WeChat ミニ プログラム プロジェクトの構築_データ インタラクション_ミニ プログラムの深い理解

13_Scratch からの WeChat ミニ プログラム プロジェクトのビルド_Data Interaction_WXML 構文の詳細な説明

14_ゼロからWeChatアプレットプロジェクトをビルド_データ連携_json-server詳細説明

15_Scratch からの WeChat ミニ プログラム プロジェクトの構築_Data Interaction_Home

16_Scratch からの WeChat ミニ プログラム プロジェクトの構築_データ インタラクション_ログインと登録

17_スクラッチからの WeChat ミニ プログラム プロジェクトの構築_データ インタラクション_選択した記事のリスト (カバー: アップリフト ロードとプルダウン リフレッシュ)

18_Scratch からの WeChat ミニ プログラム プロジェクトの構築_Data Interaction_Article Details ページ (カバー: マルチページ パラメータの受け渡しとリッチ テキスト分析)

B駅ビデオトレイン

2021年最新WeChatミニプログラムプロジェクト実践講座、入門から習熟まで、ゼロベースの入門ミニプログラム開発【構成資料+ソースコード+注意事項】_哔哩哔哩_bilibili

おすすめ

転載: blog.csdn.net/ligonglanyuan/article/details/120669474