mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
[improvement] Dialog: 优化弹窗组件对 open 信息的处理 (#366)
* dialog 支持 open-type 的按钮,并增加获取 open 数据的方式 * 增加 dialog 调用 open数据的文档说明 * 增加 dialog close 方法 * 增加文档
This commit is contained in:
parent
cf9cfdb44b
commit
87bf9c9ea7
@ -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'),
|
||||
|
@ -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'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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
10304
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
@ -18,6 +18,7 @@
|
||||
bindgetuserinfo="bindgetuserinfo"
|
||||
bindgetphonenumber="bindgetphonenumber"
|
||||
binderror="binderror"
|
||||
bindopensetting="bindopensetting"
|
||||
>
|
||||
<slot></slot>
|
||||
</button>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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'
|
||||
}]
|
||||
```
|
||||
|
||||
|
@ -18,5 +18,7 @@ module.exports = {
|
||||
// 取消按钮文案
|
||||
cancelButtonText: '取消',
|
||||
// 取消按钮颜色
|
||||
cancelButtonColor: '#333'
|
||||
cancelButtonColor: '#333',
|
||||
// 点击按钮自动关闭 dialog
|
||||
autoClose: true
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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' }}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user