微信小程序开发(三)

5.5k words

知识点


自定义组件

自定义组件的引用:

需要引用的页面的json文件下

{
  "usingComponents": {
     "l-icon":"/miniprogram_npm/lin-ui/icon/index"
  }
}

自定义组件的属性定义:

index.js

properties: {
    // text: {
    //     type: String,
    //     value: '123'
    // },
    text: String
},

properties 里定义的属性也可以用作数据绑定。

尝试将阅读页面文章列表封装到组件

post.wxml 里的文章列表代码剪切进组件 index.wxml 里,把 post.wxss 里的文章列表样式剪切进组件的 index.wxss 里。

数据绑定(如何把post页面的值传给components)

<!-- posts.wxml -->
<block wx:for="{{postList}}" wx:key="index">
   <!-- 因为在wx:for循环里,wx:for循环里的每一个数组是用item去指代的 -->
   <post res="{{item}}" />
</block>
   // index.js
   properties: {
      res: Object
   },
<!-- index.wxml -->
<view data-id="{{res.postId}}" bind:tap="onGoToDetail" class="post-container">
      <view class="post-author-date">
         <image class="post-author" src="{{res.avater}}"></image>
         <text class="post-date">{{res.date}}</text>
      </view>
      <text class="post-title">{{res.title}}</text>
      <image class="post-image" src="{{res.headImg}}"></image>
      <text class="post-content">{{res.content}}</text>
      <view class="post-like">
         <l-icon class="post-like-image" color="#666" size="26" name="favor" />
         <text class="post-like-font">{{res.collection}}</text>
         <l-icon class="post-like-image" color="#666" size="32" name="eye" />
         <text class="post-like-font">{{res.reading}}</text>
      </view>
   </view>

以后写小程序时需要优先写组件,并且在写组件时可以嵌套引用组件。

嵌套组件一般从内到外写。


字数过多时用CSS样式进行省略处理的方法

/* components/movie/movie.wxss */
.container {
   display: flex;
   flex-direction: column;
   width: 200rpx; /* 主要用以限定文字的空间 */
}

.poster {
   height: 270rpx;
   width: 100%;
   margin-bottom: 22rpx;
}

.title {
   /* 字数过多时进行省略(固定了范围时生效) */
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
   word-break: break-all;
}

外部样式类

// components/movie-list/index.js
Component({
   externalClasses: ['d-class'],
})
<!--components/movie-list/index.wxml-->
<view class="container d-class">
</view>
<!--pages/movies/movies.wxml-->
<movie-list d-class="movie-list"/>
/* pages/movies/movies.wxss */
.movie-list {
   margin-bottom: 35rpx;
}

访问服务端数据

最好不要在组件内向服务端发起请求。(通用性)

// pages/movies/movies.js
Page({
   /**
    * 生命周期函数--监听页面加载
    */
   onLoad(options) {
      wx.request({
         url: 'http://t.talelin.com/v2/movie/in_theaters?star=0&count=3',
         success: (res) => {
            // 不能直接用this.setData,因为this指代不明
            this.setData({
               inTheaters: res.data.subjects
            })
         }
      })
   },
})

然后一层层传给需要的组件:

// components/movie-list/index.js
Component({
   externalClasses: ['d-class'],
   /**
    * 组件的属性列表
    */
   properties: {
      title: String,
      movies: Array
   },
})
<!--pages/movies/movies.wxml-->
<movie-list movies="{{inTheaters}}" title="正在热映" d-class="movie-list"/>
// components/movie/index.js
Component({
   /**
    * 组件的属性列表
    */
   properties: {
      movie: Object
   },
})
<!--components/movie-list/index.wxml-->
<view class="container d-class">
   <view class="movie-container">
      <block wx:for="{{movies}}" wx:key="index">
         <movie movie="{{item}}" />
      </block>
   </view>
</view>

如何对服务端传来的数据进行处理:

  1. wxs
  2. js 文件里处理完数据再用

更多电影页面

WXSS文件

包括 flex-wrapjustify-content 的应用

/* pages/more-movie/more-movie.wxss */
.container {
   padding: 40rpx 30rpx;
   display: flex;
   flex-direction: row;
   /* 自动换行 */
   flex-wrap: wrap;
   /* 居中 */
   justify-content: space-between;
}

.movie {
   margin-bottom: 30rpx;
}

解决只有两个元素时排布问题

.search-container::after {
   content: '';
   width: 200rpx;
}

如何实现不同“更多电影”页面的跳转

<!--pages/movies/movies.wxml-->
<movie-list data-type="in_theaters" bind:tap="onGotoMore" movies="{{inTheaters}}" title="正在热映" d-class="movie-list" />
<movie-list data-type="coming_soon" bind:tap="onGotoMore" movies="{{comingSoon}}" title="即将上映" d-class="movie-list" />
<movie-list data-type="top250" bind:tap="onGotoMore" movies="{{top250}}" title="豆瓣Top250" d-class="movie-list" />
// pages/movies/movies.js
onGotoMore(event) {
    const type = event.currentTarget.dataset.type
    wx.navigateTo({
        url: '/pages/more-movie/more-movie?type=' + type,
    })
},
// pages/more-movie/more-movie.js
const app = getApp()
Page({
   onLoad(options) {
      const type = options.type
      wx.request({
         url: app.gBaseUrl + type + '?star=0&count=12',
         success: (res) => {
            this.setData({
               movies: res.data.subjects
            })
         }
      })
   },
})

上拉触底加载更多

// pages/more-movie/more-movie.js
const app = getApp()
Page({

   /**
    * 页面的初始数据
    */
   data: {
      movies: [],
      _type: ''
   },

    * 页面上拉触底事件的处理函数
    */
   onReachBottom: function () {
      wx.showNavigationBarLoading()
      wx.request({
         url: app.gBaseUrl + this._type,
         data: {
            start: this.data.movies.length,
            count: 12
         },
         success: (res) => {
            this.setData({
               // 合并数据
               movies: this.data.movies.concat(res.data.subjects)
            })
            wx.hideNavigationBarLoading()
         }
      })
   },
})
Comments