微信小程序 自定義組件 - 彈出菜單demo

前言

以前看七月老師的視頻,介紹到template的時候,七月老師說,這個template有一個缺點,大概意思就是封裝度不夠,只模板化了頁面和樣式,邏輯那些寫不了。我也很困惑這件事,今天瞭解到自定義組件這個概念,就試了試,感受好像彌補了template的那個缺點,因而寫了個小demo,也算作個筆記html

我以爲git

  • 若是不須要傳參,也不須要向外發送事件的,能夠用include,至關於直接把佈局copy過去
  • 若是須要傳參,但不須要向外發送事件的,內部能夠處理的,能夠用template
  • 若是又須要傳參,又須要向外關聯一些事件的,能夠使用自定義組件

自定義組件的中心思想:將頁面內的功能模塊抽象成自定義組件,以便在不一樣的頁面中重複使用;也能夠將複雜的頁面拆分紅多個低耦合的模塊,有助於代碼維護github

效果

作的就是個菜單組件,數據由外部灌入。json

目前我還在看怎麼樣才能實現菜單彈出的阻尼動畫效果小程序

image

實現

代碼結構以下:微信小程序

image

新建組件menu:

image

menu.jsbash

var Logger = require('../utils/Logger.js')

Component({
 //組件暴露出去的屬性
  properties: {
    //若是這裏屬性比較多的話,還能夠將它們包裹成一個對象
    menu_list: Array,
  },

//組件內部使用的屬性
  data: {
    showMenu: true
  },

  attached: function() {
    this.setData({
      menu_list: this.data.menu_list
    })
  },
  methods: {
    // 點擊新建按鈕
    onCreateTap: function() {
      this.setData({
        showMenu: !this.data.showMenu
      })
    },
    // 點擊展開的單個按鈕
    onItemTap: function(event) {
      var item = event.currentTarget.dataset.item;
      // 微信小程序中是經過triggerEvent來給父組件傳遞信息的
      //triggerEvent:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html
      var menuEventDetail = {
        item
      }
      this.triggerEvent('handleMenu', menuEventDetail)
      //menuEventOption是觸發事件的選項,包括設置事件是否冒泡之類的,不過這裏默認是不冒泡的
      // var menuEventOption = {
      //   
      // }
      // this.triggerEvent('handleMenu', menuEventDetail, menuEventOption)
    }
  }
})
複製代碼

參考文檔中Component的生命週期微信

image

設置數據選擇在attached方法內。markdown

triggerEvent

查看文檔oop

this.triggerEvent(eventName, eventDetail, eventOption)

  • eventName:事件名稱
  • eventDetail:事件傳遞的對象,是eventName這個事件中detail屬性中的內容
  • eventOption:主要定義eventName這個事件是否要冒泡之類的,不過默認的都是false,能夠不用設置

image

還有個關鍵的地方:(其實最開始建立component的時候就自動生成了)全手打的話,要記得在menu.json裏添加自定義組件的聲明:

{
  "component": true,
  "usingComponents": {}
}
複製代碼

menu.wxml

菜單個數根據傳入的menu_list來,菜單顯隱由showMenu控制

<view class='container'>
  <view hidden="{{showMenu?false:true}}" class='sub-btn-container'>
    <block wx:for='{{menu_list}}' wx:key='index'>
      <view class='sub-btns' catchtap='onItemTap' data-item='{{item}}'>
        <image class='btn' src='{{item.src}}' />
        <text class='sub-btn__name'>{{item.name}}</text>
      </view>
    </block>
  </view>
  <image catchtap='onCreateTap' class='btn' src='/resources/imgs/ic_create.png' />
</view>
複製代碼

菜單的顯示內容,由外部datas/menu-data.js控制

var menu_list = [{
  id: 1,
  name: '帖子',
  src: '/resources/imgs/ic_create_1.png'
}, {
  id: 2,
  name: '資訊',
  src: '/resources/imgs/ic_create_2.png'
}, {
  id: 3,
  name: '照片',
  src: '/resources/imgs/ic_create_3.png'
}]

module.exports = {
  menu_list: menu_list
}
複製代碼

數據在使用的地方引入

組件的使用

home.js

var menuData = require('../../datas/menu-data.js')
var Logger = require('../../utils/Logger.js')

Page({
  onLoad: function() {
    this.setData({
      menu_list: menuData.menu_list,
    })
  },
  onReady: function() {
    this.menu = this.selectComponent("#menu");
  },
  handleMenu: function(event) {
    //這裏的detail就是在自定義組件中定義的menuEventDetail
    var item = event.detail.item;
    Logger.v("item", item);
    wx.showToast({
      title: '新建' + item.name,
    })
  }
})
複製代碼

home.wxml

<view>
  <!-- handleMenu爲父組件和自定義組件之間通訊的橋樑 -->
  <menu class='menu' menu_list='{{menu_list}}' bind:handleMenu='handleMenu' />
  <text class='text'>HOME</text>
</view>
複製代碼

還有個關鍵的地方:使用的地方,這裏是home,要記得在home.json中使用該組件(引號前面的至關於別名,起啥名,wxml裏就用啥名)

home.json

{
  "usingComponents": {
    "menu": "/components/menu"
  }
}
複製代碼

傳送門

相關文章
相關標籤/搜索