提交 d8b7b569 编写于 作者: DCloud-WZF's avatar DCloud-WZF 💬

refactor(h5 map): 优化map control创建方式

上级 3f5b9ed6
import { inject, onUnmounted, watch, PropType } from 'vue'
import { computed, PropType } from 'vue'
import { getRealPath } from '@dcloudio/uni-platform'
import { defineSystemComponent, useCustomEvent } from '@dcloudio/uni-components'
import { Maps, Map } from './maps'
import { defineSystemComponent } from '@dcloudio/uni-components'
interface Position {
left: number | string
......@@ -12,78 +11,50 @@ interface Position {
const props = {
id: { type: [Number, String], default: '' },
position: { type: Object as PropType<Position>, require: true },
iconPath: { type: String, require: true },
position: { type: Object as PropType<Position>, required: true },
iconPath: { type: String, required: true },
clickable: { type: [Boolean, String], default: '' },
rootRef: { type: Object, default: null },
trigger: { type: Function, required: true },
}
export type Props = Partial<Record<keyof typeof props, any>>
type CustomEventTrigger = ReturnType<typeof useCustomEvent>
type OnMapReadyCallback = (
map: Map,
maps: Maps,
trigger: CustomEventTrigger
) => void
type OnMapReady = (callback: OnMapReadyCallback) => void
export default /*#__PURE__*/ defineSystemComponent({
name: 'MapControl',
props,
setup(props) {
const onMapReady: OnMapReady = inject('onMapReady') as OnMapReady
let control: HTMLDivElement
function removeControl() {
if (control) {
control.remove()
const imgPath = computed(() => getRealPath(props.iconPath!))
const positionStyle = computed(() => {
let positionStyle = `top:${props.position!.top || 0}px;left:${props.position!.left || 0}px;`
if (props.position!.width) {
positionStyle += `width:${props.position!.width}px;`
}
}
onMapReady((_, __, trigger) => {
function updateControl(option: Props) {
removeControl()
addControl(option)
if (props.position!.height) {
positionStyle += `height:${props.position!.height}px;`
}
function addControl(option: Props) {
control = document.createElement('div')
const style = control.style
style.position = 'absolute'
style.width = '0'
style.height = '0'
style.top = '0'
style.left = '0'
const img = new Image()
img.src = getRealPath(option.iconPath)
img.onload = () => {
const position = option.position || {}
if (position.width) {
img.width = option.position.width
}
if (position.height) {
img.height = option.position.height
}
const style = img.style
style.position = 'absolute'
style.left = (position.left || 0) + 'px'
style.top = (position.top || 0) + 'px'
style.maxWidth = 'initial'
control.appendChild(img)
props.rootRef.value && props.rootRef.value.appendChild(control)
}
img.onclick = function ($event) {
if (option.clickable) {
trigger('controltap', $event, {
controlId: option.id,
})
}
}
}
addControl(props as Props)
watch(props, updateControl)
return positionStyle
})
onUnmounted(removeControl)
const handleClick = ($event: Event) => {
if (props.clickable) {
props.trigger!('controltap', $event, {
controlId: props.id,
})
}
}
return () => {
return null
return (
<div class="uni-map-control">
<img
src={imgPath.value}
style={positionStyle.value}
class="uni-map-control-icon"
onClick={handleClick}
/>
</div>
)
}
},
}
})
......@@ -14,6 +14,7 @@ import {
useContextInfo,
useSubscribe,
useCustomEvent,
CustomEventTrigger,
} from '@dcloudio/uni-components'
import '@amap/amap-jsapi-types'
import { callOptions } from '@dcloudio/uni-shared'
......@@ -171,7 +172,6 @@ function useMap(
longitude: Number(props.longitude),
includePoints: getPoints(props.includePoints),
})
type CustomEventTrigger = ReturnType<typeof useCustomEvent>
type OnMapReadyCallback = (
map: Map,
maps: Maps,
......@@ -487,6 +487,7 @@ function useMap(
return {
state,
mapRef,
trigger,
}
}
......@@ -508,7 +509,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({
],
setup(props, { emit, slots }) {
const rootRef: Ref<HTMLElement | null> = ref(null)
const { mapRef } = useMap(props, rootRef, emit as SetupContext['emit'])
const { mapRef,trigger } = useMap(props, rootRef, emit as SetupContext['emit'])
return () => {
return (
<uni-map ref={rootRef} id={props.id}>
......@@ -526,7 +527,7 @@ export default /*#__PURE__*/ defineBuiltInComponent({
<MapCircle {...item} />
))}
{props.controls.map((item) => (
<MapControl {...item} rootRef={rootRef} />
<MapControl {...item} trigger={trigger} />
))}
{props.showLocation && <MapLocation />}
{props.polygons.map((item) => (
......
......@@ -18,4 +18,17 @@ uni-map[hidden] {
.amap-marker>.amap-icon>img{
left:0!important;
top:0!important;
}
.uni-map-control{
position:absolute;
width:0;
height:0;
top:0;
left:0;
z-index:999;
}
.uni-map-control-icon{
position:absolute;
max-width:initial;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册