微信小程序之組件的集合(四)

  這個主要是來開發book的這個大模塊的,看看如何優雅的開發出booked模塊!html

1、book模塊的建立json

這個就很簡單了,建立一個大的框架是很簡單的小程序

 2、組件的編寫微信小程序

(1)wxml組件頁面的編碼promise

首先是將一本書的展現看作是一個組件,而後就是循環展現全部請求的書籍的信息,因此須要把一本書當作一個組件來製做,這樣就能比較合理的解決這個問題!服務器

 1 // book組件的頁面的代碼
 2 <view class="container">
 3   <image src="{{book.image}}"></image>
 4   <view class="description">
 5     <text class="title">{{book.title}}</text>
 6     <text class="author">{{book.author}}</text>
 7     <view class="foot">
 8       <text class="footer">{{book.fav_nums}} 喜歡</text>
 9     </view>
10   </view>
11 </view>

將這個book組件引用到page中去,給用戶展現書籍的信息,須要在book.json 中引入,而且將組件的寫到book.wxml頁面代碼中,這裏暫時只是展現一個book組件微信

 1 // page中的book.json 中引入book組件
 2 {
 3   "usingComponents": {
 4     "v-book":"/components/book/index"
 5   }
 6 }
 7 
 8 // page中的book.wxml中引入v-book標籤
 9 <v-book book="{{books[0]}}" />
10 
11 // page中的book.js中操做數據,將數據傳遞到頁面屬性中,只寫主要的生命週期函數
12 import {
13   BookModel
14 } from '../../models/book.js';
15 
16 // 實例化BookModel對象
17 const bookModel = new BookModel();
18 
19 Page({
20 
21   /**
22    * 頁面的初始數據
23    */
24   data: {
25     // 服務器請求的數據 book的集合
26     books:[]
27   },
28 
29   /**
30    * 生命週期函數--監聽頁面加載
31    */
32   onLoad: function(options) {
33     // 這種寫法才能規避回調地獄的
34     bookModel.getHotList()
35     .then(res => {
36       // 這種寫法不完善 只是作了賦值 頁面沒法獲取到
37       // this.data.books = res
38       this.setData({
39         books:res
40       })
41     })
42 
43   },

(2)book組件樣式的編碼框架

這個啊,讓人頭疼的,我是寫不出來,哈哈xss

 1 .container{
 2   margin-top: 30rpx;
 3   display: flex;
 4   position: relative;
 5   box-shadow: 2px 2px 3px #e3e3e3;
 6   flex-direction: column;
 7   width: 240rpx;
 8   height: 360rpx;
 9 }
10 
11 /* 書籍封面的樣式 */
12 .container image {
13   width: 100%;
14   height: 100%;
15   border-radius: 2px;
16 }
17 
18 .description{
19   width: 216rpx;
20   position: absolute;
21   bottom: 0;
22   background-color: #fff;
23   padding: 5rpx 10rpx 8rpx 15rpx;
24   font-size: 24rpx;
25   display: flex;
26   flex-direction: column;
27   border-bottom-left-radius: 2px;
28   border-bottom-right-radius: 2px;
29 }
30 
31 .title{
32   margin-top: 10rpx;
33   text-overflow: ellipsis;
34   white-space: nowrap;
35   overflow: hidden;
36 }
37 
38 .author{
39   font-size: 20rpx;
40   color: #999999;
41   margin-bottom: 10rpx;
42   text-overflow: ellipsis;
43   white-space: nowrap;
44   overflow: hidden;
45 }
46 
47 .foot{
48   font-size: 20rpx;
49   display: flex;
50   flex-direction: row;
51   justify-content: flex-end;
52 }
53 
54 .footer{
55   color: 
56 }

3、組件的應用函數

由於書籍是使用的一組的書籍組件,如何來把服務器上傳回來的全部的書籍信息所有顯示出來,這個就是咱們須要考慮的,須要完成的

小程序中確定是存在相似for循環的,那就是wx:for 可是在小程序中並非叫作for循環,而是叫作列表渲染

(1)列表渲染

1 <block wx:for="{{books}}">
2   <v-book book="{{item}}" />
3 </block>

 (2)總體頁面佈局

這個就是pages中的book頁面的代碼了,主題包含一個搜索欄,以及下面的圖書列表

 1 <view class="container">
 2   <view class="header">
 3     <view class="box">
 4       <image src="/images/icon/search.png"></image>
 5       <text>搜索書籍</text>
 6     </view>
 7   </view>
 8   <view class="sub-container">
 9     <image src="/images/book/quality.png" class="head-img"></image>
10     <view class="books-container">
11       <block wx:for="{{books}}">
12         <v-book book="{{item}}" />
13       </block>
14     </view>
15   </view>
16 </view>

(3)總體的樣式代碼

看一下如何設計樣式來讓這個頁面看起來那麼舒服,這是最難的吧,充分靈活的使用flex佈局來實現這樣的樣式

 1 .container{
 2   display: flex;
 3   flex-direction: column;
 4   align-items: center;
 5   width:100%;
 6 }
 7 
 8  .sub-container{
 9   display: flex;
10   flex-direction: column;
11   align-items: center;
12   background-color: #f5f5f5;
13   margin-top:100rpx;
14   /* z-index:0;  */
15 } 
16 
17 .books-container{
18   margin-top:10rpx;
19   display: flex;
20   flex-direction: row;
21   flex-wrap: wrap;
22   padding: 0 90rpx 0 90rpx;
23   justify-content: space-between;
24 }
25 
26 .books-container v-book{
27   margin-bottom: 30rpx;
28 }
29 
30 .box{
31   display:flex; 
32   flex-direction: row;
33   justify-content: center;
34   align-items: center; 
35   border-radius: 50px;
36   background-color: #f5f5f5;
37   height: 34px;
38   width:700rpx;
39   color:#999999;
40 }
41 
42 .header{
43   /* fixed 是使得容器固定 */
44   position: fixed; 
45   background-color: #ffffff;
46   height:100rpx;
47   width:100%;
48   border-top:1px solid #f5f5f5;
49   border-bottom:1px solid #f5f5f5;
50   display: flex;
51   flex-direction: row;
52   align-items: center;
53   justify-content: center;
54   box-shadow:0 0 3px 0 #e3e3e3; 
55   z-index: 99;
56 }
57 
58 .head-img{
59   width:106rpx;
60   height:34rpx;
61   margin-top:40rpx;
62 }
63 
64 .box image{
65   margin-right:10px;
66   width:14px;
67   height:14px;
68   margin-bottom:-2px;
69 }

4、book組件中業務邏輯的實現

這個主要是實現功能就是從book列表頁面用戶直接點擊以後,跳轉到書籍的詳細信息的頁面,這個該如何實現,是在組件中實現跳轉邏輯,仍是在頁面上實現,如何取捨,如何選擇,是選擇組件的通用性呢?仍是選擇組件的設計實現簡單呢?如何來寫這個邏輯代碼?

一、不考慮組件的通用性

不考慮組件通用性的話,就直接在組件中實現頁面的跳轉就OK了,具體的實現代碼以下:

 1 // 組件中的wxml文件
 2 <view bind:tap="onTap" class="container"> 
 3 </view>
 4 
 5 // 組件中的js文件 小程序中的navigateTo實現跳轉
 6   methods: {
 7     onTap(event){
 8       const bid = this.properties.book.id;
 9       wx.navigateTo({
10         url: `/pages/book-detail/book-detail?bid=${bid}`,
11       })
12     }
13   }

二、考慮組件通用性的

5、book詳細信息的開發

一、小程序中的編譯模式

爲了方便開發,讓小程序每次編譯以後都會是書籍詳細信息的頁面,咱們能夠添加編譯模式,來控制編譯以後的啓動頁面,這樣有利於提升開發效率:

選擇本身定義的編譯模式:

 二、具體book詳情頁面的開發

首先把詳情頁面的樣式也頁面的代碼進行編寫,這裏就是沒有按照順序來整理出來代碼,直接把完整的代碼都拿出來吧

 首先是詳情頁面的wxml文件中靜態頁面代碼:(這裏不是完整的,下面的點評功能沒有實現)

 1 <wxs src="../../util/filter.wxs" module="util"/>
 2 <view class="container">
 3   <!-- 頭部信息 -->
 4   <view class="head">
 5     <image src="{{book.image}}"></image>
 6     <text class="title">{{book.title}}</text>
 7     <text class="author">{{book.author}}</text>
 8   </view>
 9   <!-- 短評 -->
10   <view class="sub-container">
11     <text class="headline">短評</text>
12     <view class="comment-container">
13       <block wx:for="{{util.limit(comments,10)}}" wx:key="">
14         <v-tag tag-class="{{index==0?'ex-tag1':'' || index==1?'ex-tag2':''}}" text="{{item.content}}">
15           <text class="num" slot="after">{{"+" + item.nums}}</text>
16         </v-tag>
17       </block>
18     </view>
19     <!-- 內容簡介 -->
20     <view class="sub-container">
21       <text class="heading">內容簡介</text>
22       <text class="content" decode="{{true}}">{{util.format(book.summary)}}</text>
23     </view>
24   </view>
25   <!-- 書籍出版信息 -->
26   <view class="sub-container">
27     <text class="heading">書籍信息</text>
28     <view class="detail-container">
29       <view class="vertical description">
30         <text>出版社</text>
31         <text>出版年</text>
32         <text>頁數</text>
33         <text>訂價</text>
34         <text>裝幀</text>
35       </view>
36       <view class="vertical">
37         <text>{{book.publisher}}</text>
38         <text>{{book.pubdate}}</text>
39         <text>{{book.pages}}</text>
40         <text>{{book.price}}</text>
41         <text>{{book.binding}}</text>
42       </view>
43     </view>
44   </view>
45 </view>·

接下來是wxss樣式的代碼:

  1 .container {
  2   background-color: #f5f5f5;
  3   width: 100%;
  4 }
  5 
  6 .head {
  7   background-color: #fff;
  8   padding-top: 40rpx;
  9   padding-bottom: 40rpx;
 10   display: flex;
 11   flex-direction: column;
 12   align-items: center;
 13 }
 14 
 15 .title {
 16   color: #2f2f2f;
 17   margin-top: 20rpx;
 18   font-size: 38rpx;
 19   font-weight: 600;
 20 }
 21 
 22 .author {
 23   font-size: 28rpx;
 24   color: #999;
 25 }
 26 
 27 .head image {
 28   width: 200rpx;
 29   height: 300rpx;
 30   box-shadow: 2px 2px 3px #e3e3e3;
 31 }
 32 
 33 .sub-container {
 34   width: 690rpx;
 35   display: flex;
 36   flex-direction: column;
 37   align-items: center;
 38   margin-top: 30rpx;
 39   background-color: #fff;
 40   padding: 30rpx;
 41 }
 42 
 43 .headline {
 44   font-size: 30rpx;
 45   font-weight: 600;
 46   color: #2f2f2f;
 47   margin-bottom: 20rpx;
 48 }
 49 
 50 .comment-container {
 51   display: flex;
 52   flex-direction: row;
 53   flex-wrap: wrap;
 54 }
 55 
 56 .comment-container v-tag {
 57   margin-right: 15rpx;
 58   margin-bottom: 10rpx;
 59 }
 60 
 61 .num {
 62   margin-left: 10rpx;
 63   font-size: 22rpx;
 64   color: #aaa;
 65 }
 66 
 67 .content{
 68   text-indent: 58rpx;
 69   font-weight: 500
 70 }
 71 
 72 /* 給標籤前兩個設置背景色 這種設置違背了組件的封裝原則的*/
 73 
 74 /* 這裏引入了小程序中的externalClasses來進行自定義組件的樣式的設置 */
 75 
 76 /* .comment-container > v-tag:nth-child(1) > view{
 77   background-color: #fffbdd;
 78 }
 79 
 80 .comment-container > v-tag:nth-child(2) > view{
 81   background-color: #eefbff;
 82 } */
 83 
 84 /* !important 強制提升外部樣式的權限 */
 85 
 86 .ex-tag1 {
 87   background-color: #fffbdd !important;
 88 }
 89 
 90 .ex-tag2 {
 91   background-color: #eefbff !important;
 92 }
 93 
 94 /* 書籍出版信息樣式 */
 95 .detail-container{
 96   width: 100%;
 97   display: flex;
 98   flex-direction: row;
 99   justify-content: flex-start;
100   margin-bottom: 100rpx;
101   font-size: 28rpx;
102   color: #666;
103 }
104 
105 .vertical{
106   display: flex;
107   flex-direction: column;
108 }
109 
110 .description{
111   color: #999;
112   margin-right: 30rpx;
113 }

最後是book詳情頁面的js代碼:

 1 import {
 2   BookModel
 3 } from '../../models/book.js';
 4 
 5 // 實例化BookModel對象
 6 const bookModel = new BookModel();
 7 
 8 Page({
 9 
10   /**
11    * 頁面的初始數據
12    */
13   data: {
14     comments:[],
15     book:null,
16     likeStatus:false,
17     likeCount:0
18   },
19 
20   /**
21    * 生命週期函數--監聽頁面加載
22    */
23   onLoad: function (options) {
24     // 從外部頁面傳遞過來的參數id
25     const bid = options.bid;
26     console.log(bid);
27     const detail = bookModel.getDetail(bid);
28     const comments = bookModel.getComments(bid);
29     const likeStatus = bookModel.getLikeStatus(bid);
30 
31     // 利用promise的then的回調獲取數據
32     detail.then(res => {
33       // console.log(res);
34       this.setData({
35         book:res
36       })
37     })
38 
39     comments.then(res => {
40       // console.log(res);
41       this.setData({
42         comments:res.comments
43       })
44     })
45 
46     likeStatus.then(res =>{
47       // console.log(res);
48       this.setData({
49         likeStatus:res.like_status,
50         likeCount:res.fav_nums
51       })
52     })
53 
54   },

 三、小程序插槽slot

這裏的插槽很適合來作自定義組件的,這種用法非誠靈活,感受真的有一種美妙的感受-slot的官方介紹:

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#組件wxml的slot

其實文檔中已經寫的很清楚了,可是仍是看一下老師的講解,畢竟在實戰中引用纔是最重要的,如何將理論的東西應用到實戰中,是很值得思考的東西

1 <view class="container">
2   <slot name="before"></slot>
3   <text>{{text}}</text>
4   <!-- 微信小程序中的 插槽 slot -->
5   <slot name="after"></slot>
6 </view>

這個其實就至關於佔位符,我事先在這裏佔有一個位置,隨時等待有人來佔有這個地方,可是若是沒人來佔,對整體的佈局也不會產生影響,有人的話,我就要把這我的給大家展現出來了,這我的就和組件中的其餘的標籤融爲一體了,注意這裏須要指定slot的name值,由於在page中是須要根據name值來找具體哪一個slot的

看page中如何插入到插槽中slot的:

1   <view class="sub-container">
2     <text class="headline">短評</text>
3     <view class="comment-container">
4       <block wx:for="{{comments}}" wx:key="">
5         <v-tag text="{{item.content}}">
6           <text class="num" slot="after">{{"+" + item.nums}}</text>
7         </v-tag>
8       </block>
9     </view>

這裏是將text標籤插入到插槽中,那麼插槽中就會被一個text標籤徹底的佔有了,你看到就是text標籤中的內容了

可是,這樣的話,slot並不會生效,須要在配置一個參數,就是:

1   options: {
2     multipleSlots:true
3   },

這樣的話,才能實現slot的功能

四、小程序中的externalClasses

這個是說的是小程序中的自定義組件如何來引入外部樣式類,就是如何將page中的樣式放入到自定義組件中,使其生效,小程序提供了externalClasses這個配置,能夠應用這個設置來解決這個問題

小程序中國的官方的介紹文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#外部樣式類

仍是來看一下這個東西是如何在實戰中應用的:

首先,看自定義組件中須要設置哪些地方:

 1 // 首先是須要設置 js中配置
 2   externalClasses:[
 3     'tag-class'
 4   ],
 5 
 6 // 其次是須要在頁面中使用這個自定義class
 7 <!-- tag標籤組件 短評以及搜索中的標籤組件 -->
 8 <view class="container tag-class">
 9   <slot name="before"></slot>
10   <text>{{text}}</text>
11   <!-- 微信小程序中的 插槽 slot -->
12   <slot name="after"></slot>
13 </view>

這樣的話,咱們就能夠在使用自定義標籤的時候來傳遞樣式進去了

 1 // 這裏面有一個樣式的切換 第一個和第二個分別展現不一樣的背景色  
 2 <view class="sub-container">
 3     <text class="headline">短評</text>
 4     <view class="comment-container">
 5       <block wx:for="{{comments}}" wx:key="">
 6         <v-tag tag-class="{{index==0?'ex-tag1':'' || index==1?'ex-tag2':''}}" text="{{item.content}}">
 7           <text class="num" slot="after">{{"+" + item.nums}}</text>
 8         </v-tag>
 9       </block>
10     </view>

再來看一下ex-tag1與ex-tag2的樣式設置

1 .ex-tag1 {
2   background-color: #fffbdd !important;
3 }
4 
5 .ex-tag2 {
6   background-color: #eefbff !important;
7 }

注意:!important 這裏是提升該樣式的重要性的,若是沒有的話,雖然外部樣式已經設置進去了,可是可能會被默認的樣式覆蓋的,這裏爲了強制覆蓋默認樣式而進行的設置

 五、小程序中的wxs

這個文件的主要功能就是在wxml文件中能夠調用外部的js代碼,固然js代碼是放在wxs文件中的,看看這個新的知識點是如何來實現的,官方文檔:

https://developers.weixin.qq.com/miniprogram/dev/reference/wxs/01wxs-module.html

 

 開始編寫邏輯代碼:

 1 // filter.wxs文件中代碼 注意model.exports導出 var關鍵字 正則替換寫法
 2 var format = function(text){
 3   if(!text){
 4     return
 5   }
 6   var reg = getRegExp('\\\\n','g');
 7   return text.replace(reg,'\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
 8 
 9 }
10 
11 module.exports = {
12   format:format
13 }
14 
15 // 頁面中的引入代碼
16 <wxs src="../../util/filter.wxs" module="util"/>
17 // 標籤中使用
18 <text class="content" decode="{{true}}">{{util.format(book.summary)}}</text>

 

內容出處:七月老師《純正商業級小程序開發》視頻課程
相關文章
相關標籤/搜索