
简体中文
组件类型:UniShareElement
共享元素
共享元素组件,用于页面转场动画。指A、B 2个页面之间在动画时共享某个组件,这个组件在转场动画中通过特殊的动画从A页面的位置移动到B页面的位置。
常见场景有:
在hello uni-app x中,组件->视图容器下有共享元素示例,在模板->列表到详情 中也提供了演示。
注意共享元素组件仅指的是动画的视觉共享,并不是2个页面真的复用了同一个组件实例,不同页面的组件仍然是各自单独的实例。
Web | 微信小程序 | Android | iOS |
---|---|---|---|
x | x | 4.51 | 4.51 |
名称 | 类型 | 默认值 | 兼容性 | 描述 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
share-key | string | - | 映射标记,页面内唯一 | ||||||||||||||||||||||
easing-function | string | "ease-out" | css 缓动函数 | ||||||||||||||||||||||
| |||||||||||||||||||||||||
shuttle-on-push | string | "to" | 指定 push 阶段的飞跃物 | ||||||||||||||||||||||
| |||||||||||||||||||||||||
shuttle-on-pop | string | "to" | 指定 pop 阶段的飞跃物 | ||||||||||||||||||||||
| |||||||||||||||||||||||||
transition-on-gesture | boolean | false | 手势返回时是否进行动画 |
开发者可以指定选定源页面或目标页的 share-element
作为飞跃物
假定 A
页和 B
页存在对应的 share-element
组件
A
进入 B
,称 A
为源页面(from 页),B
为目标页(to 页)B
页的 share-element
组件进行飞跃,设置属性 shuttle-on-push=from 可切换成 A 页的 share-element
组件B
返回 A
,此时 B
为源页面 (from 页), A
为目标页(to 页)A
页的 share-element
组件,设置属性 shuttle-on-pop=from 可切换成 B
页的 share-element
组件B
页面(to 页)的 share-element
组件,pop阶段飞跃物也是 B
页面(from 页)的 share-element
组件share-element
组件执行共享元素动画过程中会将 share-element
的飞跃物
显示在页面最顶层,这会导致部分场景原本被其他元素遮挡的 share-element
会显示完整内容,这是为了更好的过度穿越效果并非BugA
页面
<template>
<view style="flex: 1;">
<share-element style="width: 200px;height: 200px;" share-key="box" >
<view style="width: 200px;height: 200px; background-color: red;"></view>
</share-element>
</view>
</template>
B
页面
<template>
<view style="flex: 1;">
<share-element style="width: 400px;height: 400px;" share-key="box" >
<view style="width: 400px;height: 400px; background-color: red;"></view>
</share-element>
</view>
</template>
A
和 B
页面分别设置 share-element
的 share-key 属性值,需要一致并且唯一,这样两个共享元素则会建立共享关系,切页动画时则会触发共享元素过度动画效果。
支持所有组件
该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验
<template>
<page-head title="share-element"></page-head>
<view class="main">
<share-element class="share-element" share-key="left" :shuttle-on-pop="shuttleOnPopType"
:transition-on-gesture="transitionOnGesture" :shuttle-on-push="shuttleOnPushType" :easing-function="easingFunctionType" @tap="openPage()">
<image style="width: 100px;height: 150px;"
src="https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/drop-card-1.jpg">
</image>
</share-element>
</view>
<button type="primary" @click="openPage" class="button">
打开share-element页面
</button>
<scroll-view style="flex: 1">
<view class="content">
<boolean-data :defaultValue="transitionOnGesture" title="transition-on-gesture= true(仅iOS生效)"
@change="changeTransitionOnGesture"></boolean-data>
<text class="uni-common-mt choose-property-title">easing-function:</text>
<radio-group class="choose-property-type-radio-group" @change="handleEasingFunction">
<radio class="ml-10 uni-common-mt" v-for="item in easingFunctionTypeList" :key="item" :value="item"
:checked="easingFunctionType == item">{{ item }}
</radio>
</radio-group>
<text class="uni-common-mt choose-property-title">shuttle-on-push(仅iOS生效):</text>
<radio-group class="choose-property-type-radio-group" @change="handleShuttleOnPushType">
<radio class="ml-10 uni-common-mt" v-for="item in shuttleOnTypeList" :key="item" :value="item"
:checked="shuttleOnPushType == item">{{ item }}
</radio>
</radio-group>
<text class="uni-common-mt choose-property-title">shuttle-on-pop(仅iOS生效):</text>
<radio-group class="choose-property-type-radio-group" @change="handleShuttleOnPopType">
<radio class="ml-10 uni-common-mt" v-for="item in shuttleOnTypeList" :key="item" :value="item"
:checked="shuttleOnPopType == item">{{ item }}
</radio>
</radio-group>
<text class="uni-common-mt choose-property-title">animationType(页面动画降级):</text>
<radio-group class="choose-property-type-radio-group" @change="handleOpenAnimationType">
<radio class="ml-10 uni-common-mt" v-for="item in openAnimationTypeList" :key="item" :value="item"
:checked="openAnimationType == item">{{ item }}
</radio>
</radio-group>
</view>
</scroll-view>
<view style="height: 80px;"></view>
<share-element class="bottomWrap" share-key="bottom" @tap="openPage()" transitionOnGesture=true>
<view class="bottom">
<text style="color: white;">share-element(底部固定)</text>
</view>
</share-element>
</template>
<script>
type ShareElementOpenAnimationType =
'auto' |
'none' |
'slide-in-right' |
'slide-in-left' |
'slide-in-top' |
'slide-in-bottom' |
'fade-in' |
'pop-in' |
'zoom-out' |
'zoom-fade-out'
type ShareElementEasingFunctionType =
'ease' |
'ease-in' |
'ease-out' |
'ease-in-out' |
'linear'
type ShuttleOnType =
'from' |
'to'
import { ItemType } from '@/components/enum-data/enum-data-types'
export default {
data() {
return {
transitionOnGesture: true,
shuttleOnPopType: 'to' as ShuttleOnType,
shuttleOnPushType: 'to' as ShuttleOnType,
shuttleOnTypeList: [
'from',
'to'
],
openAnimationType: 'slide-in-right' as ShareElementOpenAnimationType,
openAnimationTypeList: [
'auto',
'none',
'slide-in-right',
'slide-in-left',
'slide-in-top',
'slide-in-bottom',
'fade-in',
'pop-in',
'zoom-out',
'zoom-fade-out'
],
easingFunctionType: 'ease' as ShareElementEasingFunctionType,
easingFunctionTypeList: [
'ease',
'ease-in',
'ease-out',
'ease-in-out',
'linear'
]
}
},
methods: {
openPage() {
uni.navigateTo({
animationType: this.openAnimationType,
url: "/pages/component/share-element/share-element-to?shuttleOnPush=" + this.shuttleOnPushType + "&transitionOnGesture=" + this.transitionOnGesture
})
},
changeTransitionOnGesture(checked : boolean) {
console.log(`changeTransitionOnGesture:${checked}`)
this.transitionOnGesture = checked
},
handleOpenAnimationType(e : RadioGroupChangeEvent) {
this.openAnimationType = e.detail.value as ShareElementOpenAnimationType
},
handleEasingFunction(e : RadioGroupChangeEvent) {
this.easingFunctionType = e.detail.value as ShareElementEasingFunctionType
},
handleShuttleOnPopType(e : RadioGroupChangeEvent) {
this.shuttleOnPopType = e.detail.value as ShuttleOnType
},
handleShuttleOnPushType(e : RadioGroupChangeEvent) {
this.shuttleOnPushType = e.detail.value as ShuttleOnType
},
}
}
</script>
<style>
.ml-10 {
margin-left: 10px;
}
.choose-property-title {
font-weight: bold;
}
.choose-property-type-radio-group {
flex-direction: row;
flex-wrap: wrap;
}
.bottomWrap {
width: 100%;
bottom: 0px;
height: 80px;
position: fixed;
}
.bottom {
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
background-color: #007aff;
}
.main {
padding: 5px 0;
align-items: center;
justify-content: center;
}
</style>