vue3 实现一个下拉刷新

news/2025/2/1 11:58:13/

1. 实现最简单的下拉刷新雏形


<template><div class="wrap" ref="freshcontainer" @touchstart="handlerstart"  @touchmove="handlermove" @touchend="handlerend"><div  class="fresh_txt"  v-if="moveDistance>0">释放即可刷新</div><slot></slot></div></template><script setup>
import { ref } from "vue";
const startLocation = ref(0);
const freshcontainer = ref(null);
const moveDistance = ref(0); //移动的位置const isTransition = ref(false); //移动的J距离const handlerstart = e => {startLocation.value = e.touches[0].pageY;};
const handlermove = e => {moveDistance.value = Math.floor(e.touches[0].pageY - startLocation.value);freshcontainer.value.style.transform = `translateY(${moveDistance.value}px)`;
};
const handlerend = e => {moveDistance.value = 0;isTransition.value = true;freshcontainer.value.style.transform = `translateY(0px)`;};
</script><style scoped>
.fresh_txt,
.load_txt {text-align: center;color: #ccc;
}
.ani {transition: all 0.2s;
}
</style>

2 优化体验。当手指滑动到一定距离以后禁止再继续往下滑动,同时给手指松开的时候添加动画效果,当手指抬起时,添加文本提示加载中....增强体验感


<template><div :class="[{'ani':isTransition},'wrap']" ref="freshcontainer" @touchstart="handlerstart"  @touchmove="handlermove" @touchend="handlerend"><div  class="fresh_txt"  v-if="moveDistance>0">释放即可刷新</div><div  class="load_txt"  v-if="loading">加载中...</div><slot></slot></div></template><script setup>
import { ref } from "vue";
const startLocation = ref(0);
const freshcontainer = ref(null);
const moveDistance = ref(0); //移动的位置
const loading= ref(false); //移动的位置
const isTransition = ref(false); //移动的J距离
const loading = ref(false); //移动的J距离const handlerstart = e => {startLocation.value = e.touches[0].pageY;isTransition.value = false;console.log("startLocation:", startLocation.value);
};
const handlermove = e => {moveDistance.value = Math.floor(e.touches[0].pageY - startLocation.value);// console.log("moveDistance.value:", moveDistance.value);if (moveDistance.value > 100) {moveDistance.value = 100;}freshcontainer.value.style.transform = `translateY(${moveDistance.value}px)`;
};
const handlerend = e => {moveDistance.value = 0;isTransition.value = true;
loading.value = true;freshcontainer.value.style.transform = `translateY(0px)`;};
</script><style scoped>
.fresh_txt,
.load_txt {text-align: center;color: #ccc;
}
.ani {transition: all 0.2s;
}
</style>

3 把加载中的状态单独抽离出来,在父组件中用v-model去控制。


<template><div :class="[{'ani':isTransition},'wrap']" ref="freshcontainer" @touchstart="handlerstart"  @touchmove="handlermove" @touchend="handlerend"><div  class="fresh_txt"  v-if="moveDistance>0">释放即可刷新</div><div  class="load_txt"  v-if="modelValue">加载中...</div><slot></slot></div></template><script setup>
import { ref } from "vue";
const startLocation = ref(0);
const freshcontainer = ref(null);
const moveDistance = ref(0); //移动的位置const isTransition = ref(false); //移动的J距离
const loading = ref(false); //移动的J距离
const props = defineProps({modelValue: {type: Boolean,default: false}
});
const emit = defineEmits(["update:modelValue", "refresh"]);
const handlerstart = e => {startLocation.value = e.touches[0].pageY;isTransition.value = false;console.log("startLocation:", startLocation.value);
};
const handlermove = e => {moveDistance.value = Math.floor(e.touches[0].pageY - startLocation.value);// console.log("moveDistance.value:", moveDistance.value);if (moveDistance.value > 100) {moveDistance.value = 100;}freshcontainer.value.style.transform = `translateY(${moveDistance.value}px)`;
};
const handlerend = e => {moveDistance.value = 0;isTransition.value = true;freshcontainer.value.style.transform = `translateY(0px)`;emit("update:modelValue", true);emit("refresh");
};
</script><style scoped>
.fresh_txt,
.load_txt {text-align: center;color: #ccc;
}
.ani {transition: all 0.2s;
}
</style>------------------------------------------------------------------------
//父组件中的使用<script setup>
import { ref } from "vue";import reftest from "./components/reftest.vue";
const arr = [{ id: "001", name: "标题一" },{ id: "002", name: "标题二" },{ id: "003", name: "标题三" }
];
const loading = ref(false);
const getList = () => {setTimeout(() => {loading.value = false;}, 2000);
};
</script><template><reftest v-model="loading" @refresh="getList"><div class="item" v-for="item in arr" :key="item.id">{{item.name}}</div>
</reftest ></template><style scoped>
.item {padding: 10px 0;border-bottom: 1px solid #ccc;
}
</style>

4 插件化,把该组件注册成一个全局组件。

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import refresh from "./components/reftest"const app = createApp(App)
app.component("pullRefresh", refresh)
app.use(ElementPlus)
app.config.globalProperties.cons = cons
app.mount('#app')--------------------------------------------------
//组件中使用
<script setup>
import { ref } from "vue";const arr = [{ id: "001", name: "标题一" },{ id: "002", name: "标题二" },{ id: "003", name: "标题三" }
];
const loading = ref(false);
const getList = () => {setTimeout(() => {loading.value = false;}, 2000);
};
</script><template><pullRefresh v-model="loading" @refresh="getList"><div class="item" v-for="item in arr" :key="item.id">{{item.name}}</div>
</pullRefresh><!-- <GRID></GRID> -->
</template><style scoped>
.item {padding: 10px 0;border-bottom: 1px solid #ccc;
}
</style>


http://www.ppmy.cn/news/1008789.html

相关文章

d2l 线性回归的从零开始实现

文章目录 线性回归的从零开始实现1. 构造人造数据集2. data_iter每次读取一个小批量3. 定义 初始化模型参数4. 定义模型5. 定义损失函数6. 定义优化算法7. 训练过程 线性回归的从零开始实现 导入需要使用的包数据流水线、模型、损失函数、小批量随机梯度下降器 1. 构造人造数…

MybatisPlus中的实体类中的一些注解

TableName("t_user")//假如实体类是User&#xff0c;而数据库中是t_user,使用这个注解 public class User {//TableId&#xff08;本来要传的数据是id&#xff0c;而实体类和数据表中都使用了uid&#xff09;//TableId(value "uid")&#xff08;实体类中是…

【雕爷学编程】Arduino动手做(181)---Maixduino AI开发板7

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

无涯教程-Perl - foreach 语句函数

foreach 循环遍历列表值&#xff0c;并将控制变量(var)依次设置为列表的每个元素- foreach - 语法 Perl编程语言中的 foreach 循环的语法是- foreach var (list) { ... } foreach - 流程图 foreach - 示例 #!/usr/local/bin/perllist(2, 20, 30, 40, 50);# foreach loop ex…

初阶C语言——特别详细地介绍函数

系列文章目录 第一章 “C“浒传——初识C语言&#xff08;更适合初学者体质哦&#xff01;&#xff09; 第二章 详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言——特别详细地介绍函数 目录 系列文章目录 前言 一、函数是个什么鬼东西&#xff1f; 二、C语…

【网络编程】定时器的应用:基于升序链表的定时器处理非活动连接

首先我们实现一个数据结构用来存储定时器&#xff0c;它是一个升序的双向链表。主要在其中实现了插入定时器&#xff0c;删除定时器&#xff0c;调整定时器位置的操作&#xff0c;其实现如下&#xff1a; #ifndef LST_TIMER #define LST_TIMER#include <netinet/in.h> #…

Mock.js的基本使用方法

官网网址&#xff1a;Mock.js (mockjs.com) 当前端工程师需要独立于后端并行开发时&#xff0c;后端接口还没有完成&#xff0c;那么前端怎么获取数据&#xff1f; 这时可以考虑前端搭建web server自己模拟假数据&#xff0c;这里我们选第三方库mockjs用来生成随机数据&#xf…

vue2-组件和插件的区别

1、组件是什么&#xff1f; 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念&#xff08;组件&#xff09;来实现开发的模式&#xff0c;在vue中每一个.vue文件都可以被视为一个组件。 组件的优势&#xff1a; 降低整个系统的耦合度&#xff0c;在保持接口不变的情况下…