提交 d2181186 编写于 作者: D DCloud_LXH

feat(h5): web-view

上级 a3b5033a
import Video from './video/index'
import WebView from './web-view/index'
export { Video }
export { Video, WebView }
import {
defineComponent,
watch,
ref,
ExtractPropTypes,
onMounted,
Ref,
onActivated,
onDeactivated,
onUnmounted,
} from 'vue'
import { ResizeSensor } from '@dcloudio/uni-components'
import { getRealPath } from '@dcloudio/uni-platform'
import { updateElementStyle } from '@dcloudio/uni-shared'
const props = {
src: {
type: String,
default: '',
},
allow: String,
sandbox: String,
}
type WebViewProps = ExtractPropTypes<typeof props>
type RootRef = Ref<HTMLElement | null>
type ReSize = ReturnType<typeof useWebViewSize>['_resize']
export default /*#__PURE__*/ defineComponent({
name: 'WebView',
props,
setup(props) {
const rootRef: RootRef = ref(null)
const iframe = document.createElement('iframe')
const { _resize } = useWebViewSize(rootRef, iframe)
useWebViewLoader(iframe, props, _resize)
return () => (
<uni-web-view ref={rootRef}>
<ResizeSensor onResize={_resize} />
</uni-web-view>
)
},
})
function useWebViewLoader(
iframe: HTMLIFrameElement,
props: WebViewProps,
_resize: ReSize
) {
props.allow && iframe.setAttribute('allow', props.allow)
props.sandbox && iframe.setAttribute('sandbox', props.sandbox)
iframe.src = getRealPath(props.src)
document.body.appendChild(iframe)
onMounted(() => {
_resize()
})
onActivated(() => {
iframe.style.display = 'block'
})
onDeactivated(() => {
iframe.style.display = 'none'
})
onUnmounted(() => {
document.body.removeChild(iframe)
})
watch(
() => props.src,
(val) => {
iframe.src = getRealPath(val)
}
)
}
function useWebViewSize(rootRef: RootRef, iframe: HTMLIFrameElement) {
const _resize = () => {
const { top, left, width, height } = rootRef.value!.getBoundingClientRect()
updateElementStyle(iframe, {
position: 'absolute',
display: 'block',
border: '0',
top: top + 'px',
left: left + 'px',
width: width + 'px',
height: height + 'px',
})
}
return {
_resize,
}
}
<template>
<uni-web-view v-on="$listeners">
<v-uni-resize-sensor
ref="sensor"
@resize="_resize"
/>
</uni-web-view>
</template>
<script>
export default {
name: 'WebView',
props: {
src: {
type: String,
default: ''
}
},
watch: {
src (val, oldVal) {
this.iframe && (this.iframe.src = this.$getRealPath(this.src))
}
},
mounted () {
this.iframe = document.createElement('iframe')
Object.keys(this.$attrs).forEach(key => {
this.iframe[key] = this.$attrs[key]
})
this.iframe.src = this.$getRealPath(this.src)
document.body.appendChild(this.iframe)
this._resize()
},
activated () {
this.iframe.style.display = 'block'
},
deactivated () {
this.iframe.style.display = 'none'
},
beforeDestroy () {
document.body.removeChild(this.iframe)
},
methods: {
_resize () {
const {
top,
left,
width,
height
} = this.$el.getBoundingClientRect()
this.iframe.style.position = 'absolute'
this.iframe.style.display = 'block'
this.iframe.style.border = 0
this.iframe.style.top = top + 'px'
this.iframe.style.left = left + 'px'
this.iframe.style.width = width + 'px'
this.iframe.style.height = height + 'px'
}
}
}
</script>
<style>
uni-web-view {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
</style>
uni-web-view {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册