当前位置: 首页 > news >正文

【组件封装】uniapp vue3 封装一个自定义下拉刷新组件pullRefresh,带刷新时间和加载动画教程

文章目录

  • 前言
  • 一、实现原理
  • 二、组件样式和功能设计
  • 三、scroll-view 自定义下拉刷新使用回顾
    • 相关属性:
    • 最终版完整代码:


前言

手把手教你封装一个移动端 自定义下拉刷新组件带更新时间和加载动画(PullRefresh),以uniapp vue3为代码示例。

在这里插入图片描述

请添加图片描述

在这里插入图片描述


一、实现原理

基于系统自带组件scroll-view封装,开启组件refresher-enabled属性支持自定义下拉刷新功能。下拉自定义UI容器默认状态下位于页面顶部外不可视区域,下拉时候自定义区域进入页面显示。并通过多个自定义下拉刷新回调函数refresherpulling、refresherrefresh、refresherrestore进行逻辑和UI控制。

二、组件样式和功能设计

请添加图片描述
1、如上述动图所示,下拉未达到阈值提示文字显示下拉可以刷新,到达或超过阈值显示释放立即刷新
2、释放后进入刷新状态,提示文字显示正在刷新,左边出现加载转圈动画,下拉区域卡住不动
3、数据刷新完成后设置更新时间,恢复到初始状态,再次下拉会显示上次更新时间

三、scroll-view 自定义下拉刷新使用回顾

相关属性:

属性名类型默认值说明
refresher-enabledBooleanfalse开启自定义下拉刷新
refresher-thresholdNumber45(单位px)设置自定义下拉刷新阈值
refresher-default-styleString“black”设置自定义下拉刷新默认样式,支持设置 black,white,none,none 表示不使用默认样式
refresher-backgroundString“#FFF”设置自定义下拉刷新区域背景颜色
refresher-triggeredBooleanfalse设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
@refresherpullingEventHandle自定义下拉刷新控件被下拉
@refresherrefreshEventHandle自定义下拉刷新被触发
@refresherrestoreEventHandle自定义下拉刷新被复位

上面比较重要一个关系就是下拉松手那一刻下拉高度大于或等于refresher-threshold时(刷新阈值)会触发刷新事件@refresherrefresh

refresher-enabled用来控制下拉区域是否复位,当值从true转变为false才能复位。

分析下拉过程属性值变化和回调函数的触发时机:

1、初始状态refresher-triggered=false
2、 开始下拉@refresherpulling一直持续被触发,下拉松手那一刻当下拉距离大于或等于refresher-threshold(刷新阈值)时,@refresherrefresh 被触发一次,此时设置refresher-triggered=true,下拉区域卡住不复位进入加载中状态,数据加载完成设置refresher-triggered=false,下拉复位,触发@refresherrestore。

按上面描述我们很容易实现一个自定义下拉刷新简易版如下:

pullRefresh.vue

<template><view class="pull-refresh"><scroll-view style="height: 100%;" scroll-y refresher-enabled refresher-default-style="none"refresher-background="#ffffff" :refresher-threshold="threshold" :refresher-triggered="loading"@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"@refresherrestore="onRefresherrestore" ><view class="main"><!-- 下拉提示内容 --><view class="content" :style="{top:`-${threshold}px`,height:`${threshold}px`}"><view class="tip-view"><view class="text">{{tipText}}</view></view></view></view></scroll-view></view>
</template><script setup>import {ref} from 'vue'//拉刷新阈值const threshold=ref(80)//是否正在刷新(加载数据)const loading = ref(false)//提示文字const tipText = ref('下拉可以刷新')//控件被下拉触发回调const onRefresherpulling = (e) => {console.log(e,'正在下拉')}//下拉刷新被触发回调const onRefresherrefresh = (e) => {loading.value=true;tipText.value="正在刷新..."//模拟接口请求数据setTimeout(()=>{loading.value=false uni.showToast({title:'刷新成功',icon:'none'})},1000)}//下拉刷新被复位回调const onRefresherrestore = () => {tipText.value = "下拉可以刷新"}</script><style lang="scss" scoped>.pull-refresh {height: 100vh;width: 100%;position: relative;}.main {position: relative;}.content {width: 100%;display: flex;align-items: center;justify-content: center;position: absolute;top: -80px;height: 80px;color: #000;z-index: 999;padding-bottom: 15px;box-sizing: border-box;.arrow {width: 45rpx;height: auto;}.tip-view {width: 10em;display: flex;font-size: 22rpx;flex-direction: column;align-items: center;margin-left: 20rpx;.text {font-size: 28rpx;color: #666;}}}</style>

运行效果:
请添加图片描述

通过运行效果可以看出除了图标、加载动画、更新时间外,和我们设想的效果最关键的区别在于释放刷新这个状态实现,组件无提供此状态,此时需要我们自己判断定义出来。

我们打印下来下拉刷新控件被下拉回调函数的参数

	//控件被下拉触发回调const onRefresherpulling = (e) => {console.log(e,'下拉触发')}

小程序端:
在这里插入图片描述
H5或APP:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3051ac201bdc4ba395b784f56521f24a.png

可以看到下拉过程中该回调一直被触发,小程序端内部有个dy字段而H5或APP端却变成了deltaY,dy或deltaY就是我们下拉区域的高度(单位px),当这个值大于等于下拉刷新阈值( refresher-threshold)将触发下拉刷新回调(@refresherrefresh)

所以是否达到释放立即刷新这个状态就很容易判断,也即dy或deltaY>=refresher-threshold进入释放立即刷新状态

	//控件被下拉触发回调const onRefresherpulling = (e) => {//微信小程dy字段,H5和app deltaY字段//#ifdef H5||APPif (e.detail.deltaY >= threshold ) {tipText.value = props.loosingText || "释放立即刷新"}// #endif//#ifndef H5||APPif (e.detail.dy >= threshold) {tipText.value = props.loosingText || "释放立即刷新"}// #endif		else {tipText.value = props.pullingText || "下拉可以刷新"}}

为了更好控制下拉区域图标和文字我们定义3中状态:

/*** 状态:0:下拉状态 1:可释放刷新状态 2:正在刷新状态*/const status = ref(0)

通过不同状态来改变UI和执行逻辑。

完整代码如下:
pullRefresh.vue

<template><view class="pull-refresh"><scroll-view style="height: 100%;" scroll-y refresher-enabled refresher-default-style="none"refresher-background="#ffffff" :refresher-threshold="threshold" :refresher-triggered="loading"@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"@refresherrestore="onRefresherrestore" @scrolltolower="onScrolltolower"><view class="main"><!-- 下拉提示内容 --><view class="content" :style="{top:`-${threshold}px`,height:`${threshold}px`}"><!-- 下拉或可释放状态 --><image v-if="status<2" class="arrow":src="status===0 ? '/static/arrow_down.png':'/static/arrow_up.png'" mode="widthFix"></image><!-- 正在刷新中 --><image v-else-if="status==2" class="arrow loading" src="/static/loading.png" mode="widthFix"></image><view class="tip-view"><view :class="['text',{start:!updateTime}]">{{tipText}}</view><view v-if="updateTime" class="update-time">上次更新 {{updateTime}}</view></view></view><slot></slot></view></scroll-view></view>
</template><script setup>import {ref,nextTick,computed} from 'vue'const props = defineProps({//下拉刷新阈值threshold: {type: Number,default: 80},//下拉刷新接口方法,cb:接口请求完成回调refreshMethod: {type: Function,default: cb => cb()},//下拉过程文案pullingText: {type: String,default: '下拉可以刷新'},//释放过程文案loosingText: {type: String,default: '释放立即刷新'},//刷新中文案loadingText: {type: String,default: '正在刷新...'},})const emits = defineEmits(['scrolltolower'])//是否正在刷新(加载数据)const loading = ref(false)/*** 状态:0:下拉状态 1:可释放刷新状态 2:正在刷新状态*/const status = ref(0)//提示文字const tipText = computed(()=>{let tips={0:props.pullingText,1:props.loosingText,2:props.loadingText}return tips[status.value]||props.pullingText})//上一次刷新时间const updateTime = ref('')//控件被下拉触发回调const onRefresherpulling = (e) => {//微信小程dy字段,H5和app deltaY字段//#ifdef H5||APPif (e.detail.deltaY >= props.threshold ) {status.value = 1}// #endif//#ifndef H5||APPif (e.detail.dy >= props.threshold) {status.value = 1}// #endifelse {status.value = 0}}//下拉刷新被触发回调const onRefresherrefresh = (e) => {//到达下拉阈值刷新数据if (status.value === 1) {loading.value = truestatus.value = 2;//接口获取数据props.refreshMethod(() => {nextTick(() => {uni.showToast({title: '刷新成功',icon: 'none'})updateTime.value = formatDateTime()loading.value = false})})}}//下拉刷新被复位回调const onRefresherrestore = () => {status.value = 0}//获取当前日期时间const formatDateTime = () => {let date = new Date()let month = (date.getMonth() + 1).toString().padStart(2, '0')let day = date.getDate().toString().padStart(2, '0')let hour = date.getHours().toString().padStart(2, '0')let minus = date.getMinutes().toString().padStart(2, '0')let second = date.getSeconds().toString().padStart(2, '0')return `${month}-${day} ${hour}:${minus}`}//触底const onScrolltolower = () => {emits('scrolltolower')}
</script><style lang="scss" scoped>.pull-refresh {height: 100%;width: 100%;position: relative;}.main {position: relative;}.content {width: 100%;display: flex;align-items: center;justify-content: center;position: absolute;top: -80px;height: 80px;color: #000;z-index: 999;padding-bottom: 15px;box-sizing: border-box;.arrow {width: 45rpx;height: auto;&.loading {animation: loadingFrames 1s linear infinite;}}.tip-view {width: 10em;display: flex;font-size: 22rpx;flex-direction: column;align-items: center;margin-left: 20rpx;.text {font-size: 28rpx;color: #666;&.start{align-self: flex-start;}}.update-time {font-size: 22rpx;margin-top: 10rpx;color: #808080;}}}@keyframes loadingFrames {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}
</style>

页面调用:
index.vue

<template><view class="container"><PullRefresh :threshold="80"  :refreshMethod="getData" @scrolltolower="handleScrolltolower"><view class="item" v-for="(item,index) in 20">{{item}}</view></PullRefresh></view>
</template><script setup>import PullRefresh from '@/components/pullRefresh.vue';/*** 获取数据* cb:接口数据获取完成回调函数*/const getData=(cb)=>{//模拟接口请求数据setTimeout(()=>{cb()},2000)}//触底回调const handleScrolltolower=()=>{console.log('触底')}</script><style lang="scss" scoped>.container {height: 100vh;background-color: #f2f2f2;}.item {height: 90rpx;line-height: 90rpx;text-align: center;margin-top: 20rpx;}
</style>

说明:为了让用户自定义文字,我们提供了各种状态下的文案属性设置,下拉刷新阈值也暴露属性threshold给用户自定义,同时还定义了refreshMethod属性用来控制接口获取刷新数据是否完成,该属性是一个方法内部写入从接口获取刷新数据逻辑,入参cb是个回调函数,刷新数据获取完成调用回调函数组件即可复位。组件高度默认100%继承父容器,内部默认插槽可添加页面内容。

ps:scrollView组件外层必须设置高度或最大高度才能保证自定义下拉刷新或者滚动触底功能正常

在小程序端运行:
请添加图片描述

H5或APP运行:

请添加图片描述

从运行效果看出小程序运行正常,而H5或APP端存在bug,当下拉区域较长时正常,当下拉区域较短(刚处于立即释放刷新状态)就放开手指会出现异常,组件不进入刷新状态。

查阅uniapp官方文档,官方文档对下拉回调参数都是轻描淡写,没写详细,通过多次试验测试,发现当中的猫腻,原来是下拉触发回调@refresherpulling返回的当前下拉区域高度值deltaY在这2端是不准确的,经过测试发现跟实际误差10px左右(多了10px),因此判断这2端是否到达阈值需要减去10

	//控件被下拉触发回调const onRefresherpulling = (e) => {console.log(e,'e')//微信小程dy字段,H5和app deltaY字段//#ifdef H5||APP//H5或APP端值判断是否到达阈值需要额外加10if (e.detail.deltaY-10 >= props.threshold ) {status.value = 1}// #endif//#ifndef H5||APPif (e.detail.dy >= props.threshold) {status.value = 1}// #endifelse {status.value = 0}}

最终版完整代码:

pullRefresh.vue(自定义下拉刷新组件)

<template><view class="pull-refresh"><scroll-view style="height: 100%;" scroll-y refresher-enabled refresher-default-style="none"refresher-background="#ffffff" :refresher-threshold="threshold" :refresher-triggered="loading"@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"@refresherrestore="onRefresherrestore" @scrolltolower="onScrolltolower"><view class="main"><!-- 下拉提示内容 --><view class="content" :style="{top:`-${threshold}px`,height:`${threshold}px`}"><!-- 下拉或可释放状态 --><image v-if="status<2" class="arrow":src="status===0 ? '/static/arrow_down.png':'/static/arrow_up.png'" mode="widthFix"></image><!-- 正在刷新中 --><image v-else-if="status==2" class="arrow loading" src="/static/loading.png" mode="widthFix"></image><view class="tip-view"><view :class="['text',{start:!updateTime}]">{{tipText}}</view><view v-if="updateTime" class="update-time">上次更新 {{updateTime}}</view></view></view><slot></slot></view></scroll-view></view>
</template><script setup>import {ref,nextTick,computed} from 'vue'const props = defineProps({//下拉刷新阈值threshold: {type: Number,default: 80},//下拉刷新接口方法,cb:接口请求完成回调refreshMethod: {type: Function,default: cb => cb()},//下拉过程文案pullingText: {type: String,default: '下拉可以刷新'},//释放过程文案loosingText: {type: String,default: '释放立即刷新'},//刷新中文案loadingText: {type: String,default: '正在刷新...'},})const emits = defineEmits(['scrolltolower'])//是否正在刷新(加载数据)const loading = ref(false)/*** 状态:0:下拉状态 1:可释放刷新状态 2:正在刷新状态*/const status = ref(0)//提示文字const tipText = computed(()=>{let tips={0:props.pullingText,1:props.loosingText,2:props.loadingText}return tips[status.value]||props.pullingText})//上一次刷新时间const updateTime = ref('')//控件被下拉触发回调const onRefresherpulling = (e) => {//微信小程dy字段,H5和app deltaY字段//#ifdef H5||APP//H5或APP端值判断是否到达阈值需要额外加10if (e.detail.deltaY-10 >= props.threshold ) {status.value = 1}// #endif//#ifndef H5||APPif (e.detail.dy >= props.threshold) {status.value = 1}// #endifelse {status.value = 0}}//下拉刷新被触发回调const onRefresherrefresh = (e) => {//到达下拉阈值刷新数据if (status.value === 1) {loading.value = truestatus.value = 2;//接口获取数据props.refreshMethod(() => {nextTick(() => {uni.showToast({title: '刷新成功',icon: 'none'})updateTime.value = formatDateTime()loading.value = false})})}//发现误差在1左右未到达下拉刷新阈值H5或APP也会触发,兼容处理恢复初态else {loading.value = falsestatus.value = 0}}//下拉刷新被复位回调const onRefresherrestore = () => {status.value = 0}//获取当前日期时间const formatDateTime = () => {let date = new Date()let month = (date.getMonth() + 1).toString().padStart(2, '0')let day = date.getDate().toString().padStart(2, '0')let hour = date.getHours().toString().padStart(2, '0')let minus = date.getMinutes().toString().padStart(2, '0')let second = date.getSeconds().toString().padStart(2, '0')return `${month}-${day} ${hour}:${minus}`}//触底const onScrolltolower = () => {emits('scrolltolower')}
</script><style lang="scss" scoped>.pull-refresh {height: 100%;width: 100%;position: relative;}.main {position: relative;}.content {width: 100%;display: flex;align-items: center;justify-content: center;position: absolute;top: -80px;height: 80px;color: #000;z-index: 999;padding-bottom: 15px;box-sizing: border-box;.arrow {width: 45rpx;height: auto;&.loading {animation: loadingFrames 1s linear infinite;}}.tip-view {width: 10em;display: flex;font-size: 22rpx;flex-direction: column;align-items: center;margin-left: 20rpx;.text {font-size: 28rpx;color: #666;&.start{align-self: flex-start;}}.update-time {font-size: 22rpx;margin-top: 10rpx;color: #808080;}}}@keyframes loadingFrames {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}
</style>

页面调用:

<template><view class="container"><PullRefresh :threshold="80" :refreshMethod="getData" @scrolltolower="handleScrolltolower"><view class="item" v-for="(item,index) in 20">{{item}}</view></PullRefresh></view>
</template><script setup>import PullRefresh from '@/components/pullRefresh.vue';/*** 获取数据* cb:接口数据获取完成回调函数*/const getData=(cb)=>{//模拟接口请求数据setTimeout(()=>{cb()},2000)}//触底回调const handleScrolltolower=()=>{console.log('触底')}</script><style lang="scss" scoped>.container {height: 100vh;background-color: #f2f2f2;}.item {height: 90rpx;line-height: 90rpx;text-align: center;margin-top: 20rpx;}
</style>

H5或APP端运行效果:
请添加图片描述

相关文章:

【组件封装】uniapp vue3 封装一个自定义下拉刷新组件pullRefresh,带刷新时间和加载动画教程

文章目录 前言一、实现原理二、组件样式和功能设计三、scroll-view 自定义下拉刷新使用回顾相关属性&#xff1a;最终版完整代码&#xff1a; 前言 手把手教你封装一个移动端 自定义下拉刷新组件带更新时间和加载动画&#xff08;PullRefresh&#xff09;&#xff0c;以uniapp …...

通过 JNI 实现 Java 与 Rust 的 Channel 消息传递

做纯粹的自己。“你要搞清楚自己人生的剧本——不是父母的续集&#xff0c;不是子女的前传&#xff0c;更不是朋友的外篇。对待生命你不妨再大胆一点&#xff0c;因为你好歹要失去它。如果这世上真有奇迹&#xff0c;那只是努力的另一个名字”。 一、crossbeam_channel 参考 cr…...

一起学习Fortran:如何安装Fortran

Fortran&#xff08;全称Formula Translation&#xff0c;意为“公式翻译”&#xff09;是一种通用编译命令式编程语言&#xff0c;适用于数值计算和科学计算。Fortran语言最初是由IBM在20世纪50年代为科学和工程应用程序而开发的&#xff0c;第一个Fortran版本——FORTRAN I在…...

社交新零售模式下“2+1 链动模式 S2B2C 商城小程序”的创新实践与发展策略

摘要&#xff1a;随着实体商业与社交网络深度融合&#xff0c;社交新零售蓬勃兴起&#xff0c;“21 链动模式 S2B2C 商城小程序”作为其中创新典范&#xff0c;融合独特激励机制与数字化运营优势&#xff0c;重塑零售生态。本文剖析该模式架构、运作逻辑&#xff0c;探讨其在私…...

【博主推荐】C# Winform 拼图小游戏源码详解(附源码)

文章目录 前言摘要1.设计来源拼图小游戏讲解1.1 拼图主界面设计1.2 一般难度拼图效果1.3 普通难度拼图效果1.4 困难难度拼图效果1.5 地域难度拼图效果1.6 内置五种拼图效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载结束语 前言 在数字浪潮汹涌澎湃的时代&#xff0c;程序开…...

贝叶斯统计的核心思想与基础知识:中英双语

中文版 贝叶斯统计的核心思想与基础知识 贝叶斯统计是以贝叶斯定理为核心&#xff0c;通过将先验知识和观测数据相结合&#xff0c;更新对参数或模型的认知的一种统计方法。它不仅强调概率的频率解释&#xff08;频率统计学中概率描述事件的长期发生频率&#xff09;&#xf…...

Verilog使用liberty文件中cell单元的demo

Liberty&#xff08;.lib&#xff09;文件是用来描述标准单元库中逻辑单元&#xff08;如门电路、触发器等&#xff09;的时序和功耗特性的&#xff0c;不是用来直接定义Verilog中的元件。在Verilog设计中&#xff0c;我们通常通过实例化模块&#xff08;module&#xff09;来创…...

openssl生成ca证书

常见CA文件夹 1、生成CA钥匙 openssl genrsa -out ./private/cakey.pem 2、生成CA自签名 openssl req -new -x509 -key ./private/cakey.pem -out ./cacert.crt -days 3650 3、生成http服务器私钥 openssl genrsa -out ./data/frontt.project.com.key 2048 4、CA给http服务器…...

OGRE 3D----2. QGRE + QQuickView

将 OGRE(面向对象图形渲染引擎)集成到使用 QQuickView 的 Qt Quick 应用程序中,可以在现代灵活的 UI 框架中提供强大的 3D 渲染功能。本文将指导您如何在 QQuickView 环境中设置 OGRE。 前提条件 在开始之前,请确保您已安装以下内容: Qt(版本 5.15 )OGRE(版本14.2.5)…...

【Java 学习】面向程序的三大特性:封装、继承、多态

引言 1. 封装1.1 什么是封装呢&#xff1f;1.2 访问限定符1.3 使用封装 2. 继承2.1 为什么要有继承&#xff1f;2.2 继承的概念2.3 继承的语法2.4 访问父类成员2.4.1 子类中访问父类成员的变量2.4.2 访问父类的成员方法 2.5 super关键字2.6 子类的构造方法 3. 多态3.1 多态的概…...

Online Judge——【前端项目初始化】Vue-CLI初始化项目、组件库引入

目录 一、创建项目二、前端工程化配置三、引入组件 一、创建项目 输入命令&#xff1a;vue create oj-frontend来到如下界面&#xff1a; 选择Manually select features 选择如下图的组件&#xff1a;注意空格是选择&#xff0c;之后回车即可。 选择3.x版本 继续选择&#xff…...

ASP.NET Web(.Net Framework)POST无法正常接收数据

ASP.NET Web&#xff08;.Net Framework&#xff09;POST无法正常接收数据 介绍站点Post和Get如何打断点测试测试代码如下服务器站点Post方法修改原因总结 总结 介绍 这一篇文章主要是讲一下之前搭建的HTTP站点POST无法正常接收数据&#xff0c;如果还不知道怎么搭建HTTP站点的…...

vue安装cypress及其部分用法

安装Cypress 在vue中安装Cypress 1. 安装 Cypress 首先&#xff0c;确保你已经安装了 Cypress。在你的 Vue 项目根目录下运行以下命令&#xff1a; npm install cypress --save-dev2. 打开 Cypress 安装完 Cypress 后&#xff0c;可以通过以下命令打开 Cypress 测试界面&a…...

Web Worker 入门:让前端应用多线程化

引出&#xff1a; 作为前端切图仔&#xff0c;在之前的工作中一直都是写后台&#xff0c;没机会用到web Worker&#xff0c;传统的性能优化web Worker用到的场景也很少&#xff0c;毕竟大量的数据计算一般直接给后端去做就行&#xff0c;轮不到前端来考虑&#xff08;没遇到类似…...

Vue+Elementui el-tree树只能选择子节点并且支持检索

效果&#xff1a; 只能选择子节点 添加配置添加检索代码 源码&#xff1a; <template><div><el-button size"small" type"primary" clearable :disabled"disabled" click"showSign">危险点评估</el-button>…...

MySQL各种问题的原因及解决方案梳理

背景&#xff1a;由于最近一直在做生产环境和测试环境的切换&#xff0c;遇到了各种各样的MySQL问题&#xff0c;为了后面的开发顺利&#xff0c;梳理一下MySQL的报错及解决方案 问题1、MySQL的链接数超过了本身MySQL内部设置的链接限制 报错信息&#xff1a; // An highlig…...

LeetCode—74. 搜索二维矩阵(中等)

仅供个人学习使用 题目描述&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true…...

【Redis】Redis介绍

目录 1.Redis是什么? 2. Redis特性 2.1 速度快 2.2 基于键值对的数据结构服务器 2.3 丰富的功能 2.4 简单稳定 2.5 客户端语言多 2.6 持久化 2.7 主从复制 2.8 高可用和分布式 3. Redis使用场景 3.1 缓存(Cache) 3.2 排行榜系统 3.3 计数器应用 3.4 社交网络 …...

Python 3 教程第23篇(模块)

Python3 模块 在前面的几个章节中我们基本上是用 python 解释器来编程&#xff0c;如果你从 Python 解释器退出再进入&#xff0c;那么你定义的所有的方法和变量就都消失了。 为此 Python 提供了一个办法&#xff0c;把这些定义存放在文件中&#xff0c;为一些脚本或者交互式…...

课题组自主发展了哪些CMAQ模式预报相关的改进技术?

空气污染问题日益受到各级政府以及社会公众的高度重视&#xff0c;从实时的数据监测公布到空气质量数值预报及预报产品的发布&#xff0c;我国在空气质量监测和预报方面取得了一定进展。随着计算机技术的高速发展、空气污染监测手段的提高和人们对大气物理化学过程认识的深入&a…...

七牛云AIGC内容安全方案助力企业合规创新

随着人工智能生成内容(AIGC)技术的飞速发展,内容审核的难度也随之急剧上升。在传统审核场景中,涉及色情、政治、恐怖主义等内容的标准相对清晰明确,但在AIGC的应用场景中,这些界限变得模糊且难以界定。用户可能通过交互性引导AI生成违规内容,为审核工作带来了前所未有的不可预测…...

Vue.js 中的事件处理

在 Vue.js 中&#xff0c;事件处理是用户与应用交互的重要方式。Vue.js 允许开发者以一种声明式的方式来绑定事件监听器&#xff0c;这使得代码更加简洁和易于维护。本文将介绍 Vue.js 中的事件处理&#xff0c;包括常用的事件类型和如何使用它们。 Vue.js 事件基础 在 Vue.j…...

Windows用pm2部署node.js项目

Windows上pm2启动命令不生效 按照常规启动命令应该如下&#xff0c;但是发现不生效 pm2 start npm --name "project-name" -- start具体如下&#xff0c;可以看到状态都是stopped $ pm2 start npm --name "chatgpt-next-web" -- start [PM2] Starting …...

算法【Java】—— 动态规划之路径问题

前言 本文章终点解析第一道题目【不同路径】和最后一道题目【地下城游戏】的动态规划思路&#xff0c;中间几道题目会很快过完&#xff0c;大家如果不熟悉动态规划的思路可以重点看一下这两道题目的解析。 不同路径 https://leetcode.cn/problems/unique-paths 解析&#xf…...

DreamFace4.9.0 |AI照片动画师,让照片说话和跳舞

DreamFace是一款有趣的照片动画应用程序&#xff0c;通过AI技术让您的照片唱歌、跳舞甚至说话。只需上传照片并选择歌曲&#xff0c;即可生成动态效果。此外&#xff0c;它还支持图片增强、降噪和高清处理&#xff0c;创建人工智能驱动的头像。无论是让宠物说话还是让朋友唱情歌…...

vue-baidu-map基本使用

vue-baidu-map 是一个基于 Vue.js 的百度地图组件库&#xff0c;它封装了百度地图的 JavaScript API&#xff0c;使得在 Vue 项目中使用百度地图功能更加便捷。下面是如何在 Vue 项目中安装和使用 vue-baidu-map 的步骤&#xff1a; 安装 首先确保你的项目已经集成了 Vue 和 …...

新电脑验机-允许上网,同时禁止windows系统联网自动激活

效果&#xff1a; 重要提示&#xff1a;我虽然得到上图效果&#xff0c;但也不确定是否有坑&#xff0c;不保证商家是否认可。 笔记本电脑七天无理由退货的前提条件是“windows和office未激活”。如何 oobe\bypassnor 绕过开机联网并创建本地账号的方法我就不写了&#xff0c;搜…...

Android 是否支持AB分区

Android 是否支持AB分区 C:\Users\Administrator>adb shell bengal:/ $ su bengal:/ # getprop |grep treble [ro.treble.enabled]: [true] bengal:/ #返回不为空而且为true&#xff0c;那就是支持pt(project treble)分区 进入fastboot模式 adb reboot bootloader查看当前…...

Qt6.8安卓Android开发环境配置

时隔多年&#xff0c;重拾QtCreator下Android开发。发现Qt6下安卓开发环境配置变简单不少&#xff01;只需三步即可在QtCreator下进行Android开发&#xff1a; 一、使用Qt Mantenance Tool进行Android模块的安装&#xff1a; 如果感觉安装网速较慢&#xff0c;可以查看本人另外…...

JavaSE——类与对象(4)

一、静态变量 1.1为什么要有静态变量 现在有一群小朋友在做游戏&#xff0c;不是有新的小朋友加入&#xff0c;请问如何知道现在共有多少人在完&#xff1f;看这段代码&#xff1a; public class first {public static void main(String[] args) {int count 0;child child1 …...

网络编程中的字节序函数htonl()、htons()、ntohl()和ntohs()

目录 1&#xff0c;网络字节序和主机字节序 2. 函数的具体作用 2.1,htonl&#xff08;Host to Network Long&#xff09; 2.2,htons&#xff08;Host to Network Short) 2.3,ntohl&#xff08;Network to Host Long&#xff09; 2.4,ntohs&#xff08;Network to Host Sho…...

如何在HarmonyOS NEXT中处理页面间的数据传递?

大家好&#xff0c;前两天的Mate70的发布&#xff0c;让人热血沸腾啊&#xff0c;不想错过&#xff0c;自学的小伙伴一起啊&#xff0c;今天分享的学习笔记是关于页面间数据伟递的问题&#xff0c;在HarmonyOS NEXT 5.0 中&#xff0c;页面间的数据传递可以有很多种方式&#x…...

【Code First】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列 &#x1f…...

Day28 贪心算法 part02

122.买卖股票的最佳时机II 本题解法很巧妙,本题大家可以先自己思考一下然后再看题解,会有惊喜! class Solution {public int maxProfit(int[] prices) {//分析每一天的情况。只要保证今天买,明天卖可以不亏钱,那就是最大的利润。把每一天可以赚钱的机会都不放过,先把能挣…...

JVM_栈详解一

1、栈的存储单位 **栈中存储什么&#xff1f;**&#xff0c; 每个线程都有自己的栈&#xff0c;栈中的数据都是以栈帧&#xff08;Stack Frame&#xff09;的格式存在。在这个线程上正在执行的每个方法都各自对应一个栈帧&#xff08;Stack Frame&#xff09;。 栈帧是一个内存…...

深入浅出UART驱动开发与调试:从基础调试到虚拟驱动实现

往期内容 本专栏往期内容&#xff1a;Uart子系统 UART串口硬件介绍深入理解TTY体系&#xff1a;设备节点与驱动程序框架详解Linux串口应用编程&#xff1a;从UART到GPS模块及字符设备驱动 解UART 子系统&#xff1a;Linux Kernel 4.9.88 中的核心结构体与设计详解IMX 平台UART驱…...

集成量子光子学(IQP)

IQP 正在成为量子计算的可行替代方案量子源、波导和调制器等领域的研究使这成为可能与 CMOS 技术的兼容意味着工业可扩展性将更加容易 量子光子学的基本组成部分 IQP 系统的基本组成部分包括&#xff1a; 来源&#xff08;例如腔体中的 QD&#xff09; 波导定向耦合器&#…...

【代码随想录|贪心算法02】

122.买股票的最佳时机 题目链接https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii 好巧妙的一道题啊&#xff0c;做之前完全不会想到这种解法。 局部最优&#xff1a;收集每天正利润 全局最优&#xff1a;求得最大利润 这道题只让你返回最大的利润和&…...

CentOS7 使用xtrabackup备份及恢复

安装备份工具 1.安装Percona yum存储库 sudo yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm安装过程中需要按y继续安装 2.启用Percona Server 5.7存储库 sudo percona-release setup ps573、安装percona-xtrabackup-24 sudo yum -y instal…...

【网络安全设备系列】12、态势感知

0x00 定义&#xff1a; 态势感知&#xff08;Situation Awareness&#xff0c;SA&#xff09;能够检测出超过20大类的云上安全风险&#xff0c;包括DDoS攻击、暴力破解、Web攻击、后门木马、僵尸主机、异常行为、漏洞攻击、命令与控制等。利用大数据分析技术&#xff0c;态势感…...

VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)

本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu &#xff08;1&#xff09;安装增强功能&#xff08;Guest Additions&#xff09; 首先&#xff0c;在网上下载VBoxGuestAdditions光盘映像文件 下载地址&#xff1a;Index of http://…...

【docker集群应用】Docker--harbor私有仓库部署与管理

文章目录 Harbor特性Harbor构成Harbor部署与管理Harbor 部署实例环境准备1. 部署 Docker-Compose 服务2. 部署 Harbor 服务(1) 下载并解压 Harbor 安装程序(2) 修改 Harbor 配置文件 3. 启动 Harbor4. 查看 Harbor 启动镜像5. 创建一个新项目6. 在其他客户端上传镜像 维护管理 …...

【优选算法】位运算

目录 常见位运算总结1、基础位运算2、给一个数n&#xff0c;确定它的二进制位的第x位上是0还是13、将一个数n的二进制位的第x位改成14、将一个数n的二进制位的第x位改成05、位图的思想6、提取一个数n的二进制位中最右侧的17、将一个数n的二进制位中最右侧的1变为08、位运算的优…...

2.mybatis整体配置

文章目录 mybatis-config.xml介绍SqlSessionFactoryBuilderXMLConfigBuilderpropertiessetting类型别名&#xff08;typeAliases&#xff09;扫描插件(plugins)解析objectFactory(对象工厂)解析objectWrapperFactory解析reflectorFactorysettingsElement()方法环境配置&#xf…...

js中判断数组和判断对象的方法

判断数组 Array.isArray() 方法 这是最推荐的方法&#xff0c;简单明了。它可以检测数组的情况&#xff0c;并且不会误报其他类型。 const arr [1, 2, 3]; console.log(Array.isArray(arr)); // trueconst notArray { key: value }; console.log(Array.isArray(notArray))…...

【godot】如何立刻(实时)进行碰撞检测?

因为最近在做帧同步方面的内容&#xff0c;所以发现了这个问题。 方案1&#xff1a;用Area2d进行碰撞检测&#xff0c;绑定body_entered信号。 缺陷&#xff1a; Area2d的碰撞检测只会每个物理迭代中只会执行一次&#xff0c;即在physics_process()结束后执行一次。 场景&a…...

讨论JAVA、JVM与Spring

Q1: 作为一个JAVA开发人员&#xff0c;对于jvm肯定不陌生&#xff0c;但很多人对它不陌生也仅止于概念上&#xff0c;而且对概念也是模糊不清的&#xff0c;但jvm实际是java程序运行在其中的实际存在的环境&#xff0c;对它的理解应该要是具象化的。 我们还是从一项技术产生的…...

基于SpringBoot实现的民宿管理系统(代码+论文)

&#x1f389;博主介绍&#xff1a;Java领域优质创作者&#xff0c;阿里云博客专家&#xff0c;计算机毕设实战导师。专注Java项目实战、毕设定制/协助 &#x1f4e2;主要服务内容&#xff1a;选题定题、开题报告、任务书、程序开发、项目定制、论文辅导 &#x1f496;精彩专栏…...

vue2 - 22.vant 组件库

vant 组件库 vant2下载&#xff1a; npm i vantlatest-v2 --legacy-peer-deps 目标&#xff1a;认识第三方 Vue组件库 vant-ui 组件库&#xff1a;第三方 封装 好了很多很多的 组件&#xff0c;整合到一起就是一个组件库。 https://vant-contrib.gitee.io/vant/v2/#/zh-CN…...

Git简单介绍

一、 Git介绍与安装 1.1 Git简介 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 1.2集中式(SVN&#xff09; VS 分布式(git) 集中式版本控制系统&#xff0c;版本库是集中存放在中央服务器的&#xff0c;工作时要先从中央…...