IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> uni-app移动端开发技巧总结 -> 正文阅读

[JavaScript知识库]uni-app移动端开发技巧总结

一.pages.json常用配置总结

pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径窗口样式原生的导航栏、**底部的原生tabbar **等。

1. pages 设置页面路径及窗口表现

  • pages节点的第一项为应用入口页(即首页)
  • 应用中新增/减少页面,都需要对 pages 数组进行修改
  • 文件名不需要写后缀,框架会自动寻找路径下的页面资源

pages 节点接收一个数组,数组每个项都是一个对象。该对象的属性值有:

(1) path : 配置页面的路径,字符串类型

(2) style :配置该页面独有的一些窗口表现 ,对象类型

2.tabBar 设置底部 tab 的表现

该节点也是一个对象,里面的常用属性有:

(1) color :tab 上的文字初始的颜色

(2) selectColor :tab 上的文字选中时的颜色

(3) fontSize :文字大小,默认10px

(4) height :tabbar的高度,默认50px

(5)iconWidth 图标默认宽度

(6) list :tab 的列表,最少2个,最多5个 tab

list 接收一个数组,数组中的每个项都是一个对象。对象的属性有:

  • pagePath : 页面路径,必须在 pages 中先定义
  • text :tab 上按钮文字。不填的话,就是一个图标
  • iconPath :图片路径
  • selectedIconPath :选中时的图片路径

(7) midButton: 中间按钮

仅在 list 项为偶数时有效,有以下属性:

  • width :中间按钮的宽度
  • height :中间按钮的高度,可以大于 tabBar 高度,达到中间凸起的效果
  • text :中间按钮的文字
  • iconPath :中间按钮的图片路径
  • iconWidth :中间图标的宽度。(高度等比缩放)

!注意! :midButton没有pagePath,需监听点击事件,自行处理点击后的行为逻辑。监听点击事件为调用API:uni.onTabBarMidButtonTap

3. globalStyle和style的常用属性

globalStyle和style都是对象类型的节点,大部分的样式写在两个节点里都是可行的。主要用于设置窗口的表现,一个是全局的,一个是单独页面的。有如下的属性:

navigationBarBackgroundColor :导航栏背景颜色(同状态栏背景色)。默认#000000(即黑色)

navigationBarTextStyle :导航栏标题颜色及状态栏前景颜色,仅支持 black/white。默认white(白色)

navigationBarTitleText : 导航栏标题文字内容

bounce :页面回弹效果,设置为 “none” 时关闭效果。(建议在全局设为"none")

scrollIndicator : 右侧滚动条显示策略,设置为 “none” 时不显示滚动条。按情况设置。

navigationStyle : 导航栏样式,仅支持 default/custom。默认为"default"。"custom"即取消默认的原生导航栏,使用自定义导航栏。

app-plus :设置编译到 App 平台的特定样式。是一个对象类型的属性

(1)app-plus常用属性:

bounce : 页面回弹效果,设置为 “none” 时关闭效果。

titleNView : 导航栏。对象格式。如果取为false,则取消导航栏。

titleNView的常用属性:

backgroundColor :导航栏的背景颜色,会覆盖掉navigationBarBackgroundColor

titleColor :标题文字颜色,可以设置更多rgb的颜色。

titleText :标题文字内容

titleSize :标题文字字体大小

autoBackButton :标题栏控件是否显示左侧返回按钮

titleIcon :标题图标,位于标题的左部

titleIconRadius : 标题图标圆角,取值格式为"XXpx",其中XX为像素值(逻辑像素),如"10px"表示10像素半径圆角。

titleAlign :标题在导航栏上的位置。可取值: (“center”-居中对齐; “left”-居左对齐;)

autoBackButton :是否显示左侧返回按钮 ,默认为true,取消返回按钮,设为false

二.常用功能和开发技巧总结

1.关闭导航栏返回按钮

在要关闭返回按钮的style中添加如下的代码:
"app-plus":{
				"titleNView":{
					"autoBackButton":false
				}
			}

2.禁止屏幕旋转时横屏

在App.vue中的onLaunch生命周期函数中添加如下的代码:
onLaunch: function () {  
    // 锁定竖屏  
    plus.screen.lockOrientation("portrait-primary");  
}

3.设置应用的启动时间

在App.vue中的onLaunch生命周期函数中添加如下的代码:
setTimeout(() => {
    plus.navigator.closeSplashscreen();
}, 2000);

4.禁止手机某页面右滑返回

在对应页面的vue文件中添加onBackPress生命周期函数,并返回true。
onBackPress(e) {//禁止返回
			return true;
		}

5.注册功能的总结

当点击注册按钮时,先要判断账号密码的格式是否符合要求。如果判断后,发现格式不符合要求的话,就要弹出Toast消息提示框,提示相应的错误。

消息提示框uni.showToast
uni.showToast({
						title:'提示信息',
						icon:"none",//提示框的类型,一般都为none
						position:"bottom",//提示框的位置。
    					duration:600//消息显示时间的毫秒数
					})

如果注册填写的账号密码格式填写正确,点击注册按钮时就向服务器发送请求,如果注册成功的话,就显示Toast消息提示框,消息提示框的icon不用填,设置一个duration显示时间。之后设置一个定时器,用于页面的跳转,跳转到login登录页面。如果账号注册失败也要显示失败的Toast提示。

示例代码如下:

					// 发送注册的请求
					this.$post(api.USER_REGISTER,{
						userName:this.username,
						password:this.password,
						phonenumber:this.phoneNum,
						sex:this.sex
					}).then(res =>{
						//请求成功
						if(res.code == 200){
						//显示成功的Toast
							uni.showToast({
								title:'注册成功!',
								duration:600
							})
							//跳转到注册页面
							setTimeout(function(){
								uni.navigateTo({
									url:'./login'
								})
							},600)
						}else{
							//显示错误的Toast信息
							uni.showToast({
								title:res.msg,
								icon:"none",
								position:'bottom'
							})
						}
					})

6.封装请求和API

uni-app有提供发起http请求的功能的api但是,应用各页面很多时候要发起非常多的请求,为了简化代码,所以要封装请求和API。把封装的代码放在根目录下的common目录下。

uni-app发起请求的方法uni.request(OBJECT)

uni.request({
    method:'请求的方式', // GET,POST,PUT等
    url:'请求的url地址',
    header:{}, //请求头,是一个对象类型
    data:{}, //请求的参数
    dataType:'json', //一般都设为json,会尝试对返回的数据做一次 JSON.parse
    success:function(){}, //接口请求成功时执行的回调函数
    fail:function(){} // 接口调用失败时执行时执行的回调函数
})

把请求的代码封装在common下的request.js模块下:

下面是示例代码:

//把模块内定义的方法暴露出去
export default{
	// 封装get请求的发送
	get(url,data){
		// 同步获取本地的token
		let token = uni.getStorageSync('token');
		// 封装get请求
		return new Promise((resolve,reject)=>{
			uni.request({
				method:'GET',
				url:url,
				data:data,
				header:{
					'authorization':token
				},
				dataType:'json',
				success: (res) => {
					console.log("get--success")
					// 401:未授权(登录已过期)
					if(res.data.code === 401){
						// 移除本地的token
						uni.removeStorageSync('token');
						// 显示模态弹窗
						uni.showModal({
							title:'提示',
							content:'登录认证已过期,请重新登录!',
							success: (res) => {
								// 1.如果用户点击了确认,跳转到登录页面
								if(res.confirm){
									uni.navigateTo({
										url:'/pages/startUp/login.vue'
									});
								}else if(res.cancel){
									// 用户点击了取消,则什么也不做
									console.log("用户点击了取消")
								}
							}
						});
					}
					resolve(res.data);
				},
				fail: (err) => {
					console.log(err)
					uni.showToast({
						title:"网络连接超时,请下拉刷新!",
						icon:"none",
						duration:1500
					});
					reject(err)
				}
			})
		});
	},
	//封装一个post请求
	post(url,data){
		// 同步获取本地的token指令
		let token = uni.getStorageSync('token')
		return new Promise((resolve,reject)=>{
			uni.request({
				method:'POST',
				url:url,
				data:data,
				header:{
					'content-type':'application/json',
					'authorization':token
				},
				dataType:'json',
				success:function(res){
					console.log("post---success")
					console.log("post---url:"+url)
					console.log("post---code:"+res.data.code)
					if(res.data.code === 401){
						uni.removeStorageSync('token');
						uni.showModal({
							title:'提示',
							content:"登录已过期,请重新登录!",
							success: (res) => {
								if(res.confirm){
									uni.navigateTo({
										url:'/pages/startUp/login.vue'
									})
								}else if(res.cancel){
									console.log('用户点击取消');
								}
							}
						});
					}
					resolve(res.data)
				},
				fail: (err) => {
					console.log("失败")
					uni.showToast({
						title:"接口请求失败,请稍后再试!",
						icon:"none"
					})
					reject(err)
				}
			});
		});
	},
	// 封装一个put请求
	put(url,data){
		let token = uni.getStorageSync('token');
		return new Promise((resolve,reject)=>{
			uni.request({
				method:'PUT',
				url:url,
				data:data,
				header:{
					'content-type':'application/json',
					'authorization':token
				},
				dataType:'json',
				success: (res) => {
					if(res.data.code === 401){
						uni.removeStorageSync('token')
						uni.showModal({
							title:'提示',
							content:'登录已过期,请重新登录!',
							success: (res) => {
								if(res.confirm){
									uni.navigateTo({
										url:'/pages/startUp/login.vue'
									})
								}else if(res.cancel){
									console.log("用户点击取消")
								}
							}
						});
					}
					resolve(res.data)
				},
				fail: (err) => {
					uni.showToast({
						title:"接口请求失败,请稍后再试",
						icon:'none'
					})
					reject(err)
				}
			})
		})
	}
}

其中的每一个请求的方法都返回promise。

之后,还要根据接口文档来封装一个apiUtil.js的接口模块,下面是示例代码:

var ip = uni.getStorageSync('serverIp');
var baseUrl = 'http://'+ ip;

export default{
	SERVER_BASE:baseUrl,
	//用户登录
	USER_LOGIN:baseUrl + '/prod-api/api/login',
	//注册
	USER_REGISTER:baseUrl + '/prod-api/api/register',
	// 获取用户个人信息
	GET_USER_INFO:baseUrl+ '/prod-api/api/common/user/getInfo',
	// 获取首页轮播图
	GET_INDEX_BANNER_IMG:baseUrl+'/prod-api/api/rotation/list',
	// 获取所有服务信息
	GET_SERVICE_INFO:baseUrl+'/prod-api/api/service/list'
}

ip是每一个请求都有的IP地址,通过获取注册时的本地存储里面获取。baseurl对ip地址和http请求拼接一下。

最后就是暴露当前封装的API接口。

封装好这两个模块后,还好把这两个模块在main.js中进行导入和对vue的原型进行绑定。示例代码如下

//导入封装好的模块
import request from './common/request.js'
import api from './common/apiUtil.js'

// 将起绑定到Vue的原型上面去
Vue.prototype.$api = api
Vue.prototype.$get = request.get
Vue.prototype.$post = request.post
Vue.prototype.$put = request.put

7.本地数据缓存

(1) uni.setStorage( OBJECT )

将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。

OBJECT 参数说明:

参数名参数类型说明
keystring本地缓存中的指定的 key
data任何类型需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象
successFunction接口调用成功的回调函数
failFunction接口调用失败的回调函数

示例代码:

uni.setStorage({
	key: 'storage_key',
	data: 'hello',
	success: function () {
		console.log('success');
	}
});

(2) uni.setStorageSync( KEY , DATA )

将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。

参数说明

参数名参数类型说明
keystring本地缓存中的指定的 key
data任何类型需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象

示例代码:

uni.setStorageSync('storage_key', 'hello');

(3) uni.getStorage( OBJECT )

从本地缓存中异步获取指定 key 对应的内容。

OBJECT 参数说明:

参数名参数类型说明
keystring本地缓存中的指定的 key
successFunction接口调用的回调函数
failFunction

success函数传入的参数说明:

参数名参数类型说明
dataAnykey 对应的值

示例代码如下:

uni.getStorage({
	key: 'storage_key',
	success: function (res) {
		console.log(res.data);
	}
});

(4) uni.getStorageSync( KEY )

从本地缓存中同步获取指定 key 对应的内容。

参数说明:

参数名参数类型说明
keystring本地缓存中的指定的 key

示例代码:

const value = uni.getStorageSync('storage_key');

(5) uni.removeStorage( OBJECT )

从本地缓存中异步移除指定 key。

OBJECT 参数说明:

参数参数类型说明
keystring本地缓存中的指定的 key
successFunction删除成功时的回调函数
failFunction删除失败时的回调函数

示例代码:

uni.removeStorage({
	key: 'storage_key',
	success: function (res) {
		console.log('success');
	}
});

(6) **uni.removeStorageSync( KEY ) **

从本地缓存中同步移除指定 key。

参数说明:

参数名参数类型说明
keystring本地缓存中的指定的 key

8.生命周期相关

生命周期有分应用生命周期页面生命周期

(1) 应用生命周期

函数名说明
onLaunchuni-app 初始化完成时触发(全局只触发一次
onShowuni-app 启动,或从后台进入前台显示
onHideuni-app 从前台进入后台
onErroruni-app 报错时触发
onPageNotFound页面不存在监听函数

(2) 页面的生命周期其实就是vue的组件的生命周期

9. 路由与页面跳转

(1) uni.navigateTo( OBJECT )

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

OBJECT参数说明:

参数类型参数说明
urlString需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’,path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数
successFunction成功后的回调函数

注意:

  • 页面跳转路径有层级限制,不能无限制跳转新页面
  • 跳转到 tabBar 页面只能使用 switchTab 跳转

(2) uni.navigateBack( OBJECT )

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

OBJECT参数说明:

参数类型说明
deltanumber返回的页面数,如果 delta 大于现有页面数,则返回到首页。
successFunction成功时的回调函数

(3)uni.redirectTo( OBJECT )

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

OBJECT参数说明:

参数类型说明
urlstring要跳转的页面,路径后可以带参数

(4)uni.switchTab( OBJECT )

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。注意: 如果调用了 **uni.preloadPage(OBJECT) **不会关闭,仅触发生命周期 onHide

OBJECT参数说明:

参数类型说明
urlstring要跳转的tabbar页的路径,路径后不能带参数

(5)uni.preloadPage(OBJECT)

预加载页面,是一种性能优化技术。被预载的页面,在打开时速度更快。

OBJECT参数说明:

参数类型参数说明
urlstring要预加载的路径

10.与界面相关的操作

(1)uni.showModal( OBJECT )

显示模态弹窗,可以只有一个确定按钮,也可以同时有确定和取消按钮

OBJECT参数说明

参数名参数类型说明
titlestring提示的标题
contentstring提示的内容
showCancelbool是否显示取消按钮,默认true
successfunction成功时的回调函数

success返回参数说明

参数类型说明
cancelbool是否点击取消
confirmbool是否点击确认

(2) uni.hideTabBar( )和uni.showTabBar()

隐藏 tabBar和显示tabBar

(3)onPullDownRefresh

在 js 中定义 onPullDownRefresh 处理函数(和onLoad等生命周期函数同级),监听该页面用户下拉刷新事件。

  • 需要在 pages.json 里,找到的当前页面的pages节点,并在 style 选项中开启 enablePullDownRefresh
  • 当处理完数据刷新后,**uni.stopPullDownRefresh **可以停止当前页面的下拉刷新。

(4)onTabItemTap

当点击本页tabBar的item时触发的函数

如下案例:

		onTabItemTap: function(e) {
			if(e.index==2) {
				uni.setTabBarStyle({
				  selectedColor: '#D9001B'
				})
			} else {
				uni.setTabBarStyle({
				  selectedColor: '#007AFF'
				})
			}
		}

(5)下拉刷新页面的实现原理

(1)首先要开启该页面的下拉刷新的功能

(2)然后在该页面添加的OnPullDownRefresh(e){ } 里面监听下拉刷新,并在里面调用获取页面数据的代码,然后就要在里面使用vue的**this.$forceUpdate()**方法来重新渲染页面。

示例代码如下:

onPullDownRefresh(e) {
			this.getBannerImage()
			this.getServiceInfo()
			this.getNewsList()
			this.$forceUpdate()
			uni.stopPullDownRefresh()
		}

最后别忘了调用uni.stopPullDownRefresh()停止刷新。

三.常用的uniapp组件

1.轮播图 swiper

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

常用属性说明:

属性说明
indicator-dots是否显示面板指示点,默认为false
indicator-color指示点颜色,rgb颜色
indicator-active-color当前选中的指示点颜色
autoplay是否自动切换,默认为false
interval自动切换时的时间间隔,默认5000
duration滑动时动画时长,默认500
@changecurrent 改变时会触发 change 事件,event.detail = {current: current, source: source}

2.可滚动视图区域 scroll-view

属性说明

属性说明
scroll-x允许横向滚动。默认为false
scroll-with-animation在设置滚动条位置时使用动画过渡

scroll-view里面放view。并且一定要给scroll-view的样式加上white-space: nowrap

下面是使用示例:

	<view class="scroll-box">
			<scroll-view scroll-x="true" scroll-with-animation="true">
				<view class="scroll-view-item" v-for="item in newsfl">
					<text>{{item.name}}</text>
				</view>
			</scroll-view>
	</view>

如果要点击各view换颜色,就给view添加一个hover-class的属性。

3.富文本 rich-text

富文本的用处非常的大,请求过来的数据很多带html标签,使用富文本可以对这些标签解析渲染。

常用属性:

属性说明
nodes要加载的文本(html string)

四.常用的uni-ui组件

1. **uni-data-checkbox ** 选项组件

本组件是基于uni-app基础组件checkbox的封装,这个组件可以用于单选项和多选项。

下面是基本的使用:

(1)单选按钮

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pSLuNTO3-1647782363222)(D:\Pictures\截图\Snipaste_2022-03-12_10-01-20.png)]

<template>
	<view>
		<uni-data-checkbox v-model="value" :localdata="range" @change="change"></uni-data-checkbox>
	</view>
</template>
export default {
	data() { 
		return {
			value: 0,
			range: [{"value": 0,"text": "篮球"	},{"value": 1,"text": "足球"},{"value": 2,"text": "游泳"}]
		}
	},
	methods: {
		change(e){
			console.log(e);
		}
	}
}

v-model 为表单的双向数据绑定,绑定value的值。

localdata 为要渲染的数据,属性的格式为数组,数组内每项是对象,对象的格式需为{ “value” : 选中后的值 ,“text” : 显示的文本 }

@change 选中状态改变时触发事件

2. uni-dateformat 日期格式化组件。

基本用法如下:

<uni-dateformat date="2020/10/20 20:20:20" format="yyyy年MM月dd日" ></uni-dateformat>

date 传入要格式化的时间。format指定格式化的模式(如yyyy-MM-dd hh:mm:ss)

3. uni-easyinput 增强输入框

最基础的用法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gqGbNTr-1647782363222)(D:\Pictures\截图\Snipaste_2022-03-12_11-16-06.png)]

<uni-easyinput v-model="value" placeholder="请输入内容"></uni-easyinput>

输入框带左右图标

可以用于设置搜索框,但是可能没有这个必要。而且也不是非常好看

设置 suffixIcon 属性来显示输入框的尾部图标

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ksseOCLw-1647782363223)(D:\Pictures\截图\Snipaste_2022-03-12_11-19-50.png)]

<uni-easyinput suffixIcon="search"  v-model="value" placeholder="请输入内容" @iconClick="onClick"></uni-easyinput>

可以设置输入框的类型

type属性,值有:password密码框,textarea多行文本输入框,text单行文本框,number数字输入键盘

可以设置输入框的最大长度 :maxlength

设置键盘右下角的文字 confirmType

conformType有这些属性:

属性名说明
send发送
search搜索
next下一个
go前往
done完成

是否自动去除空格 trim

样式自定义 style

type=password 时,是否显示小眼睛图标 passwordIcon 默认为true

4. uni-file-picker 文件上传组件

文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间。项目里会有一个更换头像的功能。由于比赛的项目并没有提供上传头像的接口,所以只是本地app更换头像,用来示意一下。

<uni-file-picker v-model="value" file-mediatype="image" limit="1" @select="select()">
	<button>选择头像</button>
</uni-file-picker>

v-model绑定一个空数组 就行, file-mediatype指定文件类型 ,limit用于指定上传文件的个数。有一个选中时触发的方法@select

5. uni-group 分组组件

<uni-group title="分组1" top="20" mode="card">
    <view>分组1 的内容</view>
    <view>分组1 的内容</view>
</uni-group>

<uni-group title="分组2">
    <view>分组2 的内容</view>
    <view>分组2 的内容</view>
</uni-group>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sdmOMe62-1647782363223)(D:\Pictures\截图\Snipaste_2022-03-12_13-05-51.png)]

title用于指定分组的标题,top用于指定分组的间隔,mode为模式,有默认和card模式。

6 . uni-combox

<uni-combox label="所在城市" :candidates="candidates" placeholder="请选择所在城市" v-model="city"></uni-combox>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:40:43  更:2022-03-21 20:41:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:05:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码