提交 cbb3621a 编写于 作者: D DCloud_LXH

refactor: cover-image、cover-view、navigator

上级 98622ff5
......@@ -11,7 +11,7 @@ import Input from './input/index'
import Label from './label/index'
import MovableArea from './movable-area/index'
import MovableView from './movable-view/index'
import Navigator from './navigator/index.vue'
import Navigator from './navigator'
import PickerView from './picker-view/index'
import PickerViewColumn from './picker-view-column/index'
import Progress from './progress/index'
......
import { useHover } from '../../helpers/useHover'
import { defineBuiltInComponent } from '@dcloudio/uni-components'
const OPEN_TYPES = [
'navigate',
'redirect',
'switchTab',
'reLaunch',
'navigateBack',
]
const props = {
hoverClass: {
type: String,
default: 'navigator-hover',
},
url: {
type: String,
default: '',
},
openType: {
type: String,
default: 'navigate',
validator(value: unknown) {
return Boolean(~OPEN_TYPES.indexOf(value as string))
},
},
delta: {
type: Number,
default: 1,
},
hoverStartTime: {
type: [Number, String],
default: 50,
},
hoverStayTime: {
type: [Number, String],
default: 600,
},
exists: {
type: String,
default: '',
},
hoverStopPropagation: {
type: Boolean,
default: false,
},
}
export default /*#__PURE__*/ defineBuiltInComponent({
name: 'Navigator',
compatConfig: {
MODE: 3,
},
props,
setup(props, { slots }) {
const { hovering, binding } = useHover(props)
function onClick($event: MouseEvent) {
if (props.openType !== 'navigateBack' && !props.url) {
console.error(
'<navigator/> should have url attribute when using navigateTo, redirectTo, reLaunch or switchTab'
)
return
}
switch (props.openType) {
case 'navigate':
uni.navigateTo({
url: props.url,
})
break
case 'redirect':
uni.redirectTo({
url: props.url,
// @ts-ignore
exists: props.exists,
})
break
case 'switchTab':
uni.switchTab({
url: props.url,
})
break
case 'reLaunch':
uni.reLaunch({
url: props.url,
})
break
case 'navigateBack':
uni.navigateBack({
delta: props.delta,
})
break
default:
break
}
}
return () => {
const { hoverClass } = props
const hasHoverClass = props.hoverClass && props.hoverClass !== 'none'
return (
<uni-navigator
class={hasHoverClass && hovering.value ? hoverClass : ''}
{...(hasHoverClass && binding)}
onClick={onClick}
>
{slots.default && slots.default()}
</uni-navigator>
)
}
},
})
<template>
<uni-navigator
v-if="hoverClass && hoverClass !== 'none'"
:class="[hovering ? hoverClass : '']"
v-bind="binding"
@click="_onClick"
>
<slot />
</uni-navigator>
<uni-navigator v-else @click="_onClick">
<slot />
</uni-navigator>
</template>
<script>
import { useHover } from "../../helpers/useHover";
const OPEN_TYPES = ["navigate", "redirect", "switchTab", "reLaunch", "navigateBack"];
export default {
name: "Navigator",
compatConfig: {
MODE: 3
},
props: {
hoverClass: {
type: String,
default: "navigator-hover",
},
url: {
type: String,
default: "",
},
openType: {
type: String,
default: "navigate",
validator(value) {
return ~OPEN_TYPES.indexOf(value);
},
},
delta: {
type: Number,
default: 1,
},
hoverStartTime: {
type: [Number, String],
default: 50,
},
hoverStayTime: {
type: [Number, String],
default: 600,
},
exists: {
type: String,
default: "",
},
hoverStopPropagation: {
type: Boolean,
default: false,
},
},
methods: {
_onClick($event) {
if (this.openType !== "navigateBack" && !this.url) {
console.error(
"<navigator/> should have url attribute when using navigateTo, redirectTo, reLaunch or switchTab"
);
return;
}
switch (this.openType) {
case "navigate":
uni.navigateTo({
url: this.url,
});
break;
case "redirect":
uni.redirectTo({
url: this.url,
exists: this.exists,
});
break;
case "switchTab":
uni.switchTab({
url: this.url,
});
break;
case "reLaunch":
uni.reLaunch({
url: this.url,
});
break;
case "navigateBack":
uni.navigateBack({
delta: this.delta,
});
break;
default:
break;
}
},
},
setup(props) {
const { hovering, binding } = useHover(props);
return {
hovering,
binding,
};
},
};
</script>
此差异已折叠。
此差异已折叠。
......@@ -22,6 +22,7 @@ export const redirectTo = defineAsyncApi<API_TYPE_REDIRECT_TO>(
API_REDIRECT_TO,
({ url }, { resolve, reject }) => {
return (
// TODO exists 属性未实现
removeLastPage(),
navigate(API_REDIRECT_TO, url).then(resolve).catch(reject)
)
......
import { ref } from 'vue'
import { getRealPath } from '@dcloudio/uni-platform'
import { useCustomEvent, EmitEvent } from '@dcloudio/uni-components'
import { defineBuiltInComponent } from '@dcloudio/uni-components'
export default /*#__PURE__*/ defineBuiltInComponent({
name: 'CoverImage',
compatConfig: {
MODE: 3,
},
props: {
src: {
type: String,
default: '',
},
},
emits: ['load', 'error'],
setup(props, { emit }) {
const root = ref(null)
const trigger = useCustomEvent<EmitEvent<typeof emit>>(root, emit)
function load($event: Event) {
trigger('load', $event)
}
function error($event: Event) {
trigger('error', $event)
}
return () => {
const { src } = props
return (
<uni-cover-image ref={root} src={src}>
<div class="uni-cover-image">
{src ? (
<img src={getRealPath(src)} onLoad={load} onError={error} />
) : null}
</div>
</uni-cover-image>
)
}
},
})
<template>
<uni-cover-image ref="root" :src="src">
<div class="uni-cover-image">
<img v-if="src" :src="getRealPath(src)" @load="_load" @error="_error" />
</div>
</uni-cover-image>
</template>
<script>
import { ref } from "vue";
import { getRealPath } from "@dcloudio/uni-platform";
import { useCustomEvent } from "@dcloudio/uni-components";
export default {
name: "CoverImage",
compatConfig: {
MODE: 3
},
props: {
src: {
type: String,
default: "",
},
},
methods: {
getRealPath,
_load($event) {
this.$trigger("load", $event);
},
_error($event) {
this.$trigger("error", $event);
},
},
mounted() {
this.$trigger = useCustomEvent({ value: this.root }, this.$emit);
},
setup() {
const root = ref(null);
return {
root,
};
},
};
</script>
import { ref, ExtractPropTypes, watch, onMounted } from 'vue'
import { defineBuiltInComponent } from '@dcloudio/uni-components'
const props = {
scrollTop: {
type: [String, Number],
default: 0,
},
}
type Props = ExtractPropTypes<typeof props>
export default /*#__PURE__*/ defineBuiltInComponent({
name: 'CoverView',
compatConfig: {
MODE: 3,
},
props,
setup(props, { slots }) {
const content = ref<HTMLElement | null>(null)
watch(
() => props.scrollTop,
(val) => {
setScrollTop(val)
}
)
function setScrollTop(val: Props['scrollTop']) {
let _content = content.value!
if (getComputedStyle(_content).overflowY === 'scroll') {
_content.scrollTop = _upx2pxNum(val)
}
}
function _upx2pxNum(val: Props['scrollTop']) {
let _val = String(val)
if (/\d+[ur]px$/i.test(_val)) {
_val.replace(/\d+[ur]px$/i, (text) => {
return String(uni.upx2px(parseFloat(text)))
})
}
return parseFloat(_val) || 0
}
onMounted(() => {
setScrollTop(props.scrollTop)
})
return () => {
return (
<uni-cover-view scroll-top={props.scrollTop}>
<div ref={content} class="uni-cover-view">
{slots.default && slots.default()}
</div>
</uni-cover-view>
)
}
},
})
<template>
<uni-cover-view :scroll-top="scrollTop">
<div ref="content" class="uni-cover-view">
<slot />
</div>
</uni-cover-view>
</template>
<script>
import { ref } from "vue";
export default {
name: "CoverView",
compatConfig: {
MODE: 3
},
props: {
scrollTop: {
type: [String, Number],
default: 0,
},
},
watch: {
scrollTop(val) {
this.setScrollTop(val);
},
},
mounted() {
this.setScrollTop(this.scrollTop);
},
methods: {
setScrollTop(val) {
var content = this.content;
if (getComputedStyle(content).overflowY === "scroll") {
content.scrollTop = this._upx2pxNum(val);
}
},
_upx2pxNum(val) {
if (/\d+[ur]px$/i.test(val)) {
val.replace(/\d+[ur]px$/i, (text) => {
return uni.upx2px(parseFloat(text));
});
}
return parseFloat(val) || 0;
},
},
setup() {
const content = ref(null);
return {
content,
};
},
};
</script>
\ No newline at end of file
import Video from './video/index'
import WebView from './web-view/index'
import Map from './map/index'
import CoverView from './cover-view/index.vue'
import CoverImage from './cover-image/index.vue'
import CoverView from './cover-view'
import CoverImage from './cover-image'
import Picker from './picker/index.vue'
export { Video, WebView, Map, CoverView, CoverImage, Picker }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册