123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- <template>
- <view class="muqian-content" :style="{
- width,
- height,
- }">
-
- <image class="muqian-image" @load="load" @error="error" v-if="status==1" :src="src" mode="scaleToFill" :style="{
- opacity:isShow?'1':'0',
- borderRadius,
- width,
- height,
- transition: `opacity ${duration/1000}s ${effect}`
- }">
- </image>
-
- <image :src="loadSrc" class="muqian-image muqain-load" @load="init" mode="scaleToFill" :style="{
- opacity:isShow?'0':'1',
- borderRadius,
- width,
- height,
- transition: `opacity ${duration/1000}s ${effect}`
- }"></image>
-
-
- <image class="muqian-image" v-if="status==2" :src="errorSrc" mode="scaleToFill" :style="{
- opacity:isShow?'1':'0',
- borderRadius,
- width,
- height,
- transition: `opacity ${duration/1000}s ${effect}`
- }">
- </image>
-
- </view>
- </template>
- <script>
- let loadTimer = null
- import loadingImage from '../../static/loading.gif'
- import loadFailImage from '../../static/loadFail.png'
-
- export default {
- name: "muqian-lazyLoad",
- props: {
-
- borderRadius: {
- type: String,
- default: '0'
- },
-
- width: {
- type: String,
- default: '100%'
- },
- height: {
- type: String,
- default: '100%'
- },
-
- src: {
- type: String,
- default: ''
- },
-
- minTimeOut: {
- type: String || Number,
- default: '300'
- },
-
- showDistance: {
- type: Object,
- default: () => {
- bottom: 20
- }
- },
-
- effect: {
- type: String,
- default: 'linear'
- },
-
- duration: {
- type: String || Number,
- default: '300'
- },
-
- loadSrc: {
- type: String,
- default: loadingImage
- },
-
- errorSrc: {
- type: String,
- default:loadFailImage
- },
- },
- data() {
- return {
- status: 0,
- isShow: false
- }
- },
- watch: {
-
- src() {
- if (!this.isShow) return
- this.status = 0
- this.isShow = false
- this.$nextTick(() => {
- this.status = 1
- })
- }
- },
- destroyed() {
-
- this.$emit('destroyed')
- },
- methods: {
- load() {
- if (this.minTimeOut == 0) {
- this.isShow = true
- }else{
- let newTimer = new Date().getTime() - loadTimer
- if (newTimer < this.minTimeOut) {
- setTimeout(() => {
- this.isShow = true
- }, this.minTimeOut - newTimer)
- } else {
- this.isShow = true
- }
- }
-
- setTimeout(()=>{
- this.$emit('showSuccess');
- },this.duration)
- this.$emit("imageLoadHandle",this.index)
- },
- error() {
- this.status = 2
- this.isShow = true
- this.$emit("imageLoadHandle",this.index)
- },
- init(){
- let intersectionObserver = uni.createIntersectionObserver(this)
- let load = false
-
- this.$once('destroyed', () => {
- intersectionObserver.disconnect()
- })
- intersectionObserver.relativeToViewport(this.showDistance).observe('.muqain-load', (res) => {
- if (!load && res.intersectionRatio == 0) {
- load = true
- return
- }
- this.$emit('show');
- load = true
- this.status = 1
- loadTimer = new Date().getTime()
- intersectionObserver.disconnect()
- })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .muqian-content {
- overflow: hidden;
- position: relative;
- .muqian-image {
- display: block;
- will-change: transform;
- }
- .muqain-load {
- position: absolute;
- left: 0;
- top: 0;
- }
- }
- </style>
|