首頁  >  文章  >  微信小程式  >  詳解一個自訂的微信小程式組件(modal彈跳窗組件)

詳解一個自訂的微信小程式組件(modal彈跳窗組件)

php是最好的语言
php是最好的语言原創
2018-08-01 10:05:238483瀏覽

小程式不知從何時​​火起來的,很多人都入坑了吧,對於搞開發的小夥伴來說,不管是android,ios,還是很流行的微信小程序,

#都會發現官方提供的原生控制項已經無法完全滿足我們的開發需求,所以本文介紹的就是一個自訂的微信小程式元件(modal彈窗元件),

先來一張圖。

詳解一個自訂的微信小程式組件(modal彈跳窗組件)

 看到這裡了,說明效果圖還是對你有點吸引的麼,哈哈,廢話不多說了,開始上程式碼。 。 。

總共是四個檔案js、json、xml,wxss,如果這個都還不清楚的童鞋請出門左拐,面壁思過5分鐘。

先上佈局dialog.xml檔

<!--mask dialog-->
<view class="drawer_screen" bindtap="hideDialog" wx:if="{{isShow}}" catchtouchmove="myCatchTouch"></view>
<!--content-->
<!--使用animation属性指定需要执行的动画-->
<view animation="{{animationData}}" class="drawer_box" wx:if="{{isShow}}">

  <!--drawer content-->
  <view class=&#39;row&#39;>
    <view class="drawer_title" style=&#39;width:100%;padding-left:60rpx&#39;>{{title}}</view>
    <icon type="clear" style=&#39;margin-top:40rpx;margin-right:20rpx;&#39; bindtap="hideDialog"></icon>
  </view>
  <form bindsubmit="_formSubmit">
    <scroll-view scroll-y>
      <view class="drawer_content">
        <view wx:for="{{dataObject}}" wx:key="{{id}}">
          <view class="top grid">
            <label class="title col-0" style="color:red" wx:if="{{item.must}}">*</label>
            <label class="title col-0" wx:else> </label>
            <input class="input_base input_h30 col-1" placeholder=&#39;{{item.placeholder}}&#39; wx:if="{{item.type === type_input}}" name="{{item.id}}" value="{{bean[item.id]}}"></input>
            <view class="input_base input_h30 col-1" wx:elif="{{item.id === id_sex}}" hover-class=&#39;btn_ok_hover&#39; bindtap=&#39;{{item.event}}&#39;>{{sexDefault}}</view>
            <view class="input_base input_h30 col-1" wx:elif="{{item.id === id_group}}" hover-class=&#39;btn_ok_hover&#39; bindtap=&#39;{{item.event}}&#39;>{{groupDefault}}</view>
          </view>
        </view>
      </view>
    </scroll-view>
    <button class="btn_ok" hover-class=&#39;btn_ok_hover&#39; formType="submit">确定</button>
  </form>
</view>

然後是dialog.wxss檔

/*mask dialog start*/
.drawer_screen {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  right:0;
  bottom:0;
  z-index: 1000;
  background: #000;
  opacity: 0.5;
  overflow: hidden;
}

/*content*/

.drawer_box {
  width: 650rpx;
  overflow: hidden;
  position: fixed;
  top: 50%;
  left: 0;
  z-index: 1001;
  background: #fafafa;
  margin: -480rpx 50rpx 0 50rpx;
  border-radius: 6px;
}

.drawer_title {
  padding: 15px;
  font: 20px "microsoft yahei";
  text-align: center;
}

.drawer_content {
  height: 720rpx;
  /*overflow-y: scroll; 超出父盒子高度可滚动*/
}

.btn_ok {
  padding: 10px;
  font: 20px "microsoft yahei";
  text-align: center;
  border-top: 1rpx solid #e8e8ea;
  color: #3cc51f;
}

.btn_ok_hover {
  color: #aaa;
  background: #d9d9d9;
}

.top {
  padding-top: 8px;
}

.input_base {
  border: 2rpx solid #ccc;
  border-radius: 20rpx;
  padding-left: 20rpx;
  margin-right: 20rpx;
}

.input_h30 {
  height: 30px;
  line-height: 30px;
}

.title {
  height: 30px;
  line-height: 30px;
  width: 40rpx;
  text-align: center;
  display: inline-block;
  font: 300 28rpx/30px "microsoft yahei";
}

.grid {
  display: -webkit-box;
  display: box;
}

.col-0 {
  -webkit-box-flex: 0;
  box-flex: 0;
}

.col-1 {
  -webkit-box-flex: 1;
  box-flex: 1;
}

/*mask dialog end*/

.row {
  display: flex;
  flex-direction: row;
}

再然後是dialog.js檔

// components/Dialog/dialog.js
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  /**
   * 组件的属性列表
   */
  properties: {
    title: { // 属性名
      type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
      value: &#39;标题&#39; // 属性初始值(可选),如果未指定则会根据类型选择一个
    }

  },

  /**
   * 组件的初始数据
   */
  data: {
    // 弹窗显示控制
    isShow: false,
    type_input: "input",
    type_btn: "button",
    id_sex: "sex",
    id_group: "group",
    dataObject: [],
    sexDefault: "男",
    groupDefault: "组织",
    sexArray: [&#39;男&#39;, &#39;女&#39;],
    groupArray: [&#39;组织&#39;, &#39;群众&#39;],
    bean: {},
  },

  /**
   * 组件的方法列表
   */
  methods: {
    /*
     * 公有方法
     */
    setDataObj(dataObj,beanObj) {
      this.setData({
        dataObject: dataObj,
        bean: beanObj
      })
      if (beanObj.hasOwnProperty("sex") && beanObj.sex != ""){
        this.setData({
          sexDefault: beanObj.sex
        })
      }
      if (beanObj.hasOwnProperty("group") && beanObj.group != "") {
        this.setData({
          groupDefault: beanObj.group
        })
      }
    },
    //隐藏弹框
    hideDialog() {
      this._showOrCloseDialog("close")
    },
    //展示弹框
    showDialog() {
      this._showOrCloseDialog("open")
    },
    /*
     * 内部私有方法建议以下划线开头
     * triggerEvent 用于触发事件
     */

    _formSubmit(e) {
      if ("" === e.detail.value.name) {
        wx.showToast({
          title: &#39;请填写姓名&#39;,
          icon: &#39;none&#39;
        })
        return
      }
      if ("" === e.detail.value.phone) {
        wx.showToast({
          title: &#39;请填写电话&#39;,
          icon: &#39;none&#39;
        })
        return
      }
      this._showOrCloseDialog("close")
      //触发成功回调
      this.triggerEvent("confirmEvent", {
        e: e
      });
    },

    sexButton: function() {
      var that = this;
      wx.showActionSheet({
        itemList: this.data.sexArray,
        success: function(res) {
          console.log(res.tapIndex)
          that.setData({
            sexDefault: that.data.sexArray[res.tapIndex]
          })
        },
        fail: function(res) {
          console.log(res.errMsg)
        }
      })
    },
    groupButton: function() {
      var that = this;
      wx.showActionSheet({
        itemList: this.data.groupArray,
        success: function(res) {
          console.log(res.tapIndex)
          that.setData({
            groupDefault: that.data.groupArray[res.tapIndex]
          })
        },
        fail: function(res) {
          console.log(res.errMsg)
        }
      })
    },
    _showOrCloseDialog: function(currentStatu) {
      var that = this;
      /* 动画部分 */
      // 第1步:创建动画实例 
      var animation = wx.createAnimation({
        duration: 200, //动画时长
        timingFunction: "linear", //线性
        delay: 0 //0则不延迟
      });

      // 第2步:这个动画实例赋给当前的动画实例
      this.animation = animation;

      // 第3步:执行第一组动画
      animation.opacity(0).rotateX(-100).step();

      // 第4步:导出动画对象赋给数据对象储存
      that.setData({
        animationData: animation.export()
      })

      // 第5步:设置定时器到指定时候后,执行第二组动画
      setTimeout(function() {
        // 执行第二组动画
        animation.opacity(1).rotateX(0).step();
        // 给数据对象储存的第一组动画,更替为执行完第二组动画的动画对象
        that.setData({
          animationData: animation
        })

        //关闭
        if (currentStatu == "close") {
          that.setData({
            isShow: false
          });
        }
      }.bind(this), 200)

      // 显示
      if (currentStatu == "open") {
        that.setData({
          isShow: true
        });
      }
    }
  },
  //解决滚动穿透问题
  myCatchTouch: function () {
    return
  }
})

#看這裡可能有些小夥伴就問了,你個水貨,怎麼js檔案結構怎麼跟我的不一樣,是不是來忽悠我們的?客官別急麼,請聽我娓娓道來:其實這裡為了方便調用,我把這個dialog封裝成了一個組件了。你問我怎麼封裝組件?請移步官方教學:

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/

封裝完成之後專案架構如下:

詳解一個自訂的微信小程式組件(modal彈跳窗組件)

這裡誤會就解釋清楚了,麻煩給個面子繼續往下看。 。

已經展示了三大金剛了,還有一個dialog.json文件未展示,這個文件很簡單

{
  "component": true,//作为组件
  "usingComponents": {}//引用别的组件
}

這個文件也和一般json文件有差異,主要是配置了作為組件讓別人引用的,所以到這個,這個組件已經封裝完成了

可能這個時候很多童鞋迫不及待的複制粘貼然後把代碼放入項目中想一睹真容,發現運行結果跟效果圖不一樣,然後有一部分人可能又要說:娘希匹,果然是個水貨,騙人的! ! !到這裡,我只能說:各位鄉親們,蛋定、蛋定。 。 。 ,因為到js中的dataObject和bean沒有麼,所以效果圖跟我在文章開始展示的不一樣。 so,下面就告訴大家,怎麼調用,並且實現和我一樣的效果。

在引用的xml中加入以下程式碼

<image src="../../img/add.png" class="buttom" bindtap="bindAdd"></image>

<dialog id=&#39;dialog&#39; title=&#39;新增&#39; bind:confirmEvent="_confirmEvent"></dialog>

buttom這個是個懸浮按鈕,wxss也給你

.buttom{
  width: 100rpx;
  height: 100rpx;
  display: flex;
  flex-direction: row;
  position: fixed;
  bottom:60rpx;
  right: 60rpx;
}

然後引用頁面的js檔案中

onReady: function() {
    //获得dialog组件
    this.dialog = this.selectComponent("#dialog");
}



//响应button弹框
bindAdd: function(e) {
    this.dialog.setDataObj(addObject, {})
    this.dialog.showDialog();
}

到這裡基本上點擊懸浮按鈕就可以實現彈框了。有的大胸部dei又要說了:哎哎哎,等等,addObject,和那個add.png還沒給了。好吧,給給給,都給你們

const addObject = [{
  id: "name",
  must: true,
  placeholder: "姓名",
  type: "input",
  event: "nameInput"
},
{
  id: "sex",
  must: true,
  placeholder: "男",
  type: "button",
  event: "sexButton"
},
{
  id: "group",
  must: true,
  placeholder: "组织",
  type: "button",
  event: "groupButton"
},
{
  id: "phone",
  must: true,
  placeholder: "电话号码",
  type: "input",
  event: "phoneInput"
},
{
  id: "shortNum",
  must: false,
  placeholder: "集团短号",
  type: "input",
  event: "shortNumInput"
},
{
  id: "mail",
  must: false,
  placeholder: "电子邮箱",
  type: "input",
  event: "mailInput"
},
{
  id: "unit",
  must: false,
  placeholder: "单位名称",
  type: "input",
  event: "unitInput"
},
{
  id: "department",
  must: false,
  placeholder: "部门名称",
  type: "input",
  event: "departmentInput"
},
{
  id: "job",
  must: false,
  placeholder: "职务",
  type: "input",
  event: "jobInput"
},
{
  id: "function",
  must: false,
  placeholder: "涉及工作内容",
  type: "input",
  event: "functionInput"
},
{
  id: "comPhone",
  must: false,
  placeholder: "办公电话",
  type: "input",
  event: "comPhoneInput"
},
{
  id: "fax",
  must: false,
  placeholder: "传真",
  type: "input",
  event: "faxInput"
},
{
  id: "homePhone",
  must: false,
  placeholder: "家庭电话",
  type: "input",
  event: "homePhoneInput"
},
{
  id: "showOrder",
  must: false,
  placeholder: "显示顺序",
  type: "input",
  event: "showOrderInput"
},
{
  id: "departOrder",
  must: false,
  placeholder: "部门顺序",
  type: "input",
  event: "departOrderInput"
},
{
  id: "remark",
  must: false,
  placeholder: "备注",
  type: "input",
  event: "remarkInput"
}
]

圖片

詳解一個自訂的微信小程式組件(modal彈跳窗組件)

# 到這裡應該可實現跟我一樣的效果了吧,盡情去折騰吧。

相關文章:

微信小程式自訂模態彈窗實例詳解

微信小程式 - 自定義創建

相關影片:

#微信小程式開發從入門到精通影片教學

#

以上是詳解一個自訂的微信小程式組件(modal彈跳窗組件)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn