breaking change: rename get-container to teleport

This commit is contained in:
chenjiahan 2020-08-21 10:58:02 +08:00
parent 07d1a2590f
commit 52b187692b
39 changed files with 154 additions and 127 deletions

View File

@ -7,13 +7,13 @@
GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**
```html
<!-- Before -->
<!-- Vant 2 -->
<van-goods-action>
<van-goods-action-icon text="图标" />
<van-goods-action-button text="按钮" />
</van-goods-action>
<!-- After -->
<!-- Vant 3 -->
<van-action-bar>
<van-action-bar-icon text="图标" />
<van-action-bar-button text="按钮" />
@ -25,10 +25,10 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
移除 SwitchCell 组件,可以直接使用 Cell 和 Switch 组件代替。
```html
<!-- Before -->
<!-- Vant 2 -->
<van-switch-cell title="标题" v-model="checked" />
<!-- After -->
<!-- Vant 3 -->
<van-cell center title="标题">
<template #right-icon>
<van-switch v-model="checked" size="24" />
@ -38,9 +38,7 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
### 弹窗型组件 v-model 变更
为了适配 Vue 3 的 v-model API 用法变更,所有提供 v-model 属性的组件在用法上有一定调整。
以下弹窗类组件的 `v-model` 被重命名为 `v-model:show`
为了适配 Vue 3 的 v-model API 用法变更,所有提供 v-model 属性的组件在用法上有一定调整。以下弹窗类组件的 `v-model` 被重命名为 `v-model:show`
- ActionSheet
- Calendar
@ -51,9 +49,9 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
- ShareSheet
```html
<!-- before -->
<!-- Vant 2 -->
<van-popup v-model="show" />
<!-- after -->
<!-- Vant 3 -->
<van-popup v-model:show="show" />
```
@ -75,9 +73,9 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
- Uploader
```html
<!-- before -->
<!-- Vant 2 -->
<van-field :value="value" @input="onInput" />
<!-- after -->
<!-- Vant 3 -->
<van-field :model-value="value" @update:model-value="onInput" />
```
@ -90,20 +88,6 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
- TreeSelect: `active-id.sync` 重命名为 `v-model:active-id`
- TreeSelect: `main-active-index.sync` 重命名为 `v-model:main-active-index`
### API 调整
- Area: 移除 change 事件的第一个参数picker 实例)
- Button: 蓝色按钮对应的类型由 `info` 调整为 `primary`
- Button: 绿色按钮对应的类型由 `primary` 调整为 `success`
- Picker: 移除 change 事件的第一个参数picker 实例)
- Picker: 默认开启 show-toolbar 属性
- Picker: 级联选择下confirm/change 事件返回的回调参数将包含为完整的选项对象。
- SwipeCell: `open` 事件的 `detail` 参数重命名为 `name`
- SwipeCell: `on-close` 属性重命名为 `before-close`,并调整参数结构
- Toast: `mask` 属性重命名为 `overlay`
- TreeSelect: `navclick` 事件重命名为 `click-nav`
- TreeSelect: `itemclick` 事件重命名为 `click-item`
### 徽标属性命名调整
在之前的版本中,我们通过 info 属性来展示图标右上角的徽标信息,为了更符合社区的命名习惯,我们将这个属性重命名为 badge影响以下组件
@ -118,6 +102,54 @@ GoodsAction 商品导航组件重命名为 **ActionBar 行动栏**。
同时内部使用的 Info 组件也会重命名为 Badge。
### 重命名 get-container 属性
Vue 3.0 中增加了 `Teleport` 组件,提供将组件渲染到任意 DOM 位置的能力Vant 2.x 也通过 `get-container` 属性提供了类似的能力。为了与官方的 API 保持一致Vant 中的 `get-container` 属性将重命名为 `teleport`
```html
<!-- Vant 2 -->
<template>
<van-popup get-container="body" />
<van-popup :get-container="getContainer" />
</template>
<script>
export default {
methods: {
getContainer() {
return document.querySelector('#container');
},
},
};
</script>
<!-- Vant 3 -->
<template>
<van-popup teleport="body" />
<van-popup :teleport="container" />
</template>
<script>
export default {
beforeCreate() {
this.container = document.querySelector('#container');
},
};
</script>
```
### API 调整
- Area: 移除 change 事件的第一个参数picker 实例)
- Button: 蓝色按钮对应的类型由 `info` 调整为 `primary`
- Button: 绿色按钮对应的类型由 `primary` 调整为 `success`
- Picker: 移除 change 事件的第一个参数picker 实例)
- Picker: 默认开启 show-toolbar 属性
- Picker: 级联选择下confirm/change 事件返回的回调参数将包含为完整的选项对象。
- SwipeCell: `open` 事件的 `detail` 参数重命名为 `name`
- SwipeCell: `on-close` 属性重命名为 `before-close`,并调整参数结构
- Toast: `mask` 属性重命名为 `overlay`
- TreeSelect: `navclick` 事件重命名为 `click-nav`
- TreeSelect: `itemclick` 事件重命名为 `click-item`
### 注册全局方法
Vant 2.x 中默认提供了 `$toast``$dialog` 等全局方法,但 Vue 3.0 不再支持直接在 Vue 的原型链上挂载方法,因此从 Vant 3.0 开始,使用全局方法前必须先通过 `app.use` 将组件注册到对应的 app 上。

View File

@ -166,7 +166,7 @@ export default {
| close-on-click-action | Whether to close when click action | _boolean_ | `false` |
| close-on-click-overlay | Whether to close when click overlay | _boolean_ | `true` |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` |
| get-container | Return the mount node for ActionSheet | _string \| () => Element_ | - |
| teleport | Return the mount node for ActionSheet | _string \| Element_ | - |
### Data Structure of Action

View File

@ -172,7 +172,7 @@ export default {
| close-on-click-action | 是否在点击选项后关闭 | _boolean_ | `false` |
| close-on-click-overlay | 是否在点击遮罩层后关闭 | _boolean_ | `true` |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` |
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Action 数据结构

View File

@ -14,9 +14,9 @@ export default createComponent({
title: String,
actions: Array,
duration: [Number, String],
teleport: [String, Object],
cancelText: String,
description: String,
getContainer: [String, Function],
closeOnPopstate: Boolean,
closeOnClickAction: Boolean,
round: {
@ -163,7 +163,7 @@ export default createComponent({
duration={props.duration}
lazyRender={props.lazyRender}
lockScroll={props.lockScroll}
getContainer={props.getContainer}
teleport={props.teleport}
closeOnPopstate={props.closeOnPopstate}
closeOnClickOverlay={props.closeOnClickOverlay}
safeAreaInsetBottom={props.safeAreaInsetBottom}

View File

@ -51,7 +51,7 @@ test('click overlay and close', async () => {
<div>
<action-sheet
:value="true"
:get-container="getContainer"
:teleport="teleport"
@input="onInput"
@click-overlay="onClickOverlay"
/>
@ -62,7 +62,7 @@ test('click overlay and close', async () => {
},
data() {
return {
getContainer: () => div,
teleport: () => div,
};
},
methods: {
@ -110,7 +110,7 @@ test('get container', () => {
const wrapper = mount(ActionSheet, {
propsData: {
value: true,
getContainer: 'body',
teleport: 'body',
},
});

View File

@ -388,9 +388,9 @@ export default createComponent({
<Popup
show={this.showAreaPopup}
round
teleport="body"
position="bottom"
lazyRender={false}
getContainer="body"
{...{
'onUpdate:modelValue': (value) => {
this.showAreaPopup = value;

View File

@ -258,7 +258,7 @@ Following props are supported when the poppable is true
| close-on-popstate `v2.4.4` | Whether to close when popstate | _boolean_ | `true` |
| close-on-click-overlay | Whether to close when click overlay | _boolean_ | `true` |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` |
| get-container `v2.4.4` | Return the mount node for Calendar | _string \| () => Element_ | - |
| teleport `v2.4.4` | Return the mount node for Calendar | _string \| Element_ | - |
### Range Props

View File

@ -260,7 +260,7 @@ export default {
| close-on-popstate `v2.4.4` | 是否在页面回退时自动关闭 | _boolean_ | `true` |
| close-on-click-overlay | 是否在点击遮罩层后关闭 | _boolean_ | `true` |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` |
| get-container `v2.4.4` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport `v2.4.4` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Range Props

View File

@ -27,11 +27,11 @@ export default createComponent({
show: Boolean,
title: String,
color: String,
teleport: [String, Object],
formatter: Function,
confirmText: String,
rangePrompt: String,
defaultDate: [Date, Array],
getContainer: [String, Function],
allowSameDay: Boolean,
confirmDisabledText: String,
type: {
@ -487,7 +487,7 @@ export default createComponent({
round={this.round}
position={this.position}
closeable={this.showTitle || this.showSubtitle}
getContainer={this.getContainer}
teleport={this.teleport}
closeOnPopstate={this.closeOnPopstate}
closeOnClickOverlay={this.closeOnClickOverlay}
{...listeners}

View File

@ -159,7 +159,7 @@ export default {
| allowHtml `v2.8.7` | Whether to allow HTML rendering in message | _boolean_ | `true` |
| beforeClose | Callback before close,<br>call done() to close dialog,<br>call done(false) to cancel loading | (action: string, done: Function) => void | - |
| transition `v2.2.6` | Transition, equivalent to `name` prop of [transtion](https://vuejs.org/v2/api/#transition) | _string_ | - |
| getContainer | Return the mount node for Dialog | _string \| () => Element_ | `body` |
| teleport | Return the mount node for Dialog | _string \| Element_ | `body` |
### Props
@ -187,7 +187,7 @@ export default {
| allow-html `v2.8.7` | Whether to allow HTML rendering in message | _boolean_ | `true` |
| before-close | Callback before close,<br>call done() to close dialog,<br>call done(false) to cancel loading | (action: string, done: Function) => void | - |
| transition `v2.2.6` | Transition, equivalent to `name` prop of [transtion](https://vuejs.org/v2/api/#transition) | _string_ | - |
| get-container | Return the mount node for Dialog | _string \| () => Element_ | - |
| teleport | Return the mount node for Dialog | _string \| Element_ | - |
### Events

View File

@ -189,7 +189,7 @@ export default {
| allowHtml `v2.8.7` | 是否允许 message 内容中渲染 HTML | _boolean_ | `true` |
| beforeClose | 关闭前的回调函数,<br>调用 done() 后关闭弹窗,<br>调用 done(false) 阻止弹窗关闭 | _(action, done) => void_ | - |
| transition `v2.2.6` | 动画类名,等价于 [transtion](https://cn.vuejs.org/v2/api/index.html#transition) 的`name`属性 | _string_ | - |
| getContainer | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | `body` |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | `body` |
### Props
@ -219,7 +219,7 @@ export default {
| allow-html `v2.8.7` | 是否允许 message 内容中渲染 HTML | _boolean_ | `true` |
| before-close | 关闭前的回调函数,<br>调用 done() 后关闭弹窗,<br>调用 done(false) 阻止弹窗关闭 | _(action, done) => void_ | - |
| transition `v2.2.6` | 动画类名,等价于 [transtion](https://cn.vuejs.org/v2/api/index.html#transition) 的`name`属性 | _string_ | - |
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Events

View File

@ -70,6 +70,7 @@ Dialog.defaultOptions = {
message: '',
overlay: true,
callback: null,
teleport: 'body',
className: '',
allowHtml: true,
lockScroll: true,
@ -78,7 +79,6 @@ Dialog.defaultOptions = {
overlayClass: '',
overlayStyle: null,
messageAlign: '',
getContainer: 'body',
cancelButtonText: '',
cancelButtonColor: null,
confirmButtonText: '',

View File

@ -95,8 +95,8 @@ export default createComponent({
},
onClickWrapper(event) {
// prevent being identified as clicking outside and closed when use get-contaienr
if (this.getContainer) {
// prevent being identified as clicking outside and closed when using teleport
if (this.teleport) {
event.stopPropagation();
}
},

View File

@ -143,7 +143,7 @@ Use `active-color` prop to custom active color of the title and options
| disabled | Whether to disable dropdown item | _boolean_ | `false` |
| lazy-render `v2.8.5` | Whether to lazy render util opened | _boolean_ | `true` |
| title-class | Title class | _string_ | - |
| get-container `v2.2.4` | Return the mount node for menu | _string \| () => Element_ | - |
| teleport `v2.2.4` | Return the mount node for menu | _string \| Element_ | - |
### DropdownItem Events

View File

@ -147,7 +147,7 @@ export default {
| disabled | 是否禁用菜单 | _boolean_ | `false` |
| lazy-render `v2.8.5` | 是否在首次展开时才渲染菜单内容 | _boolean_ | `true` |
| title-class | 标题额外类名 | _string_ | - |
| get-container `v2.2.4` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport `v2.2.4` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### DropdownItem Events

View File

@ -13,7 +13,7 @@
v-model:show="showArea"
round
position="bottom"
get-container="body"
teleport="body"
>
<van-area
:area-list="t('areaList')"

View File

@ -12,7 +12,7 @@
<van-calendar
v-model:show="showCalendar"
round
get-container="body"
teleport="body"
@confirm="onConfirm"
/>
</template>

View File

@ -13,7 +13,7 @@
v-model:show="showPicker"
round
position="bottom"
get-container="body"
teleport="body"
>
<van-datetime-picker
type="time"

View File

@ -13,7 +13,7 @@
v-model:show="showPicker"
round
position="bottom"
get-container="body"
teleport="body"
>
<van-picker
:columns="t('textColumns')"

View File

@ -130,7 +130,7 @@ export default {
| closeable `v2.5.0` | Whether to show close icon | _boolean_ | `false` |
| closeIcon `v2.5.0` | Close icon name | _string_ | `clear` |
| closeIconPosition `v2.5.0` | Close icon positioncan be set to `top-left` `bottom-left` `bottom-right` | _string_ | `top-right` |
| getContainer | Return the mount node for ImagePreview | _string \| () => Element_ | - |
| teleport | Return the mount node for ImagePreview | _string \| Element_ | - |
### Props
@ -150,7 +150,7 @@ export default {
| closeable `v2.5.0` | Whether to show close icon | _boolean_ | `false` |
| close-icon `v2.5.0` | Close icon name | _string_ | `clear` |
| close-icon-position `v2.5.0` | Close icon positioncan be set to `top-left` `bottom-left` `bottom-right` | _string_ | `top-right` |
| get-container | Return the mount node for ImagePreview | _string \| () => Element_ | - |
| teleport | Return the mount node for ImagePreview | _string \| Element_ | - |
### Events

View File

@ -166,7 +166,7 @@ export default {
| closeable `v2.5.0` | 是否显示关闭图标 | _boolean_ | `false` |
| closeIcon `v2.5.0` | 关闭图标名称或图片链接 | _string_ | `clear` |
| closeIconPosition `v2.5.0` | 关闭图标位置,可选值为`top-left`<br>`bottom-left` `bottom-right` | _string_ | `top-right` |
| getContainer | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Props
@ -188,7 +188,7 @@ export default {
| closeable `v2.5.0` | 是否显示关闭图标 | _boolean_ | `false` |
| close-icon `v2.5.0` | 关闭图标名称或图片链接 | _string_ | `clear` |
| close-icon-position `v2.5.0` | 关闭图标位置,可选值为`top-left`<br>`bottom-left` `bottom-right` | _string_ | `top-right` |
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Events

View File

@ -12,12 +12,12 @@ const defaultConfig = {
onScale: null,
onClose: null,
onChange: null,
teleport: 'body',
className: '',
showIndex: true,
closeable: false,
closeIcon: 'clear',
asyncClose: false,
getContainer: 'body',
startPosition: 0,
swipeDuration: 500,
showIndicators: false,

View File

@ -336,7 +336,7 @@ test('ImagePreview.Component', () => {
test('get container with function call ', async (done) => {
const element = document.createElement('div');
document.body.appendChild(element);
ImagePreview({ images, getContainer: () => element });
ImagePreview({ images, teleport: element });
await Vue.nextTick();
const wrapperDiv = document.querySelector('.van-image-preview');
@ -358,22 +358,22 @@ test('get container with component call', () => {
const wrapper = mount({
template: `
<div>
<van-image-preview :value="true" :get-container="getContainer">
<van-image-preview :value="true" :teleport="teleport">
</van-image-preview>
</div>
`,
data() {
return {
getContainer: () => div1,
teleport: () => div1,
};
},
});
const imageView = wrapper.find('.van-image-preview').element;
expect(imageView.parentNode).toEqual(div1);
wrapper.vm.getContainer = () => div2;
wrapper.vm.teleport = () => div2;
expect(imageView.parentNode).toEqual(div2);
wrapper.vm.getContainer = null;
wrapper.vm.teleport = null;
expect(wrapper.element).toEqual(wrapper.element);
});

View File

@ -1,35 +1,35 @@
function getElement(selector) {
if (typeof selector === 'string') {
return document.querySelector(selector);
function getElement(teleport) {
if (typeof teleport === 'string') {
return document.querySelector(teleport);
}
return selector();
return teleport;
}
export function PortalMixin({ ref, afterPortal } = {}) {
return {
props: {
getContainer: [String, Function],
teleport: [String, Object],
},
watch: {
getContainer: 'portal',
teleport: 'portal',
},
mounted() {
if (this.getContainer) {
if (this.teleport) {
this.portal();
}
},
methods: {
portal() {
const { getContainer } = this;
const { teleport } = this;
const el = ref ? this.$refs[ref] : this.$el;
let container;
if (getContainer) {
container = getElement(getContainer);
if (teleport) {
container = getElement(teleport);
} else if (this.$parent) {
container = this.$parent.$el;
}

View File

@ -9,9 +9,9 @@ export default createComponent({
color: String,
message: [Number, String],
duration: [Number, String],
teleport: [String, Object],
className: null,
background: String,
getContainer: [String, Function],
type: {
type: String,
default: 'danger',

View File

@ -156,7 +156,7 @@ export default {
| close-button-loading `v2.7.0` | Whether to show loading close button in custom theme | _boolean_ | `false` |
| show-delete-key `v2.5.9` | Whether to show delete button | _boolean_ | `true` |
| hide-on-click-outside | Whether to hide keyboard when click outside | _boolean_ | `true` |
| get-container `v2.10.0` | Return the mount node for NumberKeyboard | _string \| () => Element_ | - |
| teleport `v2.10.0` | Return the mount node for NumberKeyboard | _string \| Element_ | - |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` |
### Events

View File

@ -169,7 +169,7 @@ export default {
| close-button-loading `v2.7.0` | 是否将关闭按钮设置为加载中状态,仅在 `theme="custom"` 时有效 | _boolean_ | `false` |
| show-delete-key `v2.5.9` | 是否展示删除图标 | _boolean_ | `true` |
| hide-on-click-outside | 点击外部时是否收起键盘 | _boolean_ | `true` |
| get-container `v2.10.0` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport `v2.10.0` | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` |
### Events

View File

@ -83,30 +83,28 @@ Use `position` prop to set popup display position
### Get Container
Use `get-container` prop to specify mount location
Use `teleport` prop to specify mount location
```html
<!-- mount to body -->
<van-popup v-model:show="show" get-container="body" />
<van-popup v-model:show="show" teleport="body" />
<!-- mount to #app -->
<van-popup v-model:show="show" get-container="#app" />
<van-popup v-model:show="show" teleport="#app" />
<!-- Specify the mount location by function -->
<van-popup v-model:show="show" :get-container="getContainer" />
<!-- mount to Element -->
<van-popup v-model:show="show" :teleport="myContainer" />
```
```js
export default {
methods: {
getContainer() {
return document.querySelector('.my-container');
},
beforeCreate() {
this.myContainer = document.querySelector('.my-container');
},
};
```
> Tips: The get-container prop cannot be used on the root node
> Tips: The teleport prop cannot be used on the root node
## API
@ -129,7 +127,7 @@ export default {
| close-icon `v2.2.0` | Close icon name | _string_ | `cross` |
| close-icon-position `v2.2.2` | Close Icon Positioncan be set to `top-left` `bottom-left` `bottom-right` | _string_ | `top-right` |
| transition | Transition, equivalent to `name` prop of [transtion](https://vuejs.org/v2/api/#transition) | _string_ | - |
| get-container | Return the mount node for Popup | _string \| () => Element_ | - |
| teleport | Return the mount node for Popup | _string \| Element_ | - |
| safe-area-inset-bottom `v2.2.1` | Whether to enable bottom safe area adaptation | _boolean_ | `false` |
### Events

View File

@ -93,31 +93,28 @@ export default {
### 指定挂载位置
弹出层默认挂载到组件所在位置,可以通过`get-container`属性指定挂载位置
弹出层默认挂载到组件所在位置,可以通过`teleport`属性指定挂载位置
```html
<!-- 挂载到 body 节点下 -->
<van-popup v-model:show="show" get-container="body" />
<van-popup v-model:show="show" teleport="body" />
<!-- 挂载到 #app 节点下 -->
<van-popup v-model:show="show" get-container="#app" />
<van-popup v-model:show="show" teleport="#app" />
<!-- 通过函数指定挂载位置 -->
<van-popup v-model:show="show" :get-container="getContainer" />
<!-- 挂载到指定的元素下 -->
<van-popup v-model:show="show" :teleport="myContainer" />
```
```js
export default {
methods: {
// 返回一个特定的 DOM 节点,作为挂载的父节点
getContainer() {
return document.querySelector('.my-container');
},
beforeCreate() {
this.myContainer = document.querySelector('.my-container');
},
};
```
> 注意:使用 get-container 属性的组件不能为根节点
> 注意:使用 teleport 属性的组件不能为根节点
## API
@ -140,7 +137,7 @@ export default {
| close-icon `v2.2.0` | 关闭图标名称或图片链接 | _string_ | `cross` |
| close-icon-position `v2.2.2` | 关闭图标位置,可选值为`top-left`<br>`bottom-left` `bottom-right` | _string_ | `top-right` |
| transition | 动画类名,等价于 [transtion](https://cn.vuejs.org/v2/api/index.html#transition) 的`name`属性 | _string_ | - |
| get-container | 指定挂载的节点 | _string \| () => Element_ | - |
| teleport | 指定挂载的节点 | _string \| Element_ | - |
| safe-area-inset-bottom `v2.2.1` | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | _boolean_ | `false` |
### Events

View File

@ -84,15 +84,15 @@
/>
</demo-block>
<demo-block card v-if="!isWeapp" :title="t('getContainer')">
<demo-block card v-if="!isWeapp" :title="t('teleport')">
<van-cell
:title="t('getContainer')"
:title="t('teleport')"
is-link
@click="showGetContainer = true"
/>
<van-popup
v-model:show="showGetContainer"
get-container="body"
teleport="body"
:style="{ padding: '30px 50px' }"
/>
</demo-block>
@ -109,7 +109,7 @@ export default {
buttonBottom: '底部弹出',
buttonLeft: '左侧弹出',
buttonRight: '右侧弹出',
getContainer: '指定挂载节点',
teleport: '指定挂载节点',
roundCorner: '圆角弹窗',
closeIcon: '关闭图标',
customCloseIcon: '自定义图标',
@ -122,7 +122,7 @@ export default {
buttonBottom: 'From Bottom',
buttonLeft: 'From Left',
buttonRight: 'From Right',
getContainer: 'Get Container',
teleport: 'Get Container',
roundCorner: 'Round Corner',
closeIcon: 'Close Icon',
customCloseIcon: 'Custom Icon',

View File

@ -33,7 +33,7 @@ export const popupSharedProps = {
// overlay custom class name
overlayClass: String,
// teleport
getContainer: [String, Function],
teleport: [String, Object],
// whether to close popup when click overlay
closeOnClickOverlay: Boolean,
// z-index
@ -319,9 +319,9 @@ export default createComponent({
},
render() {
const { getContainer } = this;
if (getContainer) {
const to = isFunction(getContainer) ? getContainer() : getContainer;
const { teleport } = this;
if (teleport) {
const to = isFunction(teleport) ? teleport() : teleport;
return (
<Teleport to={to}>
{this.genOverlay()}

View File

@ -53,7 +53,7 @@ test('get container with parent', () => {
wrapper = mount({
template: `
<div>
<popup :value="true" :get-container="getContainer" />
<popup :value="true" :teleport="teleport" />
</div>
`,
components: {
@ -61,16 +61,16 @@ test('get container with parent', () => {
},
data() {
return {
getContainer: () => div1,
teleport: div1,
};
},
});
const popup = wrapper.find('.van-popup').element;
expect(popup.parentNode).toEqual(div1);
wrapper.vm.getContainer = () => div2;
wrapper.vm.teleport = () => div2;
expect(popup.parentNode).toEqual(div2);
wrapper.vm.getContainer = null;
wrapper.vm.teleport = null;
expect(popup.parentNode).toEqual(wrapper.element);
});
@ -78,8 +78,8 @@ test('get container with selector', () => {
wrapper = mount({
template: `
<div>
<popup class="get-container-selector-1" :value="true" get-container="body"></popup>
<popup class="get-container-selector-2" :value="true" get-container="unknown"></popup>
<popup class="teleport-selector-1" :value="true" teleport="body"></popup>
<popup class="teleport-selector-2" :value="true" teleport="unknown"></popup>
</div>
`,
components: {
@ -87,8 +87,8 @@ test('get container with selector', () => {
},
});
const dom1 = document.querySelector('.get-container-selector-1');
const dom2 = wrapper.vm.$el.querySelector('.get-container-selector-2');
const dom1 = document.querySelector('.teleport-selector-1');
const dom2 = wrapper.vm.$el.querySelector('.teleport-selector-2');
expect(dom1.parentNode).toEqual(document.body);
expect(dom2.parentNode).toEqual(wrapper.vm.$el);
@ -99,7 +99,7 @@ test('render overlay', async () => {
wrapper = mount({
template: `
<div>
<popup :value="true" :get-container="getContainer" />
<popup :value="true" :teleport="teleport" />
</div>
`,
components: {
@ -107,7 +107,7 @@ test('render overlay', async () => {
},
data() {
return {
getContainer: () => div,
teleport: () => div,
};
},
});
@ -122,7 +122,7 @@ test('watch overlay prop', async () => {
wrapper = mount({
template: `
<div>
<popup :value="show" :overlay="overlay" :get-container="getContainer" />
<popup :value="show" :overlay="overlay" :teleport="teleport" />
</div>
`,
components: {
@ -132,7 +132,7 @@ test('watch overlay prop', async () => {
return {
show: false,
overlay: false,
getContainer: () => div,
teleport: () => div,
};
},
});
@ -158,7 +158,7 @@ test('close on click overlay', async () => {
<div>
<popup
v-model="value"
:get-container="getContainer"
:teleport="teleport"
@click-overlay="onClickOverlay"
/>
</div>
@ -169,7 +169,7 @@ test('close on click overlay', async () => {
data() {
return {
value: true,
getContainer: () => div,
teleport: () => div,
};
},
methods: {

View File

@ -123,7 +123,7 @@ export default {
| close-on-popstate | Whether to close when popstate | _boolean_ | `true` |
| close-on-click-overlay | Whether to close when click overlay | _boolean_ | `true` |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` |
| get-container | Return the mount node for ShareSheet | _string \| () => Element_ | - |
| teleport | Return the mount node for ShareSheet | _string \| Element_ | - |
### Data Structure of Option

View File

@ -169,7 +169,7 @@ export default {
| close-on-popstate | 是否在页面回退时自动关闭 | _boolean_ | `true` |
| close-on-click-overlay | 是否在点击遮罩层后关闭 | _boolean_ | `true` |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` |
| get-container | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | - |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - |
### Option 数据结构

View File

@ -13,9 +13,9 @@ export default createComponent({
...popupSharedProps,
title: String,
duration: [Number, String],
teleport: [String, Object],
cancelText: String,
description: String,
getContainer: [String, Function],
options: {
type: Array,
default: () => [],
@ -141,7 +141,7 @@ export default createComponent({
duration={this.duration}
lazyRender={this.lazyRender}
lockScroll={this.lockScroll}
getContainer={this.getContainer}
teleport={this.teleport}
closeOnPopstate={this.closeOnPopstate}
closeOnClickOverlay={this.closeOnClickOverlay}
safeAreaInsetBottom={this.safeAreaInsetBottom}

View File

@ -89,7 +89,7 @@ test('click-overlay event', async () => {
const wrapper = mount(ShareSheet, {
propsData: {
value: true,
getContainer: () => root,
teleport: root,
},
});

View File

@ -154,4 +154,4 @@ Toast.resetDefaultOptions('loading');
| onOpened | Callback function after opened | _Function_ | - |
| onClose | Callback function after close | _Function_ | - |
| transition `v2.2.6` | Transition, equivalent to `name` prop of [transtion](https://vuejs.org/v2/api/#transition) | _string_ | `van-fade` |
| getContainer | Return the mount node for Toast | _string \| () => Element_ | `body` |
| teleport | Return the mount node for Toast | _string \| Element_ | `body` |

View File

@ -167,4 +167,4 @@ Toast.resetDefaultOptions('loading');
| onOpened | 完全展示后的回调函数 | _Function_ | - |
| onClose | 关闭时的回调函数 | _Function_ | - |
| transition `v2.2.6` | 动画类名,等价于 [transtion](https://cn.vuejs.org/v2/api/index.html#transition) 的`name`属性 | _string_ | `van-fade` |
| getContainer | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| () => Element_ | `body` |
| teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | `body` |

View File

@ -11,12 +11,12 @@ const defaultOptions = {
onClose: null,
onOpened: null,
duration: 2000,
teleport: 'body',
iconPrefix: undefined,
position: 'middle',
transition: 'van-fade',
forbidClick: false,
loadingType: undefined,
getContainer: 'body',
overlayStyle: null,
closeOnClick: false,
closeOnClickOverlay: false,