釘釘E應用(小程序)之自定義組件開發(計數器)


文前嘮叨幾句:這個計數器demo雖然小,但也涵蓋了整個開發自定義組件的流程和頁面與組件之間的相互傳值的問題。 (並且這個小demo是從支付寶小程序這個大demo里面摳出來的,他兩除了api和一些小細節不同之外,自定義組件這方面也還是相通的,有興趣的朋友可以自己研究下)

官方文檔:https://open-doc.dingtalk.com/microapp/dev/develop-custom-component

最終效果 && 目錄:

先說說開發自定義組件Counter的開發:

1、json:

component 聲明當前的是組件 ;

( 可選 ) usingComponents 聲明所依賴的組件 ( 即當前的組件需要使用到另外一個自定義組件 ) 所在的位置。

 

2、axml:

( 其實跟寫平常的axml沒什么不同 )

<dd-test /> :只是展示所需要的組件怎樣插入到當前組件

<view 
  class="am-stepper-content {{className}}"
  style="opacity:{{disabled ? '0.4' : '1'}}"
  max="{{max}}"
  min="{{min}}"
  onChange="{{callBackFn}}"
  step="{{step}}"
  disabled="{{disabled || readOnly}}"
>
  <view class="am-stepper-reduce" style="opacity:{{opaReduce}}" data-type="reduce" onTap="changeFn"><text class="iconfont icon-sub"></text></view>
  <input
    class="am-stepper-input"
    style="display:{{showNumber ? 'inline-block' : 'none'}};"
    value="{{value}}"
    onBlur="onBlur"
    disabled="{{disabled || readOnly}}"
    type="number"
  />
  <view class="am-stepper-add" style="opacity:{{opaAdd}}" data-type="add" onTap="changeFn"><text class="iconfont icon-iconjia"></text></view>

<dd-test />  </view>

3、js:

調用Component定義組件

Component({
  data: {   //定義組件內所需要的變量  
    opaReduce: 1,
    opaAdd: 1
  },
  props: {  //設置默認值 && 接收傳過來的值   通過this.props.xx 獲取到默認值 && 傳過來的值
    className: '',
    min: 1,    //若沒有值傳進來,就使用該默認值 ;若傳有值進來,傳過來的值便覆蓋默認值
    max: 100,
    disabled: false,
    value: 10,   
    readOnly: false,
    showNumber: false,
    step: 1,
    onChange: function onChange() { }    //觸發該組件的事件
  },
  didMount: function didMount() { //頁面渲染完畢后執行 (組件的生命周期函數)
    var _props = this.props,
      value = _props.value,
      min = _props.min,
      max = _props.max;
    this.setData({
      value: Math.min(Math.max(min, value), max)   //更新value值
    });
  },
  // 官方解釋:didUpdate 為更新后回調,每次組件數據變更的時候都會調用(組件的生命周期函數)。
  // 鄙人解釋:一有神馬動作就立刻執行 
  didUpdate: function didUpdate(preProps) {   
    var _props2 = this.props,
      value = _props2.value,
      min = _props2.min,
      max = _props2.max;
    if (preProps.value !== value) {
      var newValue = Math.min(Math.max(min, value), max);
      this.setData({
        value: newValue
      });
      this.resetFn(newValue);
    }
  },
  methods: {
    changeFn: function changeFn(ev) {
      var _props3 = this.props,
        min = _props3.min,
        max = _props3.max,
        onChange = _props3.onChange,
        disabled = _props3.disabled,
        readOnly = _props3.readOnly,
        step = _props3.step;

      var evType = ev.target.dataset.type;
      var _data = this.data,
        opaReduce = _data.opaReduce,
        opaAdd = _data.opaAdd,
        value = _data.value;

      var enable = disabled || readOnly;
      if (!enable) {
        if (evType === 'reduce') {
          if (value > min) {
            opaAdd = 1;
            value = Math.max(min, +value - +step);
            opaReduce = value === min ? 0.4 : 1;
          }
        } else {
          /* eslint-disable no-lonely-if */
          if (value < max) {
            opaReduce = 1;
            value = Math.min(+value + +step, max);
            opaAdd = value === max ? 0.4 : 1;
          }
        }
        this.setData({
          value: value,
          opaAdd: opaAdd,
          opaReduce: opaReduce
        });
        // 值通過 this.props.onChange(xxx)將值傳出去
        onChange(value);
      }
    },
    onBlur: function onBlur(event) {  //失焦事件函數
      var value = event.detail.value;

      this.resetFn(value);
    },
    resetFn: function resetFn(value) {
      var _props4 = this.props,
        max = _props4.max,
        min = _props4.min,
        onChange = _props4.onChange;

      var calculatedVal = value;
      var opaAdd = 1;
      var opaReduce = 1;
      if (value >= max) {
        calculatedVal = max;
        opaAdd = 0.4;
      } else if (value <= min) {
        calculatedVal = min;
        opaReduce = 0.4;
      }
      this.setData({
        value: calculatedVal,
        opaAdd: opaAdd,
        opaReduce: opaReduce
      });
      onChange(calculatedVal);
    }
  }
});

4、acss

.am-stepper-content {
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  line-height: 70rpx;
  font-size: 40rpx;
  height: 70rpx;
  width: 280rpx;
  color: #000;
  border: 1rpx solid #dcdfe6;
}

.am-stepper-reduce,
.am-stepper-add {
  box-sizing: border-box;
  flex: 3;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 66rpx;
  background-color: #f5f7fa;
  border-top: none;
  border-bottom: none;
  border-left: 1rpx solid #dcdfe6;
  border-right: 1rpx solid #dcdfe6;
}

.am-stepper-input {
  box-sizing: border-box;
  flex: 3;
  height: 64rpx;
  padding-left: 53rpx;
  color: #000;
}

准備就緒,調用就簡單很多了

1、json:

2、axml:

<view class="page">
  <view class="page-description">Counter </view>

  <!-- 需要傳遞的值一定要用{{}}包起來 ;<dd-counter />:調用自定義組件 -->
  <dd-counter onChange="callBackFn" step="{{1}}" showNumber readOnly="{{false}}" value="{{5}}" min="{{2}}" max="{{12}}"/>
  
  <view style="padding-top: 10px;font-size: 30rpx;">當前的值為: {{val}}</view>
</view>

3、js:

Page({
  data:{
    val:''
  },
  callBackFn(e){   //e:自定義組件傳過來的數據
    this.setData({
      val: e
    })
  }
})

自定義組件還有神馬

  插槽:slot (用過vue都知道這是啥吧...)

  生命周期:1、didMount(組件渲染完畢后回調);2、didUpdate(組件數據更改后回調);3、didUnmount(組件刪除后回調);

  mixins:用來裝公共的邏輯的,例(官網例子改造):

  ;

等就不細說了,正在開發相關功能或還感興趣的朋友可移駕官方文檔,官方文檔有更詳細的說明和例子可以參考...

ok,文章就到這了,有神馬不足的地方,請務必指正,謝謝各位大佬看到此處...

注:轉載請標明出處...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM