feat(ShareSheet): support multil line

This commit is contained in:
chenjiahan 2020-04-08 21:32:41 +08:00 committed by neverland
parent 68164e64cf
commit 1e2325c006
6 changed files with 163 additions and 12 deletions

View File

@ -13,6 +13,79 @@ Vue.use(ShareSheet);
### Basic Usage ### Basic Usage
```html
<van-cell @click="showShare = true" />
<van-share-sheet
v-model="showShare"
:options="options"
@select="onSelect"
/>
```
```js
import { Toast } from 'vant';
export default {
data() {
return {
showShare: false,
options: [
{ name: 'Wechat', icon: 'wechat' },
{ name: 'Weibo', icon: 'weibo' },
{ name: 'Link', icon: 'link' },
{ name: 'Poster', icon: 'poster' },
{ name: 'Qrcode', icon: 'qrcode' },
],
};
},
methods: {
onSelect(option) {
Toast(option.name);
this.showShare = false;
},
}
};
```
### Show Title
```html
<van-share-sheet
v-model="showShare"
title="Share with friends"
:options="options"
description="Description"
/>
```
### Multi Line
```html
<van-share-sheet v-model="showShare" :options="options" />
```
```js
export default {
data() {
return {
showShare: false,
options: [
[
{ name: 'Wechat', icon: 'wechat' },
{ name: 'Weibo', icon: 'weibo' },
{ name: 'QQ', icon: 'qq' },
],
[
{ name: 'Link', icon: 'link' },
{ name: 'Poster', icon: 'poster' },
{ name: 'Qrcode', icon: 'qrcode' },
],
],
};
},
};
```
## API ## API
### Props ### Props
@ -29,7 +102,7 @@ Vue.use(ShareSheet);
| Key | Description | Type | | Key | Description | Type |
|------|------|------| |------|------|------|
| name | Option name | *string* | | name | Option name | *string* |
| icon | Option iconcan be set to `wechat` `link` `qrcode` `poster` or image URL | *string* | | icon | Option iconcan be set to `wechat` `weibo` `qq` `link` `qrcode` `poster` or image URL | *string* |
### Events ### Events

View File

@ -37,6 +37,7 @@ export default {
showShare: false, showShare: false,
options: [ options: [
{ name: '微信', icon: 'wechat' }, { name: '微信', icon: 'wechat' },
{ name: '微博', icon: 'weibo' },
{ name: '复制链接', icon: 'link' }, { name: '复制链接', icon: 'link' },
{ name: '分享海报', icon: 'poster' }, { name: '分享海报', icon: 'poster' },
{ name: '二维码', icon: 'qrcode' }, { name: '二维码', icon: 'qrcode' },
@ -52,6 +53,49 @@ export default {
}; };
``` ```
### 展示面板标题
通过`title`属性可以设置面板标题,通过`description`属性可以设置标题下方的描述文字
```html
<van-share-sheet
v-model="showShare"
title="立即分享给好友"
:options="options"
description="描述信息"
/>
```
### 展示多行选项
当分享选项的数量较多时,可以将`options`定义为数组嵌套的格式,每个子数组代表一行选项
```html
<van-share-sheet v-model="showShare" :options="options" />
```
```js
export default {
data() {
return {
showShare: false,
options: [
[
{ name: '微信', icon: 'wechat' },
{ name: '微博', icon: 'weibo' },
{ name: 'QQ', icon: 'qq' },
],
[
{ name: '复制链接', icon: 'link' },
{ name: '分享海报', icon: 'poster' },
{ name: '二维码', icon: 'qrcode' },
],
],
};
},
};
```
## API ## API
### Props ### Props
@ -70,7 +114,7 @@ export default {
| 键名 | 说明 | 类型 | | 键名 | 说明 | 类型 |
|------|------|------| |------|------|------|
| name | 分享渠道名称 | *string* | | name | 分享渠道名称 | *string* |
| icon | 图标,可选值为 `wechat` `link` `qrcode` `poster`,支持传入图片 URL | *string* | | icon | 图标,可选值为 `wechat` `weibo` `qq` `link` `qrcode` `poster`,支持传入图片 URL | *string* |
### Events ### Events

View File

@ -47,25 +47,29 @@
export default { export default {
i18n: { i18n: {
'zh-CN': { 'zh-CN': {
qq: 'QQ',
link: '复制链接', link: '复制链接',
title: '立即分享给好友', title: '立即分享给好友',
weibo: '微博',
wechat: '微信', wechat: '微信',
poster: '分享海报', poster: '分享海报',
qrcode: '二维码', qrcode: '二维码',
multiLine: '多行展示', multiLine: '展示多行选项',
showSheet: '显示分享面板', showSheet: '显示分享面板',
withTitle: '展示带标题的面板', withTitle: '展示面板标题',
description: '描述信息', description: '描述信息',
}, },
'en-US': { 'en-US': {
qq: 'QQ',
link: 'Link', link: 'Link',
title: 'Share with friends', title: 'Share with friends',
weibo: 'Weibo',
wechat: 'Wechat', wechat: 'Wechat',
poster: 'Poster', poster: 'Poster',
qrcode: 'Qrcode', qrcode: 'Qrcode',
multiLine: 'Multi Line', multiLine: 'Multi Line',
showSheet: 'Show ShareSheet', showSheet: 'Show ShareSheet',
withTitle: 'Show ShareSheet with title', withTitle: 'Show Title',
description: 'Description', description: 'Description',
}, },
}, },
@ -81,13 +85,18 @@ export default {
created() { created() {
this.options = [ this.options = [
{ name: this.t('wechat'), icon: 'wechat' }, { name: this.t('wechat'), icon: 'wechat' },
{ name: this.t('weibo'), icon: 'weibo' },
{ name: this.t('link'), icon: 'link' }, { name: this.t('link'), icon: 'link' },
{ name: this.t('poster'), icon: 'poster' }, { name: this.t('poster'), icon: 'poster' },
{ name: this.t('qrcode'), icon: 'qrcode' }, { name: this.t('qrcode'), icon: 'qrcode' },
]; ];
this.multiLineOptions = [ this.multiLineOptions = [
[{ name: this.t('wechat'), icon: 'wechat' }], [
{ name: this.t('wechat'), icon: 'wechat' },
{ name: this.t('weibo'), icon: 'weibo' },
{ name: this.t('qq'), icon: 'qq' },
],
[ [
{ name: this.t('link'), icon: 'link' }, { name: this.t('link'), icon: 'link' },
{ name: this.t('poster'), icon: 'poster' }, { name: this.t('poster'), icon: 'poster' },

View File

@ -7,7 +7,7 @@ import { popupMixinProps } from '../mixins/popup';
// Components // Components
import Popup from '../popup'; import Popup from '../popup';
const PRESET_ICONS = ['wechat', 'link', 'qrcode', 'poster']; const PRESET_ICONS = ['qq', 'weibo', 'wechat', 'link', 'qrcode', 'poster'];
const [createComponent, bem, t] = createNamespace('share-sheet'); const [createComponent, bem, t] = createNamespace('share-sheet');
@ -30,6 +30,7 @@ export default createComponent({
methods: { methods: {
onCancel() { onCancel() {
this.toggle(false); this.toggle(false);
this.$emit('cancel');
}, },
onSelect(option, index) { onSelect(option, index) {
@ -42,7 +43,7 @@ export default createComponent({
getIconURL(icon) { getIconURL(icon) {
if (PRESET_ICONS.indexOf(icon) !== -1) { if (PRESET_ICONS.indexOf(icon) !== -1) {
return `https://img.yzcdn.cn/vant/share-icon-${icon}.svg`; return `https://img.yzcdn.cn/vant/share-icon-${icon}.png`;
} }
return icon; return icon;
@ -64,10 +65,10 @@ export default createComponent({
); );
}, },
genOptions() { genOptions(options, showBorder) {
return ( return (
<div class={bem('options')}> <div class={bem('options', { border: showBorder })}>
{this.options.map((option, index) => ( {options.map((option, index) => (
<div <div
class={bem('option')} class={bem('option')}
onClick={() => { onClick={() => {
@ -82,6 +83,14 @@ export default createComponent({
); );
}, },
genRows() {
const { options } = this;
if (Array.isArray(options[0])) {
return options.map((item, index) => this.genOptions(item, index !== 0));
}
return this.genOptions(options);
},
genCancelText() { genCancelText() {
const cancelText = isDef(this.cancelText) ? this.cancelText : t('cancel'); const cancelText = isDef(this.cancelText) ? this.cancelText : t('cancel');
@ -106,7 +115,7 @@ export default createComponent({
onInput={this.toggle} onInput={this.toggle}
> >
{this.genHeader()} {this.genHeader()}
{this.genOptions()} {this.genRows()}
{this.genCancelText()} {this.genCancelText()}
</Popup> </Popup>
); );

View File

@ -1,4 +1,5 @@
@import '../style/var'; @import '../style/var';
@import '../style/mixins/hairline';
.van-share-sheet { .van-share-sheet {
&__header { &__header {
@ -23,11 +24,16 @@
} }
&__options { &__options {
position: relative;
display: flex; display: flex;
padding: @padding-md 0 @padding-md @padding-lg; padding: @padding-md 0 @padding-md @padding-lg;
overflow-x: auto; overflow-x: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
&--border::before {
.hairline-top(@cell-border-color, @padding-md);
}
// fix right-padding issue for overflow-x element // fix right-padding issue for overflow-x element
// see: https://stackoverflow.com/questions/10054870 // see: https://stackoverflow.com/questions/10054870
&::after { &::after {

View File

@ -18,6 +18,16 @@
transform: scale(0.5); transform: scale(0.5);
} }
.hairline-top(@color: @border-color, @left: 0) {
.hairline-common();
top: 0;
right: 0;
left: @left;
border-top: 1px solid @color;
transform: scaleY(0.5);
}
.hairline-bottom(@color: @border-color, @left: 0) { .hairline-bottom(@color: @border-color, @left: 0) {
.hairline-common(); .hairline-common();