uniapp的通用页面及组件基本封装

1.基本布局页面

适用于自定义Navbar头部

html 复制代码
<template>
  <view class="bar" :style="{height : systemInfo.statusBarHeight + 'px', background: param.barBgColor }"></view>
  <view class="headBox" 
        :style="{ 
          height: param.headHight + 'px',
          background: param.headBgColor,
        }">
    <view class="leftBox">
      <slot name="left">
        <view class="back" v-if="autoBack" @click="uni.navigateBack({ delta: 1 })">
			<XIcon name="back" blod></XIcon>
		</view>
      </slot>
    </view>

    <view class="centerBox">
      <slot name="center">
        <view class="title">{{param.title}}</view>
      </slot>
    </view>
	
	<view class="rightBox" :style="{ paddingRight: !slots.right ? 0 + 'px' : (menuButton.width + 12) + 'px' }">
	  <slot name="right"></slot>
	</view>
  </view>
  <slot name="topBox"></slot>
  <scroll-view @scrolltolower="emits('tolower',true)" scroll-y id="calcPoint" :style="`height:${ rollHight }px;overflow-y: auto;`">
  	<slot name="container"></slot>
  </scroll-view>
</template>

<script setup lang="ts">
	import { onMounted , ref , useSlots } from "vue";
	import { getPageResidueDIST } from "@/utils/common";
	import XIcon from "@/element/XIcon.vue"
	
	const param = withDefaults(defineProps<{
	  barBgColor: string;
	  headHight: number;
	  headBgColor: string;
	  autoBack: boolean;
	  title: string;
	}>(),{
		headHight: 44,
		headBgColor: '#ffffff',
		barBgColor: '#ffffff',
		autoBack: true,
		title: '基本页面'
	})
	
	const emits = defineEmits<{
		( e: 'tolower' , status : boolean ) : void
	}>();
	
	
	const slots = useSlots();

	const systemInfo = ref<any>({});
	const menuButton = ref<any>({ width: 0 });


	const init = async () => {
	  systemInfo.value = await uni.getSystemInfo();
	  // #ifndef APP || H5
			menuButton.value = uni.getMenuButtonBoundingClientRect();
	  // #endif
	};

	onMounted(() => {
	  init();
	  setRollHight();
	});
	
	
	
	let rollHight = ref<number>(0);
	
	async function setRollHight() {
		let calcPoint = await getPageResidueDIST('#calcPoint');
		rollHight.value = calcPoint - (systemInfo.value?.safeAreaInsets?.bottom == 0 ?  10 : systemInfo.value?.safeAreaInsets?.bottom);
	}
	
</script>

<style scoped lang="scss">
	.headBox {
	  display: flex;
	  align-items: center;
	  justify-content: space-between;
	  padding: 0 12px;
	  width: 100%;
	  box-sizing: border-box;

	  .leftBox {
		flex: 1;
		display: flex;
		justify-content: flex-start;
	  }

	  .centerBox {
		flex: 2;
		display: flex;
		justify-content: center;
		text-align: center;
		
		.title {
		  font-size: 16px;
		  color: #303133;
		}
	  }

	  .rightBox {
		flex: 1;
		display: flex;
		justify-content: flex-end;
	  }
	}

</style>

2.阿里iocn

注意使用阿里icon需要下载阿里的字体图标,然后把css的文件引入到app.vue,就可以使用iconfont icon-xxx,是你图标名称

html 复制代码
<template>
	<view>
		<text :class='`iconfont icon-${param.name}`' :style="{ fontSize: param.size + 'rpx' , color: param.color , fontWeight : param.blod ? '400' : 'bloder' }" ></text>
	</view>
</template>

<script lang="ts" setup>
	import { onBeforeMount, ref } from "vue";
	
	interface Prop {
		name: string;
		size?: number;
		color? : string;
		blod?: false;
	}
	
	const param = withDefaults(defineProps<Prop>(),{
		size: 38
	});

	
</script>

<style lang="scss" scoped>
</style>

3.缓存工具

这里扩展了一个记录历史查看

javascript 复制代码
export function setCache(key : string, value : any ) {
	uni.setStorageSync(key,value);
}

export function getCache(key : string) : any | null {
	return uni.getStorageSync(key);
}

export function removeCache(key : string)  {
	return uni.removeStorageSync(key);
}



interface Record {
	time: number;
	key: any;
}

export function saveHistory(key : string,val : any) {
	let localHistory : Array<Record> = getCache(key);
	if(!localHistory) { localHistory = [] }
	if(localHistory.some(item => item.key == val)) { return }
	localHistory.unshift({
		time: new Date().getTime(),
		key: val
	});
	setCache(key,localHistory);
}


export function removeHistory(key : string,val : any) : number {
	let row : number = 0;
	let localHistory : Array<Record> = getCache(key);
	if(!localHistory) { localHistory = [] }
	row = localHistory.length;
	localHistory = localHistory.filter(item => {
		if (item.key === val) {
			row++;
			return false;
		}
		return true;
	});
	setCache(key,localHistory);
	return row - localHistory.length;
}

4.公共工具类

获取位置、计算元素剩余搞定 , 页面跳转

javascript 复制代码
import { getCurrentInstance } from "vue";

/**
 * 根据类型跳转页面并传递数据
 * 
 * @param type - 跳转类型:
 *               - 0: 使用 `uni.navigateTo` 跳转,保留当前页面,跳转到新页面
 *               - 1: 使用 `uni.switchTab` 跳转,切换到指定 tabBar 页面
 * @param url - 目标页面的路径
 * @param key ? - 事件通道中传递数据的键名
 * @param data ? - 通过事件通道传递的数据
 */
export function skipPage(type : number,url : string,key ? : string , data ? : any) {
	switch (type){
		case 0:
			uni.navigateTo({
				url,
				success(res) {
					res.eventChannel.emit(key,data);
				}	
			})
			break;
		case 1:
			uni.switchTab({
				url,
				success(res) {
					res.eventChannel.emit(key,data);
				}	
			})
			break;
		default:
			console.log('接入中!');
			break;
	}
}



export async function getPageResidueDIST(nodeKey: string) : Promise<number> {
	const query = uni.createSelectorQuery().in(getCurrentInstance());
	let systemInfo = await uni.getSystemInfo();
	let nodeToTop : number = await new Promise((ok, _) => {
		query
			.select(nodeKey)
			.boundingClientRect((data: any) => {
				ok(data.top);
			})
			.exec();
	});
	return systemInfo.windowHeight - nodeToTop;
}

export async function getSystemInfo() {
	 return await uni.getSystemInfo();
}

export async function getMenuButton() {
	// #ifndef APP || H5
		return uni.getMenuButtonBoundingClientRect();
	// #endif
	return { width: 0  }
}

export async function getElementHight(nodeKey: string) : Promise<number> {
	const query = uni.createSelectorQuery().in(getCurrentInstance());
	let nodeToTop : number = await new Promise((ok, _) => {
		query
			.select(nodeKey)
			.boundingClientRect((data: any) => {
				ok(data.height);
			})
			.exec();
	});
	return nodeToTop;
}

interface Point {
	latitude: number;
	longitude: number;
}

export async function initLocation() : Promise<any> {
		return await uni.getLocation({
			type: 'wgs84',
			geocode:true});
}


export async function getAddress() : Promise<any> {
	return new Promise(( ok ) =>{
		uni.chooseLocation({
			success: function (res) {
				ok({
					code: 200,
					address: res.address,
					latitude: res.latitude,
					longitude: res.longitude,
					name: res.name
				})
			},
			fail() {
				ok({
					code: 201
				})
			}	
		});
	})
}

5.网络请求类

javascript 复制代码
import { env } from "@/env"
 
export default function() {
	
	interface AskModel {
		url: string,
		data?: any
		method?: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT'
	}
	 
	 
	interface ApiRes<T> {
		 code: number;
		 msg: string;
		 data: T;
	}
	 
	 
	async function orderMealAsk<T>( option : AskModel ) : Promise<ApiRes<T>> {
		return new Promise(( resolve, reject ) => {
			uni.request({
			    url:  env.orderMealReq + option.url, 
			    data: option.data || {},
				method: option.method || 'GET',
			    header: {
			    	'content-type':'application/json' 
			    },
			    success: (res) => {
			        resolve(res.data as ApiRes<T>);
			    },
				fail(res) {
					reject(res);
				}
			});
		})
	}
	
	return {  orderMealAsk }
}
相关推荐
dy17175 分钟前
vue3 element-plus 输入框回车跳转页面问题处理
前端·javascript·vue.js
海尔辛44 分钟前
学习黑客 shell 脚本
前端·chrome·学习
每天吃饭的羊1 小时前
XSS ..
前端
2301_789169541 小时前
ai说什么是注解,并以angular ts为例
javascript
小李李32 小时前
基于Node.js的Web爬虫: 使用Axios和Cheerio抓取网页数据
前端·爬虫·node.js·跨域
酷小洋2 小时前
CSS基础
前端·css
xinruoqianqiu2 小时前
shell脚本--2
linux·运维·开发语言·前端·c++·chrome
几度泥的菜花3 小时前
Vue 项目中长按保存图片功能实现指南
前端·javascript·vue.js
学习机器不会机器学习3 小时前
什么是跨域,如何解决跨域问题
前端·后端
Code哈哈笑3 小时前
【图书管理系统】详细讲解用户登录:后端代码实现及讲解、前端代码讲解
前端·spring boot·后端·spring·状态模式