vue watch实现懒加载
使用 Vue Watch 实现懒加载
在 Vue 中,watch 可以监听数据变化,结合懒加载技术,可以实现按需加载数据或组件。以下是几种常见实现方式:
监听滚动事件实现懒加载
通过监听滚动事件,结合 watch 判断元素是否进入可视区域:
data() {
return {
isLoading: false,
items: [],
currentPage: 1
}
},
watch: {
isLoading(newVal) {
if (newVal) {
this.loadMoreData()
}
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
const scrollPosition = window.innerHeight + window.scrollY
const pageHeight = document.documentElement.scrollHeight
if (scrollPosition >= pageHeight - 200 && !this.isLoading) {
this.isLoading = true
}
},
loadMoreData() {
fetch(`/api/items?page=${this.currentPage}`)
.then(res => res.json())
.then(data => {
this.items = [...this.items, ...data]
this.currentPage++
this.isLoading = false
})
}
}
使用 Intersection Observer API
更现代的方式是使用 Intersection Observer API,性能更好:
data() {
return {
observer: null,
items: [],
currentPage: 1
}
},
mounted() {
this.observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadMoreData()
}
})
}, { threshold: 0.1 })
this.observer.observe(document.querySelector('#load-more-trigger'))
},
methods: {
loadMoreData() {
fetch(`/api/items?page=${this.currentPage}`)
.then(res => res.json())
.then(data => {
this.items = [...this.items, ...data]
this.currentPage++
})
}
}
组件懒加载
对于 Vue 组件,可以使用动态导入实现懒加载:
components: {
'lazy-component': () => import('./LazyComponent.vue')
}
结合 watch 实现按需加载:
data() {
return {
showLazyComponent: false
}
},
watch: {
showLazyComponent(newVal) {
if (newVal) {
this.$nextTick(() => {
import('./LazyComponent.vue').then(component => {
this.$options.components['lazy-component'] = component
})
})
}
}
}
图片懒加载
实现图片懒加载的示例:
directives: {
lazy: {
inserted(el, binding) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
el.src = binding.value
observer.unobserve(el)
}
})
})
observer.observe(el)
}
}
}
在模板中使用:
<img v-lazy="imageUrl" alt="Lazy loaded image">
这些方法展示了如何利用 Vue 的 watch 功能结合不同技术实现懒加载效果,可以根据具体需求选择合适的方式。







