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

news2025/4/16 7:39:23

1.基本布局页面

适用于自定义Navbar头部

<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,是你图标名称

<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.缓存工具

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

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.公共工具类

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

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.网络请求类

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 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「2025AIGC终极形态」AI系统源码:文本→图像→音乐→视频生成

—从技术痛点到企业级部署&#xff0c;手把手实现全流程AI内容工厂 行业核心痛点&#xff1a;为什么需要多模态AIGC系统&#xff1f; 1. 工具割裂&#xff0c;效率低下 传统流程&#xff1a; 文案&#xff08;ChatGPT&#xff09;→ 配图&#xff08;Midjourney&#xff09;→…

使用CS Roofline Toolkit测量带宽

使用CS Roofline Toolkit测量带宽 工程下载&#xff1a;使用CS Roofline Toolkit测量带宽-案例工程文件&#xff0c;也可以按照下面的说明使用git clone下载 目录 使用CS Roofline Toolkit测量带宽0、Roofline模型理解1、CS Roofline Toolkit下载1.1、设置代理1.2、git clone下…

L1-4 拯救外星人

题目 你的外星人朋友不认得地球上的加减乘除符号&#xff0c;但是会算阶乘 —— 正整数 N 的阶乘记为 “N!”&#xff0c;是从 1 到 N 的连乘积。所以当他不知道“57”等于多少时&#xff0c;如果你告诉他等于“12!”&#xff0c;他就写出了“479001600”这个答案。 本题就请你…

现代c++获取linux系统名称

现代c获取linux系统名称 前言一、使用命令获取操作系统名称二、使用c代码获取操作系统名称三、验证四、总结 前言 本文介绍一种使用c获取当前操作系统名称的方法 一、使用命令获取操作系统名称 在linux系统中可以使用uname或者uname -s命令来获取当前操作系统名称&#xff0c…

力扣刷题HOT100——53.最大子数组和

给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&#xff1a;6…

ES和MySQL概念对比

基本概念 ES和MySQL都属于数据库&#xff0c;不过各有各的特性&#xff0c;大致使用方法与MySQL类似并无区别。 MySQL&#xff1a;擅长事务持有ACID的特性&#xff0c;确保数据的一致性和安全。 ES&#xff1a;持有倒排索引&#xff0c;适合海量数据搜索和分析。 ES和MySQL如何…

Android开发过程中遇到的SELINUX权限问题

1、selinux权限一般问题 问题详情 log输出如下所示&#xff1a; 01-01 00:00:12.210 1 1 I auditd : type1107 audit(0.0:33): uid0 auid4294967295 ses4294967295 subju:r:init:s0 msg‘avc: denied{ set } for propertypersist.sys.locale pid476 uid1000 gid1000 scontext…

Windows系统docker desktop安装(学习记录)

目前在学习docker&#xff0c;在网上扒了很多老师的教程&#xff0c;终于装好了&#xff0c;于是决定再装一遍做个记录&#xff0c;省的以后再这么麻烦 一&#xff1a;什么是docker Docker 是一个开源的应用容器引擎&#xff0c;它可以让开发者打包他们的应用以及依赖包到一个…

MIP-Splatting:全流程配置与自制数据集测试【ubuntu20.04】【2025最新版】

一、引言 在计算机视觉和神经渲染领域&#xff0c;3D场景重建与渲染一直是热门研究方向。近期&#xff0c;3D高斯散射&#xff08;3D Gaussian Splatting&#xff09;因其高效的渲染速度和优秀的视觉质量而受到广泛关注。然而&#xff0c;当处理大型复杂场景时&#xff0c;这种…

怎样完成本地模型知识库检索问答RAG

怎样完成本地模型知识库检索问答RAG 目录 怎样完成本地模型知识库检索问答RAG使用密集检索器和系数检索器混合方式完成知识库相似检索1. 导入必要的库2. 加载文档3. 文本分割4. 初始化嵌入模型5. 创建向量数据库6. 初始化大语言模型7. 构建问答链8. 提出问题并检索相关文档9. 合…

XCTF-web(三)

xff_referer 拦截数据包添加&#xff1a;X-Forwarded-For: 123.123.123.123 添加&#xff1a;Referer: https://www.google.com baby_web 提示&#xff1a;想想初始页面是哪个 查看/index.php simple_js 尝试万能密码&#xff0c;没有成功&#xff0c;在源码中找到如下&#xf…

Verilog的整数除法

1、可变系数除法实现----利用除法的本质 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2025/04/15 13:45:39 // Design Name: // Module Name: divide_1 // Project Name: // Target Devices: // Tool Versions: // Description: // // Depe…

React 把一系列 state 更新加入队列

把一系列 state 更新加入队列 设置组件 state 会把一次重新渲染加入队列。但有时你可能会希望在下次渲染加入队列之前对 state 的值执行多次操作。为此&#xff0c;了解 React 如何批量更新 state 会很有帮助。 开发环境&#xff1a;Reacttsantd 学习内容 什么是“批处理”以…

【大模型理论篇】Search-R1: 通过强化学习训练LLM推理与利⽤搜索引擎

最近基于强化学习框架来实现大模型在推理和检索能力增强的项目很多&#xff0c;也是Deep Research技术持续演进的缩影。之前我们讨论过《R1-Searcher:通过强化学习激励llm的搜索能⼒》&#xff0c;今天我们分析下Search-R1【1】。 1. 研究背景与问题 ⼤模型&#xff08;LLM&a…

Google政策大更新:影响金融,新闻,社交等所有类别App

Google Play 4月10日 迎来了2025年第一次大版本更新&#xff0c;新政主要涉及金融&#xff08;个人贷款&#xff09;&#xff0c;新闻两个行业。但澄清内容部分却使得所有行业都需进行一定的更新。下面&#xff0c;我们依次从金融&#xff08;个人贷款&#xff09;&#xff0c;…

NO.93十六届蓝桥杯备战|图论基础-拓扑排序|有向无环图|AOV网|摄像头|最大食物链计数|杂物(C++)

有向⽆环图 若⼀个有向图中不存在回路&#xff0c;则称为有向⽆环图(directed acycline graph)&#xff0c;简称 DAG 图 AOV⽹ 举⼀个现实中的例⼦&#xff1a;课程的学习是有优先次序的&#xff0c;如果规划不当会严重影响学习效果。课程间的先后次序可以⽤有向图表⽰ 在…

每日文献(十三)——Part one

今天看的是《RefineNet: Iterative Refinement for Accurate Object Localization》。 目录 零、摘要 0.1 原文 0.2 译文 一、介绍 二、RefineNet A. Fast R-CNN B. Faster R-CNN C. RefineNet 训练 D. RefineNet 测试 零、摘要 0.1 原文 We investigate a new str…

游戏引擎学习第225天

只能说太难了 回顾当前的进度 我们正在进行一个完整游戏的开发&#xff0c;并在直播中同步推进。上周我们刚刚完成了过场动画系统的初步实现&#xff0c;把开场动画基本拼接完成&#xff0c;整体效果非常流畅。看到动画顺利呈现&#xff0c;令人十分满意&#xff0c;整个系统…

Linux 使用Nginx搭建简易网站模块

网站需求&#xff1a; 一、基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab ​ 二、给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[www.openlab.com/student](http://www.openlab.com/stud…

抖音ai无人直播间助手场控软件

获取API权限 若使用DeepSeek官方AI服务&#xff0c;登录其开发者平台申请API Key或Token。 若为第三方AI&#xff08;如ChatGPT&#xff09;&#xff0c;需通过接口文档获取访问权限。 配置场控软件 打开DeepSeek场控软件&#xff0c;进入设置界面找到“AI助手”或“自动化”…