[improvement] Dialog: 优化弹窗组件对 open 信息的处理 (#366)

* dialog 支持 open-type 的按钮,并增加获取 open 数据的方式

* 增加 dialog 调用 open数据的文档说明

* 增加 dialog close 方法

* 增加文档
This commit is contained in:
Yao 2018-07-15 17:37:10 +08:00 committed by GitHub
parent cf9cfdb44b
commit 87bf9c9ea7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1538 additions and 9026 deletions

View File

@ -55,6 +55,7 @@ module.exports = {
label: '表单',
include: {
checkbox: require('./packages/checkbox/README.md'),
datetime_picker: require('./packages/datetime-picker/README.md'),
field: require('./packages/field/README.md'),
radio: require('./packages/radio/README.md'),
search: require('./packages/search/README.md'),
@ -79,7 +80,6 @@ module.exports = {
label: '交互',
include: {
actionsheet: require('./packages/actionsheet/README.md'),
datetime_picker: require('./packages/datetime-picker/README.md'),
dialog: require('./packages/dialog/README.md'),
popup: require('./packages/popup/README.md'),
tab: require('./packages/tab/README.md'),

View File

@ -38,21 +38,9 @@ export default {
}, {
name: 'Popup 弹出层',
path: '/pages/popup/index'
}, {
name: 'Select 选择',
path: '/pages/select/index'
}, {
name: 'Stepper 计数器',
path: '/pages/stepper/index'
}, {
name: 'Steps 步骤条',
path: '/pages/steps/index'
}, {
name: 'Switch 开关',
path: '/pages/switch/index'
}, {
name: 'Search 搜索',
path: '/pages/search/index'
}, {
name: 'Tab 标签',
path: '/pages/tab/index'
@ -71,19 +59,28 @@ export default {
{
name: 'Checkbox 复选框',
path: '/pages/checkbox/index'
},
{
}, {
name: 'Datetime 时间选择器',
path: '/pages/datetime/index'
},
{
}, {
name: 'Field 输入框',
path: '/pages/field/index'
},
{
}, {
name: 'Radio 单选框',
path: '/pages/radio/index'
},
}, {
name: 'Search 搜索',
path: '/pages/search/index'
}, {
name: 'Select 选择',
path: '/pages/select/index'
}, {
name: 'Stepper 计数器',
path: '/pages/stepper/index'
}, {
name: 'Switch 开关',
path: '/pages/switch/index'
}
]
},
action: {
@ -101,9 +98,6 @@ export default {
}, {
name: 'TopTips 顶部提示',
path: '/pages/toptips/index'
}, {
name: 'Datetime 时间选择器',
path: '/pages/datetime/index'
}
]
}

View File

@ -1,4 +1,5 @@
const Dialog = require('../../dist/dialog/dialog');
const Toast = require('../../dist/toast/toast');
Page({
toggleBaseDialog() {
@ -76,6 +77,60 @@ Page({
});
},
toggleOpenDialog() {
Dialog({
title: '弹窗',
message: '获取用户数据',
selector: '#zan-open-dialog',
buttons: [{
text: '用户信息',
type: 'userInfo',
openType: 'getUserInfo'
}, {
text: '获取手机号',
type: 'tel',
openType: 'getPhoneNumber'
}, {
text: '打开授权页',
type: 'setting',
openType: 'openSetting'
}]
}).then(({ type, hasOpenDataPromise, openDataPromise }) => {
console.log(type);
// 如果没有 open 数据返回,就不处理
if (!hasOpenDataPromise) {
return;
}
openDataPromise.then((data) => {
console.log('成功获取信息', data);
}).catch((data) => {
console.log('获取信息失败', data);
});
});
},
toggleCloseDialog() {
Dialog({
title: '弹窗',
message: '这是一个自由控制关闭的弹窗',
selector: '#zan-close-dialog',
autoClose: false
}).then(() => {
console.log('=== dialog resolve ===', 'type: confirm');
Toast.loading({
selector: '#zan-toast'
});
// 2s 后自动关闭弹窗
setTimeout(() => {
Dialog.close({ selector: '#zan-close-dialog' });
Toast.clear();
}, 2000);
});
},
onShareAppMessage() {
return {
title: 'ZanUI-WeApp',

View File

@ -4,6 +4,7 @@
"doc-page": "../../components/doc-page/index",
"zan-dialog": "../../dist/dialog/index",
"zan-button": "../../dist/btn/index",
"zan-button-group": "../../dist/btn-group/index"
"zan-button-group": "../../dist/btn-group/index",
"zan-toast": "../../dist/toast/index"
}
}

View File

@ -4,10 +4,16 @@
<zan-button bindtap="toggleWithoutTitleDialog">Dialog - 无标题</zan-button>
<zan-button bindtap="toggleButtonDialog">Dialog - 自定义显示按钮</zan-button>
<zan-button bindtap="toggleVerticalDialog">Dialog - 按钮纵向排布</zan-button>
<zan-button bindtap="toggleOpenDialog">Dialog - 获取 Open 数据的弹窗</zan-button>
<zan-button bindtap="toggleCloseDialog">Dialog - 控制弹窗关闭</zan-button>
</zan-button-group>
<zan-dialog id="zan-base-dialog"></zan-dialog>
<zan-dialog id="zan-no-title-dialog"></zan-dialog>
<zan-dialog id="zan-button-dialog"></zan-dialog>
<zan-dialog id="zan-vertical-dialog"></zan-dialog>
<zan-dialog id="zan-open-dialog"></zan-dialog>
<zan-dialog id="zan-close-dialog"></zan-dialog>
<zan-toast id="zan-toast"></zan-toast>
</doc-page>

10304
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,12 @@
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"cross-env": "^5.1.4",
"eslint": "^5.1.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.10.0",
"eslint-plugin-vue": "^4.7.0",
"fs-extra": "^4.0.2",
"gh-pages": "^1.1.0",
"gulp": "^3.9.1",

View File

@ -18,6 +18,7 @@
bindgetuserinfo="bindgetuserinfo"
bindgetphonenumber="bindgetphonenumber"
binderror="binderror"
bindopensetting="bindopensetting"
>
<slot></slot>
</button>

View File

@ -42,6 +42,9 @@ module.exports = Behavior({
bindgetphonenumber({ detail = {} } = {}) {
this.triggerEvent('getphonenumber', detail);
},
bindopensetting({ detail = {}} = {}) {
this.triggerEvent('opensetting', detail);
},
binderror({ detail = {} } = {}) {
this.triggerEvent('error', detail);
}

View File

@ -64,18 +64,39 @@ Dialog({
text: '取消',
type: 'cancel'
}]
}).then(({ type }) => {
}).then(({ type, hasOpenDataPromise, openDataPromise }) => {
// type 可以用于判断具体是哪一个按钮被点击
console.log('=== dialog with custom buttons ===', `type: ${type}`);
// - 在使用自定义按钮的情况下,可以将按钮的 openType 设置为微信原生按钮支持的 open-type
// - 如果设置的 openType 为 'getUserInfo', 'getPhoneNumber', 'openSetting' 其中之一
// 就认为是需要返回相应的数据
// 为了处理方便,增加 flag 值 hasOpenDataPromise表示是否有微信开放数据返回
// 这时,通过利用 openDataPromise可以获取开放数据返回的具体信息
if (hasOpenDataPromise) {
openDataPromise.then((data) => {
console.log('成功获取信息', data);
}).catch((data) => {
console.log('获取信息失败', data);
});
}
});
```
#### 方法
| 方法名 | 参数 | 返回值 | 介绍 |
|-----------|-----------|-----------|-------------|
| Dialog | `options` 弹窗展示参数,具体见下方具体参数, `pageCtx` 页面上下文,可以不传,默认使用当前页面 | - | 展示弹窗 |
| Dialog.close | `options` 和弹窗展示参数一致,这里只需要 selector | - | 关闭弹窗 |
### 具体参数
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| message | 弹窗内容 | String | - | 必须 |
| selector | 显示弹窗对应组件节点的选择器 | String | - | 必须 |
| title | 弹窗标题 | String | - | |
| autoClose | 点击按钮后是否自动关闭弹窗 | Boolean | true | |
| buttonsShowVertical | 按钮是否纵向展示 | Boolean | false | |
| showConfirmButton | 是否展示确认按钮 | Boolean | true | |
| confirmButtonText | 确认按钮文案 | String | 确定 | |
@ -106,6 +127,12 @@ buttons 数据格式
text: '取消',
// 按钮类型,用于在 then 中接受点击事件时,判断是哪一个按钮被点击
type: 'cancel'
}, {
text: '获取用户信息',
type: 'userInfo',
// 利用 OpenType 设置微信按钮的开放能力
// 设置对应的值以后,这个按钮就会具有调用微信原生按钮支持的开放能力
openType: 'getUserInfo'
}]
```

View File

@ -18,5 +18,7 @@ module.exports = {
// 取消按钮文案
cancelButtonText: '取消',
// 取消按钮颜色
cancelButtonColor: '#333'
cancelButtonColor: '#333',
// 点击按钮自动关闭 dialog
autoClose: true
};

View File

@ -1,22 +1,33 @@
const defaultData = require('./data');
// options 使用参数
// pageCtx 页面 page 上下文
function Dialog(options, pageCtx) {
const parsedOptions = {
function getDialogCtx({ selector, pageCtx }) {
let ctx = pageCtx;
if (!ctx) {
const pages = getCurrentPages();
ctx = pages[pages.length - 1];
}
return ctx.selectComponent(selector);
}
function getParsedOptions(options = {}) {
return {
// 自定义 btn 列表
// { type: 按钮类型回调时以此作为区分依据text: 按钮文案, color: 按钮文字颜色 }
buttons: [],
...defaultData,
...options
};
}
let ctx = pageCtx;
if (!ctx) {
const pages = getCurrentPages();
ctx = pages[pages.length - 1];
}
const dialogCtx = ctx.selectComponent(parsedOptions.selector);
// options 使用参数
// pageCtx 页面 page 上下文
function Dialog(options, pageCtx) {
const parsedOptions = getParsedOptions(options);
const dialogCtx = getDialogCtx({
selector: parsedOptions.selector,
pageCtx
});
if (!dialogCtx) {
console.error('无法找到对应的dialog组件请于页面中注册并在 wxml 中声明 dialog 自定义组件');
@ -59,9 +70,29 @@ function Dialog(options, pageCtx) {
showCustomBtns,
key: `${(new Date()).getTime()}`,
show: true,
promiseFunc: { resolve, reject }
promiseFunc: { resolve, reject },
openTypePromiseFunc: null
});
});
}
Dialog.close = function (options, pageCtx) {
const parsedOptions = getParsedOptions(options);
const dialogCtx = getDialogCtx({
selector: parsedOptions.selector,
pageCtx
});
if (!dialogCtx) {
return;
}
dialogCtx.setData({
show: false,
promiseFunc: null,
openTypePromiseFunc: null
});
};
module.exports = Dialog;

View File

@ -1,4 +1,5 @@
const _f = function () {};
const needResponseOpenTypes = ['getUserInfo', 'getPhoneNumber', 'openSetting'];
Component({
properties: {},
@ -7,7 +8,7 @@ Component({
// 标题
title: '',
// 自定义 btn 列表
// { type: 按钮类型回调时以此作为区分依据text: 按钮文案, color: 按钮文字颜色 }
// { type: 按钮类型回调时以此作为区分依据text: 按钮文案, color: 按钮文字颜色, openType: 微信开放能力 }
buttons: [],
// 内容
message: ' ',
@ -28,9 +29,11 @@ Component({
// 取消按钮颜色
cancelButtonColor: '#333',
key: '',
autoClose: true,
show: false,
showCustomBtns: false,
promiseFunc: {}
promiseFunc: {},
openTypePromiseFunc: {}
},
methods: {
@ -42,15 +45,22 @@ Component({
const { resolve = _f, reject = _f } = this.data.promiseFunc || {};
// 重置展示
this.setData({
show: false
});
if (this.data.autoClose) {
this.setData({ show: false });
}
// 自定义按钮,全部 resolve 形式返回,根据 type 区分点击按钮
if (this.data.showCustomBtns) {
resolve({
type: dataset.type
});
const isNeedOpenDataButton = needResponseOpenTypes.indexOf(dataset.openType) > -1;
const resolveData = { type: dataset.type };
// 如果需要 openData就额外返回一个 promise用于后续 open 数据返回
if (isNeedOpenDataButton) {
resolveData.openDataPromise = new Promise((resolve, reject) => {
this.setData({ openTypePromiseFunc: { resolve, reject } });
});
resolveData.hasOpenDataPromise = true;
}
resolve(resolveData);
return;
}
@ -64,6 +74,38 @@ Component({
type: 'cancel'
});
}
this.setData({ promiseFunc: {} });
},
// 以下为处理微信按钮开放能力的逻辑
handleUserInfoResponse({ detail }) {
this.__handleOpenDataResponse({
type: detail.errMsg === 'getUserInfo:ok' ? 'resolve' : 'reject',
data: detail
});
},
handlePhoneResponse({ detail }) {
this.__handleOpenDataResponse({
type: detail.errMsg === 'getPhoneNumber:ok' ? 'resolve' : 'reject',
data: detail
});
},
handleOpenSettingResponse({ detail }) {
this.__handleOpenDataResponse({
type: detail.errMsg === 'openSetting:ok' ? 'resolve' : 'reject',
data: detail
});
},
__handleOpenDataResponse({ type = 'resolve', data = {} }) {
const promiseFuncs = this.data.openTypePromiseFunc || {};
const responseFunc = promiseFuncs[type] || _f;
responseFunc(data);
this.setData({ openTypePromiseFunc: null });
}
}
});

View File

@ -23,8 +23,12 @@
class="zan-dialog__button"
custom-class="{{ index === 0 ? 'zan-dialog__button-inside--first' : 'zan-dialog__button-inside' }}"
data-type="{{ item.type }}"
data-open-type="{{ item.openType }}"
open-type="{{ item.openType }}"
bind:btnclick="handleButtonClick"
bind:getuserinfo="handleUserInfoResponse"
bind:getphonenumber="handlePhoneResponse"
bind:opensetting="handleOpenSettingResponse"
>
<view
style="color: {{ item.color || '#333' }}"