qs_xinchun2026_h5/node_modules/vue-lazyload/src/lazy-image.ts

105 lines
2.4 KiB
TypeScript

import {
loadImageAsync,
noop
} from './util'
import Lazy, { TvalueFormatterParam } from './lazy'
import { useCheckInView } from './useCheckInView'
import { loadImageAsyncOption } from '../types'
import {
defineComponent,
ref,
reactive,
watch,
onMounted,
onUnmounted,
createVNode,
computed
} from 'vue'
export default (lazy: Lazy) => {
return defineComponent<{
src: TvalueFormatterParam,
tag: string
}>({
setup(props,{ slots }) {
const el = ref<HTMLElement>()
const options = reactive({
src: '',
error: '',
loading: '',
attempt: lazy.options.attempt
})
const state = reactive({
loaded: false,
error: false,
attempt: 0
})
const { rect, checkInView } = useCheckInView(el, lazy.options.preLoad!)
const renderSrc = ref<string>('')
const load = (onFinish = noop) => {
if ((state.attempt > options.attempt! - 1) && state.error) {
if (!lazy.options.silent) console.log(`VueLazyload log: ${options.src} tried too more than ${options.attempt} times`)
return onFinish()
}
const src = options.src
loadImageAsync({ src }, ({ src }: loadImageAsyncOption) => {
renderSrc.value = src
state.loaded = true
}, () => {
state.attempt++
renderSrc.value = options.error
state.error = true
})
}
const vm = computed(() => {
return {
el: el.value,
rect,
checkInView,
load,
state,
}
})
onMounted(() => {
lazy.addLazyBox(vm.value)
lazy.lazyLoadHandler()
})
onUnmounted(() => {
lazy.removeComponent(vm.value)
})
const init = () => {
const { src, loading, error } = lazy._valueFormatter(props.src)
state.loaded = false
options.src = src
options.error = error!
options.loading = loading!
renderSrc.value = options.loading
}
watch(
()=> props.src,
() => {
init()
lazy.addLazyBox(vm.value)
lazy.lazyLoadHandler()
},
{
immediate: true
}
)
return () => createVNode(
props.tag || 'img',
{
src: renderSrc.value,
ref: el
},
[slots.default?.()]
)
}
})
}