Uniapp的学习

uniapp的内容和vue网页开发会有很多区别,但是都是基于vue开发的,大多数业务还是在vue打交道,但是这些uniapp的特殊的知识点也是要掌握好的。

基本配置

创建uniapp项目

npx degit dcloudio/uni-preset-vue#vite-ts 项目名 :用于创建一个uniapp项目

npm run dev:mp-weixin :用于给项目打包成微信小程序的打包格式,接着直接将dist中相应的包导入到相应的微信开发者工具里面即可。

加上ts类型校验:npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types

ts类型校验

接着在tsconfig.json配置文件中配置好这个类型校验:

TypeScript 复制代码
{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "lib": ["esnext", "dom"],
    "types": ["@dcloudio/types",
    "@types/wechat-miniprogram",//加上
  "@uni-helper/uni-app-types"]//加上
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

uni-ui的支持

安装uni-helper/uni-ui-types:

npm i -D @uni-helper/ui-types

再把@uni-helper/uni-ui-types加上以上的type配置项中去。

TypeScript 复制代码
"types": [
      "@dcloudio/types",
      "@types/wechat-miniprogram",//加上
      "@uni-helper/uni-app-types",
      "@uni-helper/uni-ui-types"]//加上
    
    },

pinia配置

持久化配置:要先下载pinia持久化插件:

npm i pinia-plugin-persistedstate

插件默认使用 localStorage 实现持久化,小程序端不兼容,需要替换持久化 API。

store下的index.ts:

TypeScript 复制代码
import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'

// 创建 pinia 实例
const pinia = createPinia()
// 使用持久化存储插件
pinia.use(persist)

// 默认导出,给 main.ts 使用
export default pinia

// 模块统一导出
export * from './modules/member'

main.ts:

TypeScript 复制代码
import { createSSRApp } from "vue";
import App from "./App.vue";
import pinia from './stores'
export function createApp() {
  const app = createSSRApp(App);
  app.use(pinia)
  return {
    app,
  };
}

要多端配置持久化,要在相应的store的ts文件中,配置持久化规则:

小程序端配置持久化persist,要专门配置下getItem和setItem:(在defineStore中配置此参数)

TypeScript 复制代码
// TODO: 持久化
    persist: {
      storage:{
        getItem(key){
          return uni.getStorageSync(key)
        },
        setItem(key,value){
          uni.setStorageSync(key,value)
        }
      }
    }

封装promise请求函数和请求过滤器

TypeScript 复制代码
import { useMemberStore } from "@/stores/modules/member"
import { BaseRequestUrl } from "./properties"
const baseURL = BaseRequestUrl

//添加拦截器
const httpInterceptor = {
    invoke(option:UniApp.RequestOptions){
        //非http开头的请求需要拼接地址
        if(!option.url.startsWith('http')){
            option.url = baseURL + option.url
        }
        //请求超时,默认是六十秒
        option.timeout = 30000
        console.log(option)
        //添加小程序请求头标识
        option.header = {
            ...option.header, //如果有原来的请求头,保留原来的请求头后再加上小程序请求头
            'source-client':'miniapp'
        }
        //添加token请求头标识
        const memberStore = useMemberStore()
        const token = memberStore.profile?.token
        if(token){
            option.header.Authorization = token
        }
    }
}
uni.addInterceptor('request',httpInterceptor)
uni.addInterceptor('uploadFile',httpInterceptor)

interface Data<T>{
    code:string,
    message:string,
    data:T
}

export const sendRequest = <T>(option:UniApp.RequestOptions) => {  //指定泛型,该泛型是有效数据的类型
    return new Promise<Data<T>>((resolve,reject) => {  
        uni.request({
            ...option,
            success(res){
                if(res.statusCode >= 200 && res.statusCode < 300){ //如果是2xx,说明是
                    resolve(res.data as Data<T>)  //后端响应过来的有效数据
                }else if(res.statusCode === 401){
                    // 401错误 -》 清理用户信息,跳转到登录页
                    const memberStore = useMemberStore()
                    memberStore.clearProfile()
                    uni.navigateTo({url:'/pages/login/login'})
                    reject(res)
                }else{
                    //其他错误 -》 根据后端错误信息轻提示
                    uni.showToast({
                        icon:'none',
                        title:(res.data as Data<T>).message || '请求错误'
                    })
                }
            },fail(err){ //响应失败,一般是网络问题
                uni.showToast({
                    icon:'none',
                    title:'网络错误'
                })
                reject(err)
            }
        })
    })
}

其实就是小程序端使用uni.request来发送请求,自定义了一个promise,内部使用了uni.request函数,用于发送请求。uni.request返回的数据中,是属于后端返回的数据的是res中的data,所以要返回的就是res.data。Data接口是后端返回的数据类型的格式。token的信息也封装在其中,登录后获取token之后,token信息会储存在pinia中,每次发送请求的时候,token会自动被读取到请求头中。

baseUrl是服务器的url地址或者微服务网关的url地址。

关于pages.json

在uniapp中,每个页面都是要注册在pages.json文件中。

在pages.json中,配置页面的路由地址及窗口表现、默认窗口表现、tarbar

代码案例:

TypeScript 复制代码
{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",//可以在此处修改一些小程序的页面信息
			"style": {
				"navigationBarTitleText": "首页"
			}
		},
		{
			"path" : "pages/my/my",
			"style" : 
			{
				"navigationBarTitleText" : "我的"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#2ff8d0",
		"backgroundColor": "#F8F8F8"
	},
	"tabBar": {
		"selectedColor": "#2ff8d0",//tarbar选中的时候的文字的颜色指定
		"list": [
			{
				"pagePath": "pages/index/index",//tabar的路由
				"text": "首页",//tabar下方的文字
				"iconPath": "static/tabs/home_default.png",//tabar的图标
				"selectedIconPath": "static/tabs/home_selected.png"//tabar被选中的时图标
			},
			{
				"pagePath": "pages/my/my",
				"text": "我的",
				"iconPath": "static/tabs/user_default.png",
				"selectedIconPath": "static/tabs/user_selected.png"
			}
		]
	},
}

pages参数

pages参数是一个数组,数组中的元素就是一个一个的页面的信息,数组中的第一个元素代表的页面就是应用首页。

path就是页面的路由地址,之后关于路由跳转页面的时候,都是使用这个配置的路由地址。

style是页面的一些窗口表现配置。style用于设置每个页面的状态栏、导航条、标题、窗口背景色等。在pages参数外还有一个参数叫globalStyle,用于配置全局窗口表现,每个页面的实际的窗口表现会先找style,如果没有的话再找globalStyle。

常见的样式如下:

属性 类型 默认值 描述
navigationBarBackgroundColor HexColor #F8F8F8 导航栏背景颜色(同状态栏背景色)
navigationBarTextStyle String black 导航栏标题颜色及状态栏前景颜色,仅支持 black/white
navigationBarTitleText String 导航栏标题文字内容
navigationStyle String default 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏
backgroundColor HexColor #ffffff 窗口的背景色

至于具体的样式,见

pages.json 页面路由 | uni-app官网

tarbar

tarbar是用于配置一级导航栏,即底部的那个导航栏。

常用配置属性:

属性 类型 必填 默认值 描述
color HexColor tab 上的文字默认颜色
selectedColor HexColor tab 上的文字选中时的颜色
backgroundColor HexColor tab 的背景色
list Array tab 的列表,详见 list 属性说明,最少2个、最多5个 tab
position String bottom 可选值 bottom、top,用于控制一级导航栏是显示在底部还是顶部

tarbar参数中的list数组,是一级导航栏里面的tab导航的信息的数组,tar导航的顺序和数组中的一致,tarbar最多配置五个tab,最少配置两个tab。

tab的配置属性:

属性 类型 必填 说明
pagePath String 页面路径,必须在 pages 中先定义
text String tab 上按钮文字,在 App 和 H5 平台为非必填。例如中间可放一个没有文字的+号图标
iconPath String 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 position 为 top 时,此参数无效,不支持网络图片,不支持字体图标
selectedIconPath String 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 position 为 top 时,此参数无效
visible Boolean 该项是否显示,默认显示
iconfont Object 字体图标,优先级高于 iconPath

具体参数信息见官网文档:pages.json 页面路由 | uni-app官网

分包

pages.json中还可以进行分包配置,分包可以让一些页面和主要的页面分开下载,即进入程序的时候,会默认下载主包中的页面信息,而分包中的信息,在进入指定页面的时候,此分包才会开始下载页面信息,如此可以大大优化小程序的下载和启动速度。

分包中的页面不要放在src下的pages目录中,要自定义一个和pages目录同级的新目录,代表一个分包,将分包页面放在此分包的目录中。

例:若有个分包叫pagesMember,此分包下有两个页面:settings.vue,profile.vue

TypeScript 复制代码
{
	//组件自动导入的规则
	"easycom": {
		//是否开启自动扫描
		"autoscan": true,
		//以正则的方式自定义组件匹配规则
		"custom": {
			// uni-ui 规则如下配置
			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
		}
	},
	"pages": [
		//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationStyle": "custom", //隐藏默认导航栏
				"navigationBarTitleText": "首页"
			}
		},
		{
			"path": "pages/my/my",
			"style": {
				"navigationStyle": "custom",
				"navigationBarTextStyle": "white",
				"navigationBarTitleText": "我的"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	// 设置 TabBar
	"tabBar": {
		"color": "#333",
		"selectedColor": "#27ba9b",
		"backgroundColor": "#fff",
		"borderStyle": "white",
		"list": [
			{
				"text": "首页",
				"pagePath": "pages/index/index",
				"iconPath": "static/tabs/home_default.png",
				"selectedIconPath": "static/tabs/home_selected.png"
			}
			{
				"text": "我的",
				"pagePath": "pages/my/my",
				"iconPath": "static/tabs/user_default.png",
				"selectedIconPath": "static/tabs/user_selected.png"
			}
		]
	},
	//分包信息配置
	"subPackages": [
		{
			"root": "pagesMember",
			"pages": [
				{
					"path": "settings/settings",
					"style": {
						"navigationBarTitleText": "设置"
					}
				},
				{
					"path": "profile/profile",
					"style": {
						"navigationStyle": "custom",
						"navigationBarTextStyle": "white",
						"navigationBarTitleText": "个人信息详情页面"
					}
				}
			]
		}
	],
	//分包预下载规则
	"preloadRule": {
		"pages/my/my": {
			"network": "all", 
			"packages": [
				"pagesMember"
			] 
		}
	}
}

subPackages中,root是此分包中页面的的根目录,也就是以上自定义的那个pagesMember目录。

preloadRule就是指定,进入了哪个页面的时候,会下载哪个分包。参数名就是触发下载的页面的路径,参数值中的network是代表在什么网络环境下下载分包,packages是指定要加载哪些分包。

具体使用见:pages.json 页面路由 | uni-app官网

常用api

api比较多,我列举几个我觉得看了有用的api。例如上传文件、选择媒体资源上传到服务器、页面路由跳转、弹出窗口提示等。

uni.uploadFile()

此方法用于将文件数据上传到服务器中,请求方式是post,其中 content-type 为 multipart/form-data。

参数名 类型 必填 说明
url String 开发者服务器 url
fileType String 见平台差异说明 文件类型,image/video/audio
file File 要上传的文件对象。
filePath String 是(files和filePath选其一) 要上传文件资源的路径。
name String 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
header Object HTTP 请求 Header, header 中不能设置 Referer。
timeout Number 超时时间,单位 ms
formData Object HTTP 请求中其他额外的 form data
success Function 接口调用成功的回调函数
fail Function 接口调用失败的回调函数
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)
TypeScript 复制代码
        uni.uploadFile({
			url: 'https://www.example.com/upload', //仅为示例,非真实的接口地址
			filePath: tempFilePaths[0],
			name: 'file',
			formData: {
				'userInfo': userinfo.value
			},
			success: (uploadFileRes) => {
				console.log(uploadFileRes.data);
			}
		});

其中一定要注意的是,formData参数的参数值会变成一个json字符串请求给后端,后端可以在controller的方法的参数列表上,添加一个String的参数,在其前面的@RequestParam注解中,加上指定在formData中设置的key的名称,这个参数上就会接受到指定的formData中的相应的参数信息。

java 复制代码
@PostMapping(value="/upload")
    public ResultData<RoleContentPo> voiceMsgSend(@RequestParam("userInfo") String str, @RequestParam("file") MultipartFile file){
    UserInfo userInfo = JSONObject.parseObject(str,UserInfo.class);
    //其他操作
}

关于下载文件,没什么要特殊说明的,见文档:uni.uploadFile(OBJECT) | uni-app官网

uni.chooseMedia()

用于用户从自己的相册中选择图片或者启动拍照功能获取图片。

参数名 类型 默认值 必填 说明
count Number 9(注意:ios不可大于9) 最多可以选择的文件个数
mediaType Array.<string> ['image', 'video'] 文件类型
sourceType Array.<string> ['album', 'camera'] 图片和视频选择的来源
maxDuration Number 10 拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 30s 之间
sizeType Array.<string> ['original', 'compressed'] 仅对 mediaType 为 image 时有效,是否压缩所选文件
camera String 'back' 仅在 sourceType 为 camera 时生效,使用前置或后置摄像头
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

代码案例:

TypeScript 复制代码
uni.chooseMedia({
  count: 9,
  mediaType: ['image','video'],
  sourceType: ['album', 'camera'],
  maxDuration: 30,
  camera: 'back',
  success(res) {
    console.log(res.tempFiles)
  }
})

res.tempFiles是选择的图片/视频的临时文件的路径的数组,其中的元素就是一个个临时文件的路径。

路由跳转

uni.navigateTo()

保留原有页面,跳转到指定的页面。要跳转到原来的页面,使用uni.navigateBack()即可跳回原来的页面。

参数 类型 必填 说明
url String 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 'path?key=value&key2=value2',path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数
success Function 接口调用成功的回调函数
fail Function 接口调用失败的回调函数
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)
TypeScript 复制代码
uni.navigateTo({
	url: '/pages/login/login?id=1&name=uniapp'
});

路由路径后面带的参数可以被下个页面的onLoad函数的参数中获取,当然也会作为query参数传递。

uni.redirectTo()

和uni.navigate使用方法一致,区别是,uni.redirectTo()是关闭当前页面,跳转到指定页面,类似一个替换的效果。

uni.reLaunch()

使用也是和以上两个一致,区别是,它使用后,会关闭此前的所有的页面,跳转到指定页面。

uni.switchTab()

以上的四个api都是只能用于打开非tab页面,要想打开tab页面,要使用uni.switchTab,使用方法和以上四个是一致的。只是页面路径要是tab页面。并且使用了该方法后会关闭所有的非tab页面。

uni.navigateBack()

用于回退到之前的页面。

参数 类型 必填 默认值 说明
delta Number 1 返回的页面数,如果 delta 大于现有页面数,则返回到首页。
success Function 接口调用成功的回调函数
fail Function 接口调用失败的回调函数
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

当然,更多的知识点和使用方法,在官网文档中才是最详细的,uniapp官网:uni-app官网

相关推荐
Liquor14191 小时前
JavaScript知识点梳理及案例实践
开发语言·前端·javascript·python·css3·html5·js
空白诗3 小时前
HTML 基础概念:什么是 HTML ? HTML 的构成 与 HTML 基本文档结构
前端·html
漫天转悠5 小时前
Uniapp在Vue环境中引入iconfont图标库(详细教程)
前端·vue.js·uniapp
334554327 小时前
element表格双击修改时间
开发语言·前端·javascript
想退休的搬砖人7 小时前
axios请求中的data和params的区别
前端
前端李易安7 小时前
如何封装一个axios,封装axios有哪些好处
前端·vue.js·axios
sky.fly8 小时前
HTML5+css3(伪类,动态伪类,结构伪类,否定伪类,UI伪类,语言伪类,link,hover,active,visited,focus)
开发语言·前端·css3·html5
沈询-阿里8 小时前
spring ai 入门 之 结构化输出 - 把大模型llm返回的内容转换成java bean
前端·javascript·easyui