1.基本布局页面
适用于自定义Navbar头部
<template><view :style="{ background : param.bgColor , height: '100%' }"><block v-if="param.noHead"><slot name="head"></slot></block><block v-if="!param.noHead"><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></block><slot name="nav"></slot><scroll-view @scrolltolower="emits('tolower',true)" scroll-y id="calcBasePoint" :style="`height:${ rollHight }px;overflow-y: auto;`"><slot name="container"></slot></scroll-view></view>
</template><!-- 适用于自定义Navbar头部 -->
<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;noHead: boolean;bgColor: string;}>(),{bgColor: '#FAFAFA',headHight: 44,headBgColor: '#ffffff',barBgColor: '#ffffff',autoBack: true,title: '',noHead: false})const emits = defineEmits<{( e: 'tolower' , status : boolean ) : void,(e : 'sysInfo', data : any ) : void}>();const slots = useSlots();const systemInfo = ref<any>({});const menuButton = ref<any>({ width: 0 });const init = async () => {systemInfo.value = await uni.getSystemInfo();// #ifndef APP || H5menuButton.value = uni.getMenuButtonBoundingClientRect();// #endifemits('sysInfo',{system: systemInfo.value,menuBtn: menuButton.value});};onMounted(() => {init();setRollHight();});let rollHight = ref<number>(0);async function setRollHight() {let calcPoint = await getPageResidueDIST('#calcBasePoint');console.log(systemInfo.value?.safeAreaInsets?.bottom);rollHight.value = calcPoint - (!systemInfo.value?.safeAreaInsets?.bottom ? 0 : systemInfo.value?.safeAreaInsets?.bottom) ;// #ifdef APP || MP-WEIXINrollHight.value = rollHight.value - systemInfo.value.statusBarHeight - param.headHight;// #endif}</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 || H5return uni.getMenuButtonBoundingClientRect();// #endifreturn { 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?: anymethod?: '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 }
}