微信小程序填坑之路(五):簡單的自定義組件

在微信小程序開發中,在很多地方會用到相似的UI布局時,如果我們每一頁都重寫一遍UI布局,不說效率低下,費時費力,在后期維護中如果需要更改UI布局,哪怕只是一個很小的改動,那么相同頁面就都需要改動,工程量大!所以,這時我們可以將相似的UI做成自定義組件,在需要的頁面引用,方便快捷!

效果圖

自定義picker
自定義picker

Step 1:創建component

這里寫圖片描述

組件目錄

上圖中,創建的component一共有四個文件,分別是js文件json文件wxml文件以及wxss文件

Step 2:繪制component

wxml

<!-- 帶標題的普通選擇器 -->
<block wx:if="{{show}}">
  <view class="we-title-picker-container">
    <view style="width:{{titleWidth}};font-size:{{titleSize}};color:{{titleColor}};">{{ title }}</view>
    <picker class="we-title-picker" 
            style="background:{{pickerBg}};border:{{borderSize}} solid {{borderColor}};" 
            value="{{pickerIndex}}" 
            range="{{pickerRange}}" 
            bindchange="_pickerChangeEvent">
      <view class="we-title-picker-content" style="font-size:{{contentSize}};color:{{contentColor}};">{{ content }}</view>
    </picker>
  </view>
</block>

wxss

.we-title-picker-container {
  display: flex;
  align-items: center;
  width: 100%;
  height: 100%;
}

.we-title-picker {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  box-sizing: border-box;
  overflow: hidden;
  padding: 15rpx;
}

.we-title-picker-content {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 110%;
  left: 15rpx;
  top: 15rpx;
  width: calc(100% - 30rpx);
  height: calc(100% - 30rpx);
}

Step 3:JS書寫

重點注意JS文件中的properties: {}以及methods: {}

// 選擇器的選擇方法名
const EVENT_PICKER_CHANGE = 'pickerChange';
// 默認屬性值
const DEF_CONFIG = {
  show: true,
  title: '標題',
  titleWidth: '220rpx',
  titleSize: '34rpx',
  titleColor: '#353535',
  pickerBg: 'white',
  pickerIndex: 0,
  pickerRange: null,
  content: '',
  contentSize: '34rpx',
  contentColor: '#353535',
  borderSize: '1rpx',
  borderColor: '#dadada',
}

Component({

  /**
   * 組件的屬性列表
   */
  properties: {
    // 是否顯示
    show: {
      type: Boolean,
      value: DEF_CONFIG.show
    },
    // 標題文字
    title: {
      type: String,
      value: DEF_CONFIG.title
    },
    // 標題的寬
    titleWidth: {
      type: String,
      value: DEF_CONFIG.titleWidth
    },
    // 標題文字的大小
    titleSize: {
      type: String,
      value: DEF_CONFIG.titleSize
    },
    // 標題文字的顏色
    titleColor: {
      type: String,
      value: DEF_CONFIG.titleColor
    },
    // 選擇器的選擇下標
    pickerIndex: {
      type: Number,
      value: DEF_CONFIG.pickerIndex
    },
    // 選擇器的選擇范圍
    pickerRange: {
      type: null,
      value: DEF_CONFIG.pickerRange
    },
    // 選擇器的背景
    pickerBg: {
      type: String,
      value: DEF_CONFIG.pickerBg
    },
    // 內容
    content: {
      type: String,
      value: DEF_CONFIG.content
    },
    // 內容文字的大小
    contentSize: {
      type: String,
      value: DEF_CONFIG.contentSize
    },
    // 內容文字的顏色
    contentColor: {
      type: String,
      value: DEF_CONFIG.contentColor
    },
    // 邊框的大小
    borderSize: {
      type: String,
      value: DEF_CONFIG.borderSize
    },
    // 邊框的顏色
    borderColor: {
      type: String,
      value: DEF_CONFIG.borderColor
    }
  },

  /**
   * 組件的初始數據
   */
  data: {

  },

  /**
   * 組件的方法列表
   */
  methods: {
    /**
     * 公共方法
     */
    // 顯示組件
    show: function (config) {
      this.setData({
        show: true,
        // 如果 config.title 有值,則使用 config.title;如果為空,則使用原來的 title 值,下面屬性類似
        title: config.title ? config.title : this.data.title,
        titleWidth: config.titleWidth ? config.titleWidth : this.data.titleWidth,
        titleSize: config.titleSize ? config.titleSize : this.data.titleSize,
        titleColor: config.titleColor ? config.titleColor : this.data.titleColor,
        pickerIndex: config.pickerIndex ? config.pickerIndex : this.data.pickerIndex,
        pickerRange: config.pickerRange ? config.pickerRange : this.data.pickerRange,
        pickerBg: config.pickerBg ? config.pickerBg : this.data.pickerBg,
        content: config.content ? config.content : this.data.content,
        contentSize: config.contentSize ? config.contentSize : this.data.contentSize,
        contentColor: config.contentColor ? config.contentColor : this.data.contentColor,
        borderSize: config.borderSize ? config.borderSize : this.data.borderSize,
        borderColor: config.borderColor ? config.borderColor : this.data.borderColor,
      });
    },
    // 隱藏組件
    hide: function () {
      this.setData({
        show: false
      });
    },
    /**
     * 內部方法,所有內部方法不適合在外部調用,為區別開公有方法,內部方法可以以 "_" 開頭
     */
    // 選擇器選擇事件,在 picker 中的 bindchange="_pickerChangeEvent" 被調用
    _pickerChangeEvent: function (e) {
      // 獲取事件 e 的 detail 值
      let _detail = { value: e.detail.value }
      // triggerEvent 為觸發事件函數,與 _pickerChangeEvent 綁定,用于外部調用 _pickerChangeEvent 方法
      // 參數 1:EVENT_PICKER_CHANGE ===> 是外部調用時使用的方法名
      // 參數 2:_detail ===> 傳遞給 EVENT_PICKER_CHANGE 方法的 detail 值,  
      // 不傳遞則 EVENT_PICKER_CHANGE  方法的 detail 值為空
      this.triggerEvent(EVENT_PICKER_CHANGE, _detail);
    }
  }
})

Step 4:在頁面中使用

  • 1、在頁面的json文件中添加組件引用
"usingComponents": {
    "we-title-picker": "/lib-me/ui/we-title-picker/we-title-picker",
    "we-title-date-picker": "/lib-me/ui/we-title-date-picker/we-title-date-picker",
    "we-simple-toast": "/lib-me/ui/we-simple-toast/we-simple-toast"
}  

引用規則 ===> "自定義組件名(可隨意取名)":"組件在項目中的相對路徑"
注意!注意!注意! ===> 自定義組件名不能以wx-開頭,否則在頁面中會報"找不到組件標簽"

  • 2、在頁面的wxml中調用
<!-- 多元統計頁面 -->
<view class="container">
  <view class="container-main">
    // 省略無關代碼
    ...... 
    <we-title-picker 
       id="customPicker"
       class="multi-hp-picker"   
       title="機器地點"   
       pickerRange="{{machinePosList}}"   
       content="{{machinePos}}"  
       bind:pickerChange="machineChange"   
       contentSize="30rpx" />
    // 省略無關代碼
    ......
  </view>
  <we-simple-toast id="toast" class="we-simple-toast" />
</view>

上述<we-title-picker ... >即為我們的自定義組件

  • titlepickerRangecontentcontentSize為我們的自定義屬性
  • bind:pickerChange="machineChange"為我們在JS中使用this.triggerEvent(EVENT_PICKER_CHANGE, _detail);方法向外暴露的自定義方法,EVENT_PICKER_CHANGE為方法名,即pickerChange注意:自定義方法前,一定要加bind,可以寫為bind:方法名或者bind方法名
  • 3、在頁面的JS中調用
  • 根據id獲取自定義組件對象: customPicker= this.selectComponent('#customPicker');
  • 調用自定義組件的方法,即methods: {...}中的方法:customPicker.show();
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容