工程目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌─uniCloud              云空间目录,支付宝小程序云为uniCloud-alipay,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─utssdk 存放uts文件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源都应存放于此目录
├─uni_modules 存放uni_module 详见
├─platforms 存放各平台专用页面的目录,详见
├─nativeplugins App原生语言插件 详见
├─nativeResources App端原生资源目录
│ ├─android Android原生资源目录 详见
| └─ios iOS原生资源目录 详见
├─hybrid App端存放本地html文件的目录,详见
├─wxcomponents 存放小程序组件的目录,详见
├─unpackage 非工程代码,一般存放运行或发行的编译结果
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
├─AndroidManifest.xml Android原生应用清单文件 详见
├─Info.plist iOS原生应用配置文件 详见
└─uni.scss 内置的常用样式变量

内置组件

view(块级元素)

类似于 div标签,会独占一行显示!

1
2
3
4
5
6
7
8
9
10
<template>
<view class="view" hover-class="view-hover" hover-start-time="50">
view box!
</view>
</template>
<style>
.view{ ... }
/* 延迟 50ms 后显示 hover-class */
.view-hover{ ... }
</style>
属性名描述
class样式类名
hover-class手势按下去时的样式类名
hover-start-time延迟显示hover-class的时间,单位ms
hover-stop-propagation阻止事件冒泡行为! 防止 点击子组件触发事件父组件的点击事件被触发!

处理冒泡行为

1
2
3
4
5
6
7
<template>
<view class="view" hover-class="view-hover" hover-start-time="50">
view box!
<!-- 子组件触发事件 防止冒泡行为! -->
<view class="view-inner-box" hover-stop-propagation></view>
</view>
</template>

hover-stop-propagation 兼容微信小程序和百度小程序,但是其他支付宝 抖音小程序等并不支持

text(行内元素)

类似于 span 标签,不会独占一行显示!

属性名描述可选值
selectable是否可被选中true/false
user-select是否可被选中(微信小程序)true/false
space显示连续空格ensp(中文空格一半) emsp(中文字符空格大小) nbsp(根据字体设置的空格大小)
decode是否解码 (百度 和 钉钉 小程序不支持)true/false
1
2
3
4
5
6
7
8
9
10
<template>
<text>
text box!
</text>
</template>
<style>
.view{ ... }
/* 延迟 50ms 后显示 hover-class */
.view-hover{ ... }
</style>

scroll-view滚动组件

可滚动视图区域。用于区域滚动。

属性名描述可选值
scroll-x允许横向滚动true/false
scroll-y允许纵向滚动true/false
scroll-top设置竖向滚动条位置Number(1)/String('1')
scroll-left设置横向滚动条位置Number(1)/String('1')
show-scrollbar是否出现滚动条true/false
refresher-enabled开启自定义刷新true/false
refresher-threshold触发下拉刷新的距离Number(1)/String('1')
enable-back-to-topiOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向true/false(app-nvue,微信小程序)
refresher-default-style下拉刷新默认样式black/white
refresher-background下拉刷新背景颜色String('#FFF')
scroll-with-animation在设置滚动条位置时使用动画过渡true/false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<view class="scroll-view-box" hover-class="scroll-view-box-hover">
scroll-view box!

<view>y</view>
<scroll-view class="scroll-view-y" scroll-y>
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
<view>5</view>
<view>6</view>
<view>7</view>
<view>8</view>
</scroll-view>
<view>x</view>
<scroll-view class="scroll-view-x" scroll-x>
<view>1</view>
<view>2</view>
<view>3</view>
<view>4</view>
<view>5</view>
<view>6</view>
<view>7</view>
<view>8</view>
</scroll-view>
</view>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.scroll-view-y, .scroll-view-x{
border: 1px solid red;
height: 80px;
margin-top: 5px;
padding: 2px;
border-radius: 5px;
}
.scroll-view-x{
// 不换行
white-space: nowrap;
view{
display: inline-block;
width: 50px;
height: 50px;
background-color: #938fff;
margin-left: 5px;
text-align: center;
line-height: 50px;
}
}
}

swiper滑块组件轮播区域

滑块视图容器。
一般用于左右滑动或上下滑动,比如banner轮播图。

属性名描述可选值
indicator-dots是否可被选中true/false
indicator-color指示点颜色rgba(0, 0, 0, .3)
indicator-active-color当前选中的指示点颜色#000000
current当前所在滑块的 indexNumber(1)/String('1')
current-item-id当前所在滑块的 item-idString('1')
autoplay是否自动切换true/false
interval自动切换时间间隔Number(1)/String('1')
duration滑动动画时长Number(1)/String('1')
circular是否采用衔接滑动,即播放到末尾后重新回到开头true/false
vertical滑动方向是否为纵向true/false
previous-margin前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值String('1')
next-margin后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值String('1')
display-multiple-items同时显示的滑块数量Number(1)/String('1')
easing-function指定 swiper 切换缓动动画类型(微信 快手 京东)default、linear、easeInCubic、easeOutCubic、easeInOutCubic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<view class="swiper-box" hover-class="swiper-box-hover">
<view> swiper 组件 </view>
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item>
<view class="swiper-item">1</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">2</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">3</view>
</swiper-item>
</swiper>
</view>

注意滑动切换和滚动的区别,滑动切换是一屏一屏的切换。`swiper`下的每个`swiper-item`是一个滑动切换区域,不能停留在2个滑动区域之间。

image 媒体组件配合swiper

属性名描述可选值
src图片地址String('1')
mode图片裁剪、缩放的模式aspectFit、aspectFill、widthFix、heightFix、top、bottom、center、left、right、top left、top right、bottom left、bottom right
lazy-load是否开启图片懒加载true/false
show-menu-by-longpress是否开启长按图片显示识别小程序码菜单true/false
webp是否开启 webp 格式支持true/false
@load加载事件event
@error错误事件event
1
2
3
4
<view class="image-box" hover-class="image-box-hover">
<view> image 组件 </view>
<image src="../../static/logo.png" mode="aspectFit"></image>
</view>

该组件类似HTML中的<a>组件,但只能跳转本地页面。目标页面必须在pages.json中注册

属性名描述可选值
url跳转目标页面/pages/navigation/navigation
open-type跳转方式navigateTo、redirectTo、reLaunch、switchTab
deltaopen-typenavigateBack 时有效,表示回退的层数Number
animation-typeopen-typenavigatenavigateBack 时有效,窗口的显示/关闭动画效果pop-in/out
animation-durationopen-typenavigatenavigateBack 时有效,窗口显示/关闭动画的持续时间300
1
2
3
4
<view class="navigation-box" hover-class="navigation-box-hover">
<view> navigation 组件 </view>
<navigator url="/pages/navigation/navigation" open-type="navigate" animation-type="slide-in-left">点我跳转到navigation页面</navigator>
</view>

button组件

属性名描述可选值
type按钮类型primary、default、warn
size按钮大小default、mini
disabled按钮是否禁用true/false
1
2
3
4
<view class="button-box" hover-class="button-box-box-hover">
<view> button 组件 </view>
<button type="primary" disabled size="mini">按钮组件</button>
</view>

input 组件

属性名描述可选值
type输入框的类型text、number、idcard、digit、password
placeholder输入框的提示文字String('1')
placeholder-style指定 placeholder 的样式String('1')
placeholder-class指定 placeholder 的样式类String('1')
disabled是否禁用true/false
1
2
3
4
<view class="input-box" hover-class="input-box-hover">
<view> input 组件 </view>
<input type="text" placeholder="请输入内容:" />
</view>

生命周期

uni-app中,页面的生命周期Vue的生命周期相似,但也有其特定的生命周期钩子。以下是uni-app中页面的生命周期函数及其作用:

钩子描述
onLoad页面加载时触发,一个页面只会调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数。
onShow页面出现在屏幕上时触发,包括从下拉菜单、返回键、硬件返回键等触发。
onReady页面加载完成时触发,一个页面只会调用一次,代表页面已经渲染完成。
onHide页面从前台变为后台时触发,包括下拉菜单返回键硬件返回键等触发。
onUnload页面销毁时触发,如跳转页面(open-type="reLaunch")关闭当前页面退出应用等。
onPullDownRefresh页面下拉刷新时触发
onReachBottom页面滚动到底部时触发
onShareAppMessage页面分享时触发
onPageScroll页面滚动时触发
onResize页面尺寸变化时触发
onTabItemTap点击 tab 时触发
onNavigationBarButtonTap监听原生标题栏按钮点击事件。
onBackPress监听页面返回,返回 event = {from:backbutton、 navigateBack}``,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress
onNavigationBarSearchInputChanged监听原生标题栏搜索输入框输入内容变化
onNavigationBarSearchInputConfirmed监听原生标题栏搜索输入框搜索事件
onNavigationBarSearchInputClicked监听原生标题栏搜索输入框点击事件

在项目中使用

1
2
3
4
import { onReachBottom } from "@dcloudio/uni-app"
onReachBottom(()=> {
console.log("触底刷新 onReachBottom!")
})

page.json配置

路由页面配置

pages.json -> pages 配置项中的第一个页面,作为当前工程的首页(启动页)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"pages": [
{
"path": "pages/index/index", //名字叫不叫index无所谓,位置在第一个,就是首页
"style": {
"navigationBarTitleText": "首页", //页面标题
"navigationStyle": "custom" //自定义导航样式
}
},
{
"path": "pages/my",
"style": {
"navigationBarTitleText": "我的"
}
},
]
}

属性描述
pathurl页面路径
style页面样式
style.navigationStyle自定义导航栏样式
style.navigationBarTitleText页面标题
style.navigationBarBackgroundColor页面标题栏背景颜色
style.navigationBarTextStyle页面标题栏文字颜色
style.navigationBarColor页面标题栏颜色
enablePullDownRefresh是否开启下拉刷新
onReachBottomDistance页面上拉触底事件触发时距页面底部距离,单位只支持px
backgroundColor下拉显示出来的窗口的背景色
backgroundTextStyle下拉显示的窗口字体颜色

pagas 中的 style当前页面的样式, 其配置会覆盖 page.json 中的 globalStyle 配置。

globalStyle配置

uni-apppage.json文件中,globalStyle用于全局配置应用状态栏导航条标题窗口背景色等外观。以下是一些常用的配置属性:

  1. navigationBarBackgroundColor: 导航栏背景颜色。默认值为#F7F7F7。
  2. navigationBarTextStyle: 导航栏标题颜色。可选值为white(白色)或black(黑色)。
  3. navigationBarTitleText: 导航标题文字内容
  4. backgroundColor: 窗口背景色。只有在页面下拉时才能看见
  5. backgroundTextStyle: 下拉loading的样式。可选值为dark(深色)或light(浅色)。
  6. onReachBottomDistance: 页面触底事件触发时距页面底部的距离,单位是px。

注意: 以上是全局配置,pages中的配置会覆盖全局配置。

tabbar底部导航

如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}]
}

manifest.json 配置

manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。

属性描述
name应用名称
appid应用标识
description应用描述
versionName应用版本名称,例如:1.0.0。
versionCode应用版本号 版本号,例如:36
description应用描述
permissions应用权限列表
networkTimeout网络超时时间,
debug调试模式

vite.config.js

unplugin-auto-import

配置自动导入

1
2
import { ref } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'

安装插件

1
npm install unplugin-auto-import -D

配置插件
vite.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import UnpluginAutoImport from 'unplugin-auto-import/vite';
export default defineConfig({
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
plugins: [
uni(),
// 配置自动导入
UnpluginAutoImport({ imports: ['vue','uni-app'] })
],
})

注意: 配置完成后,需要重启小程序开发工具(关掉小程序开发者工具后,使用 hbuilderx 工具重新运行!)。

相关api

界面交互

showToast hideToast

显示隐藏消息提示框

1
2
3
4
5
6
uni.showToast({
title: '标题',
duration: 2000
});

uni.hideToast();

showLoading hideLoading

显示 隐藏加载提示框

1
2
3
4
5
uni.showLoading({
title: '加载中'
});

uni.hideLoading();

showModal

显示模态弹窗

1
2
3
4
5
6
7
8
9
10
11
uni.showModal({
title: '提示',
content: '这是一个模态弹窗',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});

showActionSheet

显示操作菜单

1
2
3
4
5
6
7
8
9
uni.showActionSheet({
itemList: ['A', 'B', 'C'],
success: function (res) {
console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
},
fail: function (res) {
console.log(res.errMsg);
}
});

设置导航条样式

setNavigationBarTitle

动态设置当前页面的标题。

1
2
3
4
uni.setNavigationBarTitle({
title: '新的标题'
});

如果需要在页面进入时设置标题,可以在onReady内执行,以避免被框架内的修改所覆盖。如果必须在onShow内执行需要延迟一小段时间

setNavigationBarColor

设置页面导航条颜色。如果需要进入页面就设置颜色,请延迟执行,防止被框架内设置颜色逻辑覆盖

1
2
3
4
5
6
7
8
9
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#ff0000',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})

showNavigationBarLoading

在当前页面显示导航条加载动画。

1
2
3
4
// 显示
uni.showNavigationBarLoading()
// 隐藏
uni.hideNavigationBarLoading()

hideHomeButton

隐藏返回首页按钮。

1
uni.hideHomeButton()

设置 tabbar

setTabBarBadge

设置 tabBar 某一项的角标。

1
2
3
4
5
uni.setTabBarBadge({
index: 0,
text: 123
})
uni.removeTabBarBadge({index: 0})

最好在app.vue中去设置 tabbar避免无法正常获取 index!

showTabBarRedDot

显示 tabBar 某一项的红点。

1
2
3
4
// 显示
uni.showTabBarRedDot({index: 0})
// 隐藏
uni.hideTabBarRedDot({index: 0})

页面和路由

保留当前页面跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。

属性类型描述
urlString要跳转的应用内页面的路径,路径后可以带参数。
animationTypeString窗口显示的动画效果,支持none、slide-in-right、slide-in-left、slide-in-top、slide-in-bottom、fade-in、pop-in
animationDurationNumber窗口显示动画的时长,单位为ms
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)
1
2
3
4
5
uni.navigateTo({
url: 'pages/index/index',
animationType: 'pop-in',
animationDuration: 300
});

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。

属性类型描述
deltaNumber返回的页面数,如果 delta 大于现有页面数,则返回到首页。
animationTypeString窗口显示的动画效果,支持none、slide-in-right、slide-in-left、slide-in-top、slide-in-bottom、fade-in、pop-in
animationDurationNumber窗口显示动画的时长,单位为ms
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数
completeFunction接口调用结束的回调函数(调用成功、失败都会执行)

注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 此处是A页面
uni.navigateTo({
url: 'B?id=1'
});

// 此处是B页面
uni.navigateTo({
url: 'C?id=1'
});

// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
delta: 2
});

redirectTo

关闭当前页面,跳转到应用内的某个页面`。

1
2
3
uni.redirectTo({
url: 'pages/index/index'
});

switchTab

跳转到应用内的某个tabBar页面 并关闭其他所有非 tabBar 页面。

tabbar

1
2
3
4
5
6
7
8
9
10
11
{
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
},{
"pagePath": "pages/other/other",
"text": "其他"
}]
}
}

1
2
3
uni.switchTab({
url: 'pages/index/index'
});

reLaunch

关闭当前页面,重新打开到应用内的某个页面。

1
2
3
uni.reLaunch({
url: 'pages/index/index'
});

页面参数传递

navigateTo redirectTo switchTab reLaunch 都可以接收参数,参数在目标页面的onLoad方法中获取。

1
2
3
uni.navigateTo({
url: "page/B/B?id=115123123&name='张三'"
})
1
2
3
4
onLoad: function(options) {
console.log(options.id); // 115123123
console.log(options.name); // 张三
}

EventChannel

EventChannel 是一个发布-订阅模式的通信接口,用于不同页面之间的数据通信。

属性描述参数
emit触发一个事件emit(string eventName, any args)
off取消监听一个事件。给出第二个参数时,只取消给出的监听函数,否则取消所有监听函数off(string eventName, function fn)
on监听一个事件on(string eventName, function fn)
once监听一个事件,只触发一次once(string eventName, function fn)

navigateTo, redirectTo 只能打开非 tabBar 页面。
switchTab 只能打开 tabBar 页面。
reLaunch 可以打开任意页面
页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
不能在首页 onReady 之前进行页面跳转。
H5端页面刷新之后页面栈会消失,此时navigateBack不能返回,如果一定要返回可以使用history.back()导航到浏览器的其他历史记录。

数据缓存

同步数据缓存,统一在api接口后面加Sync!
setStorageSync getStorageSync removeStorageSync clearStorageSync

setStorage

设置本地缓存

1
2
3
4
5
uni.setStorage({

key: 'name',
data: '张三'
});

getStorage

获取本地缓存

1
2
3
4
5
6
uni.getStorage({
key: 'name',
success: function(res) {
console.log(res.data); // 输出 "张三"
}
});

getStorageSync

同步获取本地缓存

1
2
const name = uni.getStorageSync('name');
console.log(name); // 输出 "张三"

removeStorage

删除本地缓存

1
2
3
4
5
6
uni.removeStorage({
key: 'name',
success: function() {
console.log('remove success');
}
});

clearStorage

清除本地缓存

1
uni.clearStorage();

网络请求

request

发起请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uni.request({
url: 'https://www.example.com/api',
data: {
name: '张三'
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
console.log(res.data);
},
fail: function(res) {
console.log(res.errMsg);
}
});

uploadFile

上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uni.chooseImage({
count: 1,
success: function(res) {
var tempFilePaths = res.tempFilePaths;
uni.uploadFile({
url: 'https://www.example.com/upload',
filePath: tempFilePaths[0],
name: 'file',
header: {
'content-type': 'application/octet-stream'
},
success: function(res) {
console.log(res.data);
},
fail: function(res) {
console.log(res.errMsg);
}
});
}
});

downloadFile

下载文件

1
2
3
4
5
6
7
8
9
uni.downloadFile({
url: 'https://www.example.com/download',
success: function(res) {
console.log(res.tempFilePath);
},
fail: function(res) {
console.log(res.errMsg);
}
});

使用 axios

推荐使用 axios 库进行网络请求,它是基于 Promise 的 HTTP 库,可以用更简洁的 API 实现请求。

uniapp中不支持xhr请求,因此axios需要通过自定义适配器(adapter)来实现!

安装 axios 和 适配器插件
1
2
npm install axios -S
npm install axios-adapter-uniapp -S
创建 http.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import axios from 'axios';
import axiosAdapterUniapp from 'axios-adapter-uniapp';

const http = axios.create({
baseURL: 'https://api.example.com',
adapter: axiosAdapterUniapp,
});

http.interceptors.request.use(config => {
// 在请求之前做些什么
return config;

}, error => {
// 对请求错误做些什么
return Promise.reject(error);
});

http.interceptors.response.use(response => {
// 对响应数据做点什么
return response;

}, error => {
// 对响应错误做点什么
return Promise.reject(error);
});

export default http;

uniapp demo

小猫列表展示

功能项

  • [x] 列表展示
  • [x] 图片预览
  • [x] 返回顶部
  • [x] 下拉刷新
  • [x] 触底加载
  • [x] 数据请求

界面展示

代码实现

uni-load-more uni-iconsuni-ui扩展ui组件!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<scroll-view>
<view class="cat-container">
<view class="cat-card" v-for="(cat, index) in catList">
<view class="cat-img" @click="onPreviewImage(index)">
<image mode="widthFix" lazy-load :src="cat.url"></image>
</view>
<view class="cat-title">
<text>第 {{ index + 1 }} 张 {{ cat.width }} * {{ cat.height }}</text>
</view>
</view>

<view class="float-btn">
<view class="refresh" @click="onRefresh">
<uni-icons type="refreshempty" size="30"></uni-icons>
</view>
<view class="return-top" @click="returnTop">
<uni-icons type="arrow-up" size="30"></uni-icons>
</view>
</view>

<view class="load-more">
<uni-load-more status="loading"></uni-load-more>
</view>
</view>
</scroll-view>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { ref } from 'vue'
import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app';
let catList = ref([]);

// 图片预览
function onPreviewImage( currentIndex ){
console.log('catList.map(cat => cat.url)', catList.value.map(cat => cat.url))
uni.previewImage({
current: currentIndex,
urls: catList.value.map(cat => cat.url)
})
}

// 获取 cat 列表
function getCatList(){
// 需要在微信公众平台 开发者设置下 开启 request 合法域名 不然预览时无法使用
return uni.request({
url: "https://api.thecatapi.com/v1/images/search",
data: {
limit: 10
},
method: "GET"
})
}
// 添加 cat 追加到新的列表
function addCatListAppendToList( list = [], model = 'onload' ){
if( !list.length ){ return }
catList.value = catList.value.concat( list )
console.log(`${ model } -> 追加成功~`, catList.value, catList.value.length )
}
// 刷新列表
function onRefresh(){
uni.startPullDownRefresh()
}

// 返回顶部
function returnTop(){
uni.pageScrollTo({
scrollTop: 0
})
}
// 页面加载完成
onLoad(async () => {
console.log('页面加载完成 onLoad!')
let res = await getCatList();
addCatListAppendToList( res.data, 'onload' )
})
// 下拉刷新
onPullDownRefresh( async () => {
let res = await getCatList();
catList.value = res.data;
uni.showToast({
title: "刷新成功!",
duration: 3000
});
uni.stopPullDownRefresh();
returnTop();
console.log('onPullDownRefresh', catList.value.length)
})
// 触发底部刷新
onReachBottom(async () => {
console.log('触发底部刷新 onReachBottom!')
let res = await getCatList();
addCatListAppendToList( res.data, 'onReachBottom' )
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.cat-container{
padding: 15rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 35rpx;
.float-btn{
position: fixed;
right: 15rpx;
bottom: 15rpx;
font-size: 16rpx;
.refresh,.return-top{
width: 85rpx;
height: 85rpx;
border-radius: 50px;
margin-top: 15rpx;
text-align: center;
line-height: 85rpx;
background-color: #fff;
}
}
.cat-card{
// width: 655rpx;
.cat-img{
// text-align: center;
}
.cat-title{
text-align: center;
padding: 5rpx;
}
border-radius: 15rpx;
box-shadow: 1rpx 1rpx 15rpx rgba(0,0,0, .4);
overflow: hidden;
}
}

皮皮熊壁纸

一款参照咸虾米壁纸uniapp壁纸应用。

界面展示

gitee地址