微信小程序封裝bindinput & 輸入框出現清空圖標 & wx:key對input的影響


Q:我以前寫小程序每次獲取輸入內容,都要寫一個方法,覺得十分麻煩,所以寫了一個通用的方法。

A:我能想到的原理就是,不同的input所帶的data不同,bindinput事件setData不同的data。

<input class="weui-input" bindinput="bindKeyInput" data-inputName='telephone' placeholder="請輸入電話號碼"/>
 // 獲取輸入框的內容,封裝起來,根據data-的值去渲染不同的data
bindKeyInput: function (e) {
  let inputName = e.currentTarget.dataset.inputname;
  this.setData({
    [inputName]: e.detail.value
  })
},

 

 

Q:最近項目有一個需求,就是點擊輸入框時右邊顯示清空圖標。

A:我的思路是:好好利用bindfocus和bindblur,聚焦函數和非聚焦函數。聚焦時顯示清空圖標,非聚焦時隱藏清空圖標。

  // 清空輸入框的內容
  // 聚焦函數:如果字符串長度為0,則不顯示清空圖標,否則顯示清空圖標。
  bindKeyFocus: function (e) {
    let index = e.currentTarget.dataset.index;
    let fullInputName = `local.is_clear_icon[${index}]`;
    let inputLength = e.detail.value.length;
    inputLength == 0 ? this.setData({ [fullInputName]: true }) : this.setData({ [fullInputName]: false })
  },
  // 非聚焦函數:隱藏清空圖標
  bindKeyBlur: function (e) {
    let index = e.currentTarget.dataset.index;
    let inputName = e.currentTarget.dataset.inputname;
    let fullInputName = `local.is_clear_icon[${index}]`;
    let fullInputName2 = `local.${inputName}[0]`;
    let value = e.detail.value;
    if (this.data.local.test) { 
      value = [""]; 
      this.setData({ "local.test": false });
      }
    this.setData({ [fullInputName]: true, [fullInputName2]: value });
  },
  // 點擊圖標清空
  clearInput: function (e) {
    let inputName = e.currentTarget.dataset.inputname;
    let fullInputName = `local.${inputName}`;
    console.log(e.currentTarget.dataset.inputname, fullInputName)
    let index = e.currentTarget.dataset.index;
    let clearIcon = `local.focus[${index}]`;

    this.setData({ [fullInputName]: [""], [clearIcon]: false, "local.test": true })
  },
  
//名字輸入
<block wx:for="{{name}}" wx:key="idx" wx:for-index="idx"> <view class="weui-cell weui-cell_input"> <view class="weui-cell__hd wh-card-list-item"> <view class="weui-label wh-required" wx:if="{{idx == 0}}">姓名</view> </view> <view class="weui-cell__bd clear-input-father weui-flex" wx:if="{{idx == 0}}"> <input class="weui-input" data-inputName='name' placeholder="你的姓名" bindinput="bindKeyInput" value='{{item}}' bindfocus="bindKeyFocus" data-index="0" bindblur="bindKeyBlur"/> <icon class='clear-input' type="clear" size="20" hidden='{{is_clear_icon[0]}}' data-inputName='name' data-index="0" catchtap='clearInput'/> </view> <view class="weui-cell__bd clear-input-father weui-flex wh-white-space" wx:else> <view class='wh-white-space' data-index='{{idx}}' data-inputName='name' catchtap='chooseItem'>{{item}}</view> <icon class='clear-input' type="clear" size="20" data-index='{{idx}}' data-inputName='name' catchtap='deteleItem'/> </view> </view> </block>

//手機號輸入 <block wx:for="{{telephone}}" wx:key="*this" wx:for-index="idx"> <view class="weui-cell weui-cell_input"> <view class="weui-cell__hd wh-card-list-item"> <view class="weui-label wh-required" wx:if="{{idx == 0}}">手機號</view> </view> <view class="weui-cell__bd clear-input-father weui-flex" wx:if="{{idx == 0}}"> <input class="weui-input" type='number' placeholder="你的手機號" bindinput="bindKeyInput" data-inputName='telephone' value='{{item}}' bindfocus="bindKeyFocus" data-index="1" bindblur="bindKeyBlur" /> <icon class='clear-input' type="clear" size="20" hidden='{{is_clear_icon[1]}}' data-inputName='telephone' data-index="1" catchtap='clearInput'/> </view> <view class="weui-cell__bd clear-input-father weui-flex wh-white-space" wx:else> <view class='wh-white-space' data-index='{{idx}}' data-inputName='telephone' catchtap='chooseItem'>{{item}}</view> <icon class='clear-input' type="clear" size="20" data-index='{{idx}}' data-inputName='telephone' catchtap='deteleItem'/> </view> </view> </block>

 

 

Q:使用wx:for=“{{name}}”去渲染input輸入框,而input輸入框又修改了name的內容,這樣會出現一種情況:用戶一輸入之后,input便失去聚焦。

A:個人觀點:bindinput動態改變name的值,會重新渲染整個html代碼。wx:key值設置值不對,改為wx:key="index"即可。

  <block wx:for="{{name}}" wx:key="idx" wx:for-index="idx">
    <view class="weui-cell weui-cell_input">
        <view class="weui-cell__hd wh-card-list-item">
            <view class="weui-label wh-required" wx:if="{{idx == 0}}">姓名</view>
          </view>
          <view class="weui-cell__bd clear-input-father weui-flex" wx:if="{{idx == 0}}">
              <input class="weui-input" data-inputName='name'  placeholder="你的姓名" bindinput="bindKeyInput" value='{{item}}' bindfocus="bindKeyFocus" data-index="0" bindblur="bindKeyBlur"/>
               <icon class='clear-input' type="clear" size="20" hidden='{{is_clear_icon[0]}}' data-inputName='name' data-index="0" catchtap='clearInput'/>
            </view>
            <view class="weui-cell__bd clear-input-father weui-flex wh-white-space" wx:else>
               <view class='wh-white-space' data-index='{{idx}}' data-inputName='name' catchtap='chooseItem'>{{item}}</view>
               <icon class='clear-input' type="clear" size="20" data-index='{{idx}}' data-inputName='name' catchtap='deteleItem'/>
            </view>
      </view>
    </block>

下面這種就會失去聚焦:

  <block wx:for="{{telephone}}" wx:key="*this" wx:for-index="idx">
    <view class="weui-cell weui-cell_input">
        <view class="weui-cell__hd wh-card-list-item">
            <view class="weui-label wh-required" wx:if="{{idx == 0}}">手機號</view>
          </view>
          <view class="weui-cell__bd clear-input-father weui-flex" wx:if="{{idx == 0}}">
              <input class="weui-input" type='number' placeholder="你的手機號" bindinput="bindKeyInput" data-inputName='telephone' value='{{item}}' bindfocus="bindKeyFocus" data-index="1" bindblur="bindKeyBlur" />
               <icon class='clear-input' type="clear" size="20" hidden='{{is_clear_icon[1]}}' data-inputName='telephone' data-index="1" catchtap='clearInput'/>
            </view>
            <view class="weui-cell__bd clear-input-father weui-flex wh-white-space" wx:else>
               <view class='wh-white-space' data-index='{{idx}}' data-inputName='telephone' catchtap='chooseItem'>{{item}}</view>
               <icon class='clear-input' type="clear" size="20" data-index='{{idx}}' data-inputName='telephone' catchtap='deteleItem'/>
            </view>
      </view>
  </block>

這里主要是wx:key的應用:源於http://www.wxappclub.com/topic/536

wx:key 的值以兩種形式提供

  1. 字符串,代表在 for 循環的 array 中 item 的某個 property,該 property 的值需要是列表中唯一的字符串或數字,且不能動態改變。
  2. 保留關鍵字 *this 代表在 for 循環中的 item 本身,這種表示需要 item 本身是一個唯一的字符串或者數字,如:當數據改變觸發渲染層重新渲染的時候,會校正帶有 key 的組件,框架會確保他們被重新排序,而不是重新創建,以確保使組件保持自身的狀態,並且提高列表渲染時的效率。

1:有wx:key的情況(不重新創建,僅改變順序)

添加元素或改變元素順序導致數據改變時,
會校正帶有Key的組件(可通過key識別各組件),
框架會根據“目前數據”,重新排序各組件,而不是重新創建,
使組件保持自身的狀態,列表渲染效率高。

2:無wx:key的情況(重新創建)

添加元素或改變元素順序導致數據改變時,
此時各組件沒有key(無法識別各組件)
框架會被迫根據“目前數據”重新創建各組件,
使組件重置初始狀態(原有狀態自然被清空),列表渲染效率低。

B:兩種情況的對比

wk:key 組件識別 渲染情況 狀態情況 for效率
各組件可識別 渲染時僅改變組件順序 保持組件之前原來狀態 效率高
組件無法識別 渲染時重新創建各組件 重置組件的初始狀態 效率低


免責聲明!

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



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