建立网站需要多少钱责任y湖南岚鸿联系,wordpress图片设置水印,卓博招聘人才网,网站建设优化哪家专业目标#xff1a;实现当组件进入可视区域在加载数据或者发送请求。
背景#xff1a;父组件为vxe-table构成的组件、子组件为table的某一列#xff0c;这一列的数据通过接口返回#xff0c;有多少条表格数据就会请求多少次接口#xff0c;为了提升性能#xff0c;所以采用…目标实现当组件进入可视区域在加载数据或者发送请求。
背景父组件为vxe-table构成的组件、子组件为table的某一列这一列的数据通过接口返回有多少条表格数据就会请求多少次接口为了提升性能所以采用接口懒加载但是需要在回滚的时候不重复请求或者加载数据
使用 vueuse/core 中的 useIntersectionObserver 来实现监听进入可视区域行为但是必须配合vue3.0的组合API的方式才能实现。对某个板块进行数据懒加载首先要获取到这个dom元素然后用useIntersectionObserver来监听这个dom一旦可视区进入了这个dom元素这里就可以进行请求数据接口安装vueuse/core包,它封装了一些常见的交互逻辑通过状态机保存在列表上已经加载过了的数据并打上已经加载过了的标签isLaded:rue回滚时就对比传入子组件的row数据的id与存入状态机的数据是否有id相同的一条并查看是否 已存在isLoaded npm i vueuse/core4.9.0 步骤
理解 useIntersectionObserver 的使用各个参数的含义封装 useLazyData 函数作为数据懒加载公用函数把 index.vue页面里数据改造成懒加载方式 页面准备
src/hook.ts存放懒加载逻辑的函数
import { useIntersectionObserver } from vueuse/core
import { ref } from vue/*** 用于懒加载数据* param {*} apiFn 懒加载数据的接口* returns target: 需要绑定的DOM对象 result: 结果数据*/
export const useLazyData (apiFn: Function) {const target ref(null)const result ref()let stopObserver // 保存观察者的停止函数const { stop } useIntersectionObserver(target, ([{ isIntersecting }], observerElement) {if (isIntersecting) {stopObserver() // 调用之前保存的停止函数apiFn().then((data) {if (data) {result.value data}})}})stopObserver stop // 保存观察者的停止函数return { target, result,stopObserver }
}
在状态机中定义好状态机的一切 [RootMutations.LOADED_TEST_DATA](state: RootState, value) {state.loadedTestData value},
子组件绑定target使用懒加载
section reftargetspan{{ newData?.end_time }}/span/sectionimport { defaultProps } from ./propsconst props defineProps(defaultProps)
const emits defineEmits([update])
const { modelValue, endTime } toRefs(props)const newData: RefApp.BatteryTest ref(unref(modelValue))
//封装接口请求
const getDeadline () {
.test(参数, {//逻辑代码}).then(([res]) {if (res?.status 200) {nextTick(() {newData.value { ...unref(newData), end_time: dateFormat(res?.data?.Deadline / 1000) }emits(update, unref(newData))updateLoadedData() //更新已经加载的数据 })return dateFormat(res?.data?.Deadline / 1000) //这里返回给hook中定义的useLazyData中的result}else {nextTick(() {newData.value { ...unref(newData), end_time: }emits(update, unref(newData))updateLoadedData() //更新已经加载的数据})return }
})function dateFormat(date: any) {//转变导出报表记录日期格式if (date undefined || date 0) {return }return moment(date * 1000).format(YYYY-MM-DD HH:mm:ss)
}//更新已经加载的数据isLoaded: true,存入状态机
function updateLoadedData() {let bbarr cloneDeep(store.state.loadedTestData)bbarr.push({ ...unref(newData), isLoaded: true })store.commit(LOADED_TEST_DATA,bbarr)
}const { target, result, stopObserver } useLazyData(getDeadline)
//监听穿入子组件的props数据
watch(modelValue,newValue {let originArr cloneDeep(store.state.loadedTestData)if (originArr.length 0) {// 停止观察已经加载的节点const hasSameId originArr.some(item item.id unref(modelValue)?.id item.isLoaded)if (hasSameId) {stopObserver()const item originArr.find(item item.id unref(modelValue)?.id item.isLoaded)newData.value.end_time formateEndTime(item.end_time)//重新赋值为原来的数据} } },{ deep: true, immediate: true }
)
父组件 vxe-column:keyindexv-bind.synccolumn:fieldcolumn.prop:titlecolumn.labelwidthitem.minWidthshow-overflow:formattercolumn.prop test_state ? formatTestState : null:sortablecolumn.prop ! end_timev-ifcolumn.checkedtemplate v-else-ifcolumn.prop end_time #default{ row }!-- battary-loading :end-timerow.end_time :model-value.syncrow :class[endTimeClass, endTimeBreathLight(row.end_time)]/battary-loading --battary-loading :end-timerow.end_time :model-value.syncrow updategetTableRow/battary-loading/templatevxe-column///在nMounted里面重置为[]onMounted(() {store.commit(LOADED_TEST_DATA,[])
})
//如果有分页可在分页事件中将OADED_TEST_DATA重新置为空数组