├── effect.png
├── README.md
└── components
└── modal-view
├── modal-view.wxml
├── modal-view.wxss
└── modal-view.js
/effect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iRobin520/WeApp-ModalView/HEAD/effect.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WeApp-ModalView
2 | 微信小程序自定义模态弹窗,完全根据传入的数据值动态生成各种类型的组件, 无需修改任何模版或样式的的代码,只需添加相应的js字段即可。
3 |
4 | 先上效果图:
5 | 
6 |
7 | 示列代码:
8 | 在wxml文件中加入代码:
9 | < import src="../../../../components/modal-view/modal-view.wxml" / >
10 | < template is="modalView" data="{{ ...__modalView__ }}" / >
11 |
12 | 在js文件中加入代码:
13 | import { ModalView } from '../../../../components/modal-view/modal-view'
14 |
15 | 在onLoad事件中加入:
16 | new ModalView
17 |
18 | 在你自己定义的事件中加入:
19 | this.modalView.showModal({
20 | title: '申请退货',
21 | confirmation: true,
22 | confirmationText: '确定要申请退货吗?',
23 | inputFields: [{
24 | fieldName: 'reason',
25 | fieldType: 'Picker',
26 | fieldPlaceHolder: '选择退货原因',
27 | fieldDatasource: reasons,
28 | isRequired: true,
29 | },
30 | {
31 | fieldName: 'test',
32 | fieldType: 'Text',
33 | fieldPlaceHolder: '请填写测试信息',
34 | isRequired: false,
35 | },
36 | {
37 | fieldName: 'descriptions',
38 | fieldType: 'Textarea',
39 | fieldPlaceHolder: '请填写退货描述',
40 | isRequired: false,
41 | }],
42 | confirm: function (res) {
43 | console.log(res)
44 | //用户按确定按钮以后会回到这里,并且对输入的表单数据会带回
45 | }
46 | })
47 |
--------------------------------------------------------------------------------
/components/modal-view/modal-view.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{title}}
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{formData[i]?formData[i]:item.fieldPlaceHolder}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
31 |
32 |
--------------------------------------------------------------------------------
/components/modal-view/modal-view.wxss:
--------------------------------------------------------------------------------
1 | .show-btn {
2 | margin-top: 100rpx;
3 | color: #22cc22;
4 | }
5 | .modal-mask {
6 | width: 100%;
7 | height: 100%;
8 | position: fixed;
9 | top: 0;
10 | left: 0;
11 | background: #000;
12 | opacity: 0.5;
13 | overflow: hidden;
14 | z-index: 9000;
15 | color: #fff;
16 | }
17 | .modal-dialog {
18 | width: 540rpx;
19 | overflow: hidden;
20 | position: fixed;
21 | top: 40%;
22 | left: 0;
23 | z-index: 9999;
24 | background: #f9f9f9;
25 | margin: -180rpx 105rpx;
26 | border-radius: 20rpx;
27 | }
28 | .modal-title {
29 | padding-top: 20rpx;
30 | font-size: 36rpx;
31 | color: #030303;
32 | text-align: center;
33 | }
34 | .modal-content {
35 | padding: 20rpx 32rpx 40rpx 32rpx;
36 | }
37 | .modal-input,.modal-input_solo,.modal-input_hd,.modal-input_bd,.modal-input_ft {
38 | display: flex;
39 | background: #fff;
40 | font-size: 28rpx;
41 | }
42 | .modal-input_solo {
43 | border: 2rpx solid #ddd;
44 | }
45 | .modal-input_hd{
46 | border-top: 2rpx solid #ddd;
47 | border-left: 2rpx solid #ddd;
48 | border-right: 2rpx solid #ddd;
49 | padding-left: 24rpx;
50 | }
51 | .modal-input_bd {
52 | padding-left: 24rpx;
53 | border-left: 2rpx solid #ddd;
54 | border-right: 2rpx solid #ddd;
55 | }
56 | .modal-input_ft {
57 | padding-left: 24rpx;
58 | border-left: 2rpx solid #ddd;
59 | border-right: 2rpx solid #ddd;
60 | border-bottom: 2rpx solid #ddd;
61 | }
62 | .input,.input_solo,.input_hd,.input_bd,.input_texarea {
63 | width: 100%;
64 | height: 70rpx;
65 | line-height: 70rpx;
66 | font-size: 28rpx;
67 | padding: 0 20rpx;
68 | box-sizing: border-box;
69 | color: #333;
70 | }
71 | .input_bd {
72 | border-top: 2rpx solid #ddd;
73 | }
74 | .input_texarea {
75 | height: 220rpx;
76 | line-height: 34rpx;
77 | padding: 10rpx 8rpx;
78 | border-top: 2rpx solid #ddd;
79 | }
80 | .input-holder {
81 | color: #666;
82 | font-size: 28rpx;
83 | }
84 | .input-content {
85 | color: #333;
86 | font-size: 28rpx;
87 | }
88 | .modal-footer {
89 | display: flex;
90 | flex-direction: row;
91 | height: 86rpx;
92 | border-top: 1px solid #dedede;
93 | font-size: 34rpx;
94 | line-height: 86rpx;
95 | }
96 | .btn-cancel {
97 | width: 50%;
98 | color: #000000;
99 | text-align: center;
100 | border-right: 1px solid #dedede;
101 | }
102 | .btn-confirm {
103 | width: 50%;
104 | color: #3cc51f;
105 | text-align: center;
106 | }
--------------------------------------------------------------------------------
/components/modal-view/modal-view.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ModalView by Robin Shen
3 | * WeApp ModalView add-ons
4 | * 微信小程序 ModalView 增强插件
5 | * Created at 2017-08-23
6 | * Github: https://github.com/iRobin520/WeApp-ModalView.git
7 | * LICENSE: MIT
8 | */
9 |
10 | function ModalViewClass() {
11 | //数据
12 | let _componentData = {
13 | '__modalView__.title': null,
14 | '__modalView__.inputFields': null,
15 | '__modalView__.confirm': null,
16 | '__modalView__.formData': null,
17 | '__modalView__.confirmation': false,
18 | '__modalView__.confirmationText': null,
19 | }
20 | //事件
21 | let _componentEvent = {
22 | //文本输入
23 | __modalView__onTextBlur: function (e) {
24 | var filedIndex = e.currentTarget.dataset.field_index
25 | var formData = this.data.__modalView__.formData
26 | formData[filedIndex] = e.detail.value
27 | this.setData({
28 | '__modalView__.formData': formData,
29 | })
30 | },
31 | //单选列表数据变更
32 | __modalView__onPickerChange: function (e) {
33 | var filedIndex = e.currentTarget.dataset.field_index
34 | let inputField = this.data.__modalView__.inputFields[filedIndex]
35 | var datasource = inputField.fieldDatasource
36 | var selectedIndex = parseInt(e.detail.value)
37 | var selectedPickerValue = datasource[selectedIndex]
38 | var formData = this.data.__modalView__.formData
39 | formData[filedIndex] = selectedPickerValue
40 | this.setData({'__modalView__.formData': formData})
41 | },
42 | //确定
43 | __modalView__onConfirm: function (e) {
44 | let page = this
45 | var formData = this.data.__modalView__.formData
46 | var errorMessage = null
47 | console.log(this.data.__modalView__.inputFields)
48 | for (var i = 0; i < this.data.__modalView__.inputFields.length; i++) {
49 | var field = this.data.__modalView__.inputFields[i]
50 | var value = formData[i]
51 | if (field.isRequired && !value) {
52 | errorMessage = field.fieldPlaceHolder
53 | break
54 | }
55 | }
56 | if (errorMessage) {
57 | page.setData({
58 | '__modalView__.reveal': false
59 | })
60 | wx.showModal({
61 | title: '',
62 | content: errorMessage,
63 | showCancel: false,
64 | success: function (res) {
65 | if (res.confirm) {
66 | page.setData({
67 | '__modalView__.reveal': true
68 | })
69 | }
70 | }
71 | })
72 | return
73 | }
74 | if (this.data.__modalView__.confirmation) {
75 | page.setData({
76 | '__modalView__.reveal': false
77 | })
78 | wx.showModal({
79 | title: '',
80 | content: this.data.__modalView__.confirmationText,
81 | success: function (res) {
82 | if (res.confirm) {
83 | page.__modalView__onHideModal()
84 | typeof page.data.__modalView__.confirm === 'function' && page.data.__modalView__.confirm(formData)
85 | } else {
86 | page.setData({
87 | '__modalView__.reveal': true
88 | })
89 | }
90 | }
91 | })
92 | } else {
93 | page.__modalView__onHideModal()
94 | typeof page.data.__modalView__.confirm === 'function' && page.data.__modalView__.confirm(formData)
95 | }
96 | },
97 | //取消
98 | __modalView__onCancel: function (e) {
99 | this.__modalView__onHideModal()
100 | },
101 | //弹出框蒙层截断touchmove事件
102 | __modalView__onPreventTouchMove: function (e) {
103 |
104 | },
105 | //隐藏
106 | __modalView__onHideModal: function () {
107 | let page = this
108 | let animation = wx.createAnimation()
109 | animation.opacity(0).step()
110 | page.setData({
111 | '__modalView__.reveal': false
112 | })
113 | }
114 | }
115 | //构造函数
116 | function ModalView() {
117 | let pages = getCurrentPages()
118 | let curPage = pages[pages.length - 1]
119 | this.__page = curPage
120 | // 把组件的事件“合并到”页面对象上
121 | Object.assign(curPage, _componentEvent)
122 | curPage.setData(_componentData)
123 | curPage.modalView = this
124 | return this
125 | }
126 | //显示
127 | ModalView.prototype.showModal = function (data) {
128 | let page = this.__page
129 | let animation = wx.createAnimation()
130 | animation.opacity(1).step()
131 | if (data) {
132 | page.setData({
133 | '__modalView__.title': data.title,
134 | '__modalView__.inputFields': data.inputFields,
135 | '__modalView__.confirm': data.confirm,
136 | '__modalView__.formData': new Array(data.inputFields.length),
137 | '__modalView__.confirmation': data.confirmation ? data.confirmation: false,
138 | '__modalView__.confirmationText': data.confirmationText ? data.confirmationText : null,
139 | })
140 | }
141 | page.setData({
142 | '__modalView__.reveal': true
143 | })
144 | }
145 | return new ModalView()
146 | }
147 |
148 | module.exports = {
149 | ModalView: ModalViewClass
150 | }
--------------------------------------------------------------------------------