从搭建uni-app+vue3工程开始

技术栈

uni-app、vue3、typescript、vite、sass、uview-plus、pinia、axios

一、项目搭建

1、创建以 typescript 开发的工程

npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

2、安装sass

npm install -D sass

// 安装sass-loader,注意需要版本10,否则可能会导致vue与sass的兼容问题而报错
pnpm add sass-loader@10 -D

 3、安装uview-plus

介绍 | uview-plus - 全面兼容nvue/鸿蒙/uni-app-x的uni-app生态框架 - uni-app UI框架

npm install uview-plus
①main.ts引入uview-plus
import uviewPlus from 'uview-plus'
 
export function createApp() {
  const app = createSSRApp(App);
  app.use(uviewPlus)
  return {
    app,
  };
}
②uni.scss引入全局SCSS主题文件
@import 'uview-plus/theme.scss';
③App.vue引入基础样式
<style lang="scss">
	/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
	@import "uview-plus/index.scss";
</style>
④pages.json配置easycom组件模式
{
	"easycom": {
		// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
		"custom": {
			"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
			"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
	        "^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
		}
	},
	
	// 此为本身已有的内容
	"pages": [
		// ......
	]
}
⑤如果在mian.ts中引入uview-plus时会提示ts报错:无法找到模块“uview-plus”的声明文件

在src文件中创建一个types文件夹专门用来存放ts类型声明文件,在文件中新建uview.d.ts文件写入下方声明代码

declare module "uview-plus"
⑥测试使用

 在vue页面的使用

<u-button text="提交"></u-button>

4、安装 axios

(1)h5使用axios

pnpm install axios
① 安装qs

查询参数序列化和解析库。可以将一个普通的object序列化成一个查询字符串,或者反过来将一个查询字符串解析成一个object

pnpm install qs --save-dev
②统一配置请求接口时的请求头参数

在src下创建utils文件夹=》创建axios文件夹=》创建config.ts文件

const http_config: {
  result_code: number | string
  default_headers: AxiosHeaders
  token_name: string
  request_timeout: number
} = {
  /**
   * token默认名称
   */
  token_name: '_token',
  /**
   * 接口成功返回状态码
   */
  result_code: '0000',

  /**
   * 接口请求超时时间
   */
  request_timeout: 60000,

  /**
   * 默认接口请求类型
   * 可选值:application/x-www-form-urlencoded multipart/form-data
   */
  default_headers: 'application/json;charset=utf-8'
}

export { http_config }
③设置请求、响应拦截器

同一文件夹下=》创建service.ts

import axios, { AxiosError, type AxiosRequestHeaders, type AxiosResponse } from 'axios'
import qs from 'qs'
import { http_config } from './config'

const { request_timeout } = http_config

export const PATH_URL = 'https://fj9dazt2gi.laf.run'
// 创建axios实例
const service: any = axios.create({
	baseURL: PATH_URL, // api 的 base_url
	timeout: request_timeout // 请求超时时间
})


//显示loading
function showLoading(title: any) {
	uni.showToast({
		title: title,
		duration:0,
	})
}

//隐藏loading
function hideLoading() {
	uni.hideToast();
}


// request拦截器
service.interceptors.request.use(
	(config: any) => {
		if (config.showLoading) {
			showLoading(config.message);
		}
		if (
			config.method === 'post' &&
			(config.headers as AxiosRequestHeaders)['Content-Type'] ===
			'application/x-www-form-urlencoded'
		) {
			config.data = qs.stringify(config.data)
		}
		// get参数编码
		if (config.method === 'get' && config.params) {
			let url = config.url as string
			url += '?'
			const keys = Object.keys(config.params)
			for (const key of keys) {
				if (config.params[key] !== void 0 && config.params[key] !== null) {
					url += `${key}=${encodeURIComponent(config.params[key])}&`
				}
			}
			url = url.substring(0, url.length - 1)
			config.params = {}
			config.url = url
		}

		return config
	},
	(error: AxiosError) => {
		console.log(error) // for debug
		uni.showToast({
			title: error.message,
			icon: 'none'
		})
		Promise.reject(error)
		hideLoading();
	}
)

// response 拦截器
service.interceptors.response.use(
	(response: AxiosResponse<any>) => {
		hideLoading();
		if (response.config.responseType === 'blob') {
			// 如果是文件流,直接过
			return response
		} else {
			if (response.config.responseType === 'arraybuffer') {
				return response.data = `data: image/jpeg;base64,${btoa(new Uint8Array(response.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))}`
			} else {
				const { success, code, msg } = response.data;
				if (!success) {
					// 规定错误码功能,例如9108-请登录系统进行访问,自动跳转登录页
					if (code == 9108) {
						// 请登录系统进行访问,自动跳转登录页
						uni.showToast({
							title: '登录过期请重新登录'
						})
						setTimeout(() => {
							uni.reLaunch({
								url: '/pages/login/login'
							})
						}, 2000);
					}
					return response.data
				}
				return response.data;
			}
		}
	}
	,
	(error: AxiosError) => {
		console.log('err' + error) // for debug
		uni.showToast({
			title: error.message,
			icon: 'none'
		})
		hideLoading();
		return Promise.reject(error)
	}
)

export { service }
④封装axios请求传参、请求方式等

同一文件夹下=》创建index.ts

import { service } from './service'
import { http_config } from './config'

const { default_headers } = http_config

const request = (option: any) => {
  console.log(option);
  const { url, method, params, data, headersType, responseType, loadingMsg, headers,isShow } = option
  const message = loadingMsg ? loadingMsg :'请稍后...'
  const showLoading = isShow ? isShow : true
  return service({
    url: url,
    method,
    params,
    data,
    responseType: responseType,
    headers: {
      'Accept-Language': JSON.parse(localStorage.getItem("language")) || 'zh-CN,zh;q=0.9',
      'Content-Type': headersType || default_headers,
      ...headers
    },
    message,
    showLoading
  })
}

export default {
  get: <T = any>(option: any) => {
    return request({ method: 'get', ...option }) as unknown as T
  },
  post: <T = any>(option: any) => {
    return request({ method: 'post', ...option }) as unknown as T
  },
  delete: <T = any>(option: any) => {
    return request({ method: 'delete', ...option }) as unknown as T
  },
  put: <T = any>(option: any) => {
    return request({ method: 'put', ...option }) as unknown as T
  }
}

(2)小程序使用axios

①安装axios-miniprogram-adapter库

由于兼容性问题,安装axios,同时还需要适配器

pnpm i axios axios-miniprogram-adapter
②设置axios请求适配器

在设置请求、响应拦截器前进行配置

import axios, { AxiosError, type AxiosRequestHeaders, type AxiosResponse } from 'axios'
import mpAdapter from 'axios-miniprogram-adapter'

axios.defaults.adapter = mpAdapter
③其他配置步骤同h5

5、安装依赖

pnpm i

6、h5启动项目

pnpm dev:h5

7、启动小程序项目

①方式一

通过HBuilder X=》配置好manifest.json底下小程序的appid=》运行到小程序模拟器

②方式二

打包小程序,将项目目录生成的dist文件夹,导入微信开发工具运行并编译

pnpm dev:mp-weixin

8、拓展

(1)自动引入插件配置

实现在使用函数时,无需import引入

①安装依赖
pnpm i unplugin-auto-import
②在vite.config.ts 文件中进行配置
# 导入安装的插件
import AutoImport from 'unplugin-auto-import/vite'
# 进行插件配置
export default defineConfig({
	plugins: [
	AutoImport({
		dts:'src/typings/auto-imports.d.ts',
		imports:['vue', 'uni-app', 'pinia'],
		dirs:['src/composables']
	})
	],
});

(2)vue语法糖支持

①安装依赖
pnpm add -D @vue-macros/reactivity-transform
②开启语法糖
// vite.config.ts
import ReactivityTransform from '@vue-macros/reactivity-transform/vite'

export default defineConfig({
  plugins: [ReactivityTransform()],
})
// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["@vue-macros/reactivity-transform/macros-global" /* ... */]
  }
}

(3)pinia缓存

pinia 官网

Pinia | The intuitive store for Vue.jsIntuitive, type safe, light and flexible Store for Vueicon-default.png?t=O83Ahttps://pinia.vuejs.org/pinia 中文手册

Pinia v2.1.7 - 中文开发文档手册|官方文档中文版同步翻译更新高质量汉化介绍是什么、它的工作原理、它的用途以及何时使用它。用于 Vue.js 的轻量级状态管理库,基于 Vue 3 Composition API,可以让开发者轻松管理应用程序的状态和副作用。icon-default.png?t=O83Ahttps://ezdoc.cn/docs/pinia/

①安装pinia依赖
pnpm add pinia@2.0.30
②main.ts引入pinia
import { createSSRApp } from "vue";
import { createPinia } from 'pinia';
import App from "./App.vue";

export function createApp() {
  const app = createSSRApp(App).use(createPinia());
  return {
    app,
  };
}

二、封装自定义全局组件

封装前的准备

①src下创建compontents文件夹=》创建index.ts做为所有组件的中转文件

// index.ts
/**自定义全局组件 */
import type { Component } from 'vue';

const components: {
  [propName: string]: Component //字面量类型,每个属性值类型为组件的类型
} = {
}
export default components

②main.ts文件引入组件

import globalComponent from '@/components/index'

export function createApp() {
  const app = createSSRApp(App);

  for (const componentItem in globalComponent) {
    app.component(componentItem, globalComponent[componentItem])
  }
  
  return {
    app
  };
}

1、封装自定义tabbar组件

①在components下创建文件夹m-tabbar=》创建index.vue文件
<script setup lang="ts">
import { onMounted, ref } from "vue";

const urls = ref()
const props = defineProps({
	tabbarValue: {
		type: Number,
		default: 1,
	},
});

onMounted(() => {
	initTabbar()
});

function initTabbar() {
	urls.value = [
		{
			pagePath: '/pages/index/index',
			activeIcon: '../../static/tabbar/index_select.png',
			inActiveIcon: '../../static/tabbar/index.png',
			text: '首页'
		},
		{
			pagePath: '/pages/user/user',
			activeIcon: '../../static/tabbar/user_select.png',
			inActiveIcon: '../../static/tabbar/user.png',
			text: '我的'
		}
	]
}

function selectTabbar(name:any) {
	uni.switchTab({
		url: urls.value[name].pagePath,
	})
}
</script>

<template>
  <view class="m-tabbar">
    <up-tabbar :zIndex="10" :value="tabbarValue" @change="selectTabbar" :fixed="true" :placeholder="false" activeColor="#1890e1"
    :safeAreaInsetBottom="true" inActiveColor="#79766A">
    <up-tabbar-item v-for="(item, index) in urls" :key="index" :text="item.text">
      <template #active-icon>
        <image
          class="u-page__item__slot-icon iconsize"
          :src="item.activeIcon"
        ></image>
      </template>
      <template #inactive-icon>
        <image
          class="u-page__item__slot-icon iconsize"
          :src="item.inActiveIcon"
        ></image>
      </template>
    </up-tabbar-item>
  </up-tabbar>
  </view>
</template>

<style lang="scss" scoped>
.iconsize {
	height: 50rpx;
	width: 50rpx;
	margin-top: 8rpx;
}
</style>
②在components下的中转文件index.ts定义引入组件
/**自定义全局组件 */
import type { Component } from 'vue';
import mTabbar from './m-tabbar/index.vue'

const components: {
  [propName: string]: Component //字面量类型,每个属性值类型为组件的类型
} = {
  mTabbar
}
export default components
③pages.json文件中定义tabBar
"tabBar": {
	"color": "#666666",
	"selectedColor": "#2468F2",
	"borderStyle": "white",
	"backgroundColor": "#fff",
	"list": [
		{
			"pagePath": "pages/index/index"
		},
		{
			"pagePath": "pages/user/user"
		}
	]
}
④使用tabbar

注意:使用自定义tabbar的页面必须要隐藏uni-app默认的tabbar

<mTabbar :tabbar-value="0"></mTabbar>
<script setup lang="ts">
import { onShow } from "@dcloudio/uni-app";

onShow(()=>{
  uni.hideTabBar()
})
</script>
⑤最终效果图 

文章将持续更新...

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WPF中的登录界面

创建如下的目录结构&#xff1a; 2.在App.xaml.cs中设置为先登录验证之后再进入主页面 using Prism.Ioc; using System.Windows; using 校园访客系统.Views;namespace 校园访客系统 {/// <summary>/// Interaction logic for App.xaml/// </summary>public partia…

ros2学习日记_241124_ros相关链接

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

ETAS工具导入DBC生成Com协议栈

文章目录 前言DBC配置关键属性Cobra参数配置Cobra使用isolar工程配置总结前言 ETAS工具导入DBC主要也是生成arxml用的,ETAS推荐使用Cobra导入,本文介绍导入过程及注意事项 DBC配置关键属性 对于普通Com报文,配置为周期发送,及其周期,NmMessage配置为No,示例如下: 对…

Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

如果在docker 容器中安装ros遇到的问题

1.在容器内部无法修改时间&#xff0c;需要在宿主机外边修改时钟。修改时钟&#xff1a; hwclock --systohc或者执行 date -s "2024-11-24 19:25:10"2.容器内部内置有opencv4.5版本&#xff0c;需要卸载&#xff0c;重新安装4.2.0版本。记录折腾好久的卸载过程。 …

排序(Java数据结构)

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。(所有的排序都是默认从小到大排序) 稳定性&#xff1a;假定在待排序的记录序列中&#xff…

AutoDL安装docker问题

在AutoDL上租了卡&#xff0c;安装docker遇到一些问题&#xff1a; 1.执行 sudo docker run hello-world 报错 docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 解决方法 先查看docker有没有启动&#xff0c;…

ArcGIS定义投影与投影的区别(数据和底图不套合的原因和解决办法)

今天介绍一下ArcGIS中定义投影与投影的区别。 给大家解惑一下为什么经常出现自己的数据无法和底图套合的情况。 一 目录 1、ArcGIS定义投影与投影的概念区别 2、ArcGIS定义正确的坐标系 3、ArcGIS动态投影实现套合 4、ArcGIS地理坐标系转投影坐标系&#xff08;错误做法&am…

ChatGPT 桌面版发布了,如何安装?

本章教程教大家如何进行安装。 一、下载安装包 官网地址地址&#xff1a;https://openai.com/chatgpt/desktop/ 支持Windows和MacOS操作系统 二、安装步骤 Windows用户下载之后&#xff0c;会有一个exe安装包&#xff0c;点击运行安装即可。 注意事项&#xff0c;如果Windows操…

鸿蒙开发——根据背景图片来构建特定颜色的蒙版

效果图如下(文字部分马赛克处理)&#xff1a; 最近突然发现网易云和QQ音乐这些图片上方的蒙版颜色不是固定的&#xff0c;而是跟着图片内容走的&#xff0c;想看看能不能在鸿蒙实现&#xff0c;最后凭借俺寻思之力寻思出了一套流程(有bug&#xff0c;有时候蒙版直接透明了&…

clipboard

clipboard 现代复制到剪贴板。无闪光。只有 3kb 的 gzip 压缩。 安装 npm install clipboard --save第三方cdn提供商 <script src"https://cdn.jsdelivr.net/npm/clipboard2.0.11/dist/clipboard.min.js"></script>使用 data-clipboard-target"…

Matlab深度学习(四)——AlexNet卷积神经网络

网络搭建参考&#xff1a;手撕 CNN 经典网络之 AlexNet&#xff08;理论篇&#xff09;-CSDN博客 在实际工程应用中&#xff0c;构建并训练一个大规模的卷积神经网络是比较复杂的&#xff0c;需要大量的数据以及高性能的硬件。如果通过训练好的典型网络稍加改进&#xf…

《Python基础》之循环结构

目录 简介 一、for循环 1、基本语法与作用 2、使用 range() 函数配合 for 循环 3、嵌套的for循环 二、while循环 1、基本语法与作用 2、while 循环嵌套 &#xff08;1&#xff09;、while循环与while循环嵌套 &#xff08;2&#xff09;、while循环与for循环嵌套 简介 …

深入探索JMeter bin目录中的Properties文件:优化性能测试的关键

引言 在现代软件开发中&#xff0c;性能测试是确保应用质量和用户体验的重要环节。Apache JMeter作为一款流行的开源性能测试工具&#xff0c;提供了丰富的功能来模拟各种用户行为和负载情况。本文将深入探讨JMeter中的Properties&#xff08;属性&#xff09;功能&#xff0c…

第三十九篇 ShuffleNet V1、V2模型解析

摘要 ShuffleNet V1 ShuffleNet V1是由旷视科技&#xff08;Megvii&#xff0c;又称Face&#xff09;在2017年底提出的一种轻量级卷积神经网络架构。该网络专为移动设备和边缘计算环境设计&#xff0c;旨在以较低的计算资源实现高效的图像分类和其他计算机视觉任务。 特点与…

JavaScript练习——文本与图形

要求实现下面这个效果&#xff1a; 观察图片&#xff0c;我们的需求如下&#xff1a; 准备画布和上下文&#xff1a;在开始绘制之前&#xff0c;需要有一个HTML5 <canvas> 元素&#xff0c;并且获取其绘图上下文&#xff08;context&#xff09;&#xff0c;这是进行绘图…

[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案

问题log /tmp/ccByifPx.o: In function main: read.c:(.text0x1a): undefined reference to shm_open read.c:(.text0xd9): undefined reference to shm_unlink collect2: error: ld returned 1 exit status 程序代码 #include <stdio.h> #include <stdlib.h> #…

【redis】哈希类型详解

哈希类型详解 一、哈希类型的介绍二、哈希类型的常用命令2.1 HSET2.2 HGET2.3 HEXISTS2.4 HDEL2.5 HKEYS2.6 HAVLS2.7 HGETALL2.8 HMGET2.9 HLEN2.10 HSETNX2.11 HINCRBY2.12 HINCRBYFLOAT 三、哈希类型命令小结四、哈希类型内部编码五、哈希类型应用场景 一、哈希类型的介绍 …

单片机GPIO的8种工作模式

1、输入 GPIO_MODE_AIN:模拟输入 GPIO_MODE_IN_FLOATING:浮空输入 GPIO_MODE_IPD:下拉输入 GPIO_MODE_IPU:上拉输入 2、输出 GPIO_MODE_OUT_OD:开漏输出&#xff08;特殊情况使用&#xff09; GPIO_MODE_OUT_PP&#xff1a;推挽输出-----点灯&#xff08;通用&#…

YOLO-World解读:零基础学习开放世界模型

文章目录 一、摘要二、引言相关工作方法预训练公式模型架构可重新参数化的视觉-语言路径聚合网络&#xff08;RepVL-PAN&#xff09; 3.4 预训练方案 实验YOLO-World: 利用多样化数据集进行开放词汇对象检测的预训练方法YOLO-World: LVIS数据集上的零样本性能评估YOLO-World: 预…