文章目录
-
- 一、创建项目
-
- [1. 安装 Hubilder](#1. 安装 Hubilder)
- [2. 安装安卓模拟器](#2. 安装安卓模拟器)
- [3. 创建项目](#3. 创建项目)
- [4. 运行](#4. 运行)
- [5. 安装依赖](#5. 安装依赖)
-
- [5.1 Pinia](#5.1 Pinia)
- [5.2 其他依赖](#5.2 其他依赖)
- [6. form表单验证](#6. form表单验证)
- [7. loading 全屏](#7. loading 全屏)
- [8. 持久化存储](#8. 持久化存储)
- 问题
-
- [1. 跨域](#1. 跨域)
-
- [1. 问题:跨域](#1. 问题:跨域)
- [2. 解决:在vite.config.js中配置代理(vue3版本)](#2. 解决:在vite.config.js中配置代理(vue3版本))
- [3. 解决:vue.config.js中配置代理(vue2版本)](#3. 解决:vue.config.js中配置代理(vue2版本))
uniApp 官网: https://www.dcloud.io/index.html
一、创建项目
- node 版本
v16.20.2 下载地址: https://pan.quark.cn/s/e8057ca96c4c- node镜像
npm config get registry
返回
https://registry.npmmirror.com/
如果不是这个那么设置镜像
npm config set registry https://registry.npmmirror.com
1. 安装 Hubilder
https://zhuhukang.blog.csdn.net/article/details/128074455
2. 安装安卓模拟器
3. 创建项目
- 通过命令创建
javascript
npx degit dcloudio/uni-preset-vue#vite my-vue3-project
-
安装:
npm install- 增加几个配置来忽略版本提示
manifest.json
javascript"compatible":{ "ignoreVersion":true },- 去掉页面回弹效果:
pages.json
javascript"globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8", "app-plus": { "bounce": "none" } }
- 增加几个配置来忽略版本提示

4. 运行



5. 安装依赖
5.1 Pinia
- 下载
javascript
npm install pinia@2.0.36 --legacy-peer-deps
main.js文件中全局引入
js
import {
createSSRApp
} from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
export function createApp() {
const app = createSSRApp(App);
app.use(createPinia())
return {
app,
};
}
- 新建
store/appInfo.js
javascript
import {defineStore} from 'pinia'
export const useAppInfoStore = defineStore('appInfo',{
state:()=>{
return {
statusbar:0,
navBarHeight:0,
screenWidth:0,
screenHeight:0,
deviceId:"",
deviceBrand:"",
appVersion:""
}
},
getters:{
getAppVersion(state){
return state.appVersion
}
},
actions:{
setInfo(statusbar,navBarHeight,screenWidth,screenHeight,deviceId,deviceBrand,appVersion){
this.statusbar = statusbar;
this.navBarHeight = navBarHeight;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.deviceId = deviceId;
this.deviceBrand = deviceBrand;
this.appVersion = appVersion;
}
}
})
- 使用
js
import { useAppInfoStore } from "./stores/appInfo";
const appInfoStore = useAppInfoStore()
const saveDeviceInfo = (e)=>{
let statusBar = e.statusBarHeight;
const naveBarHeight = 45;
const deviceId = e.deviceId;
const deviceBrand = e.deviceBrand
appInfoStore.setInfo(
statusBar,
naveBarHeight,
e.screenWidth,
e.screenHeight,
deviceId,
deviceBrand,
e.appVersion
)
}
5.2 其他依赖
javascript
npm install md5@^2.3.0 sass@^1.63.6 sass-loader@^13.3.2 --save
6. form表单验证
- 添加 红色星号 作为必填项判断:
required
javascript
<uni-forms-item label="测点名称" name="test_point_name" required>
<uni-easyinput
v-model="formData.test_point_name"
placeholder="请输入"
/>
</uni-forms-item>
javascript
<template>
<uni-forms
ref="baseForm"
:model="formData"
labelWidth="70px"
:rules="rules">
<uni-forms-item label="昵称" name="nickName">
<uni-easyinput v-model="formData.nickName" placeholder="请输入" />
</uni-forms-item>
<uni-forms-item label="手机号" name="phonenumber">
<uni-easyinput
v-model="formData.phonenumber"
placeholder="请输入"
/>
</uni-forms-item>
<uni-forms-item label="邮箱" name="email">
<uni-easyinput v-model="formData.email" placeholder="请输入" />
</uni-forms-item>
<uni-forms-item label="个人简介" name="remark">
<uni-easyinput v-model="formData.remark" placeholder="请输入" />
</uni-forms-item>
</uni-forms>
<button
type="primary"
@click="handleSubmit(currentTitle)"
style="width: 90%"
>
修改
</button>
</template>
javascript
const rules = {
// 对name字段进行必填验证
nickName: {
rules: [{
required: true,
errorMessage: '请输入姓名',
},
// {
// minLength: 3,
// maxLength: 5,
// errorMessage: '姓名长度在 {minLength} 到 {maxLength} 个字符',
// }
]
},
// 对email字段进行必填验证
email: {
rules: [{
required: true,
errorMessage: '请输入邮箱地址',
}]
},
phonenumber: {
rules: [{
required: true,
errorMessage: '请输入电话号',
}]
},
oldPassword: {
rules: [{
required: true,
errorMessage: '请输入旧密码',
}]
},
newPassword: {
rules: [{
required: true,
errorMessage: '请输入新密码',
}]
},
}
const formData = ref({})
const baseForm = ref(null)
const handleSubmit = (flag) => {
// gotoHome()// 错误页面
// const res = await baseForm.value?.validate();
baseForm.value?.validate().then(info => {
if (flag == '基础信息') {
editUserInfo(info).then((res) => {
if (res.code == 200) {
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000
});
uni.switchTab({
url: '/pages/user/user'
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
});
} else {
updatePwd(info).then((res) => {
if (res.code == 200) {
uni.showToast({
title: res.msg,
icon: 'success',
duration: 2000
});
uni.removeStorage({
key: 'access_token',
success: function (res) {
}
});
uni.switchTab({
url: '/pages/login/index'
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
});
}
}).catch((err) => {
})
}
7. loading 全屏

javascript
uni.showLoading({
title: '正在识别中...'
})
javascript
uni.hideLoading()
8. 持久化存储
uniApp中的 uni.setStorageSync 该接口仅用于将数据同步存储到本地缓存,默认永久有效,直至用户主动删除或调用清除接口。若需要实现数据过期机制,需开发者自行处理。
问题
1. 跨域
- 参考来源:在uniapp Vue3版本中如何解决web/H5网页浏览器跨域的问题
- gitee:https://gitee.com/qingnian8/univue3/tree/master/uniapp跨域
1. 问题:跨域
我们在项目中直接使用 request 进行请求时,内置浏览器和小程序是不会产生跨域问题,而在浏览器端中会产生跨域问题
javascript
uni.request({
url: 'https://aip.baidubce.com/baiduApi/oauth/2.0/token',
})

2. 解决:在vite.config.js中配置代理(vue3版本)
这种方案是开发vue项目最普遍的用法,在uniapp项目中依然适用,也是我重点给推荐的方式。
- vue3是适用vite构建及打包的,所以在uniapp项目根目录下创建
vite.config.js,拷贝如下代码:
javascript
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
export default defineConfig({
plugins: [uni()],
server: {
host: "localhost", // 指定服务器应该监听哪个IP地址,默认:localhost
port: 5173, // 指定开发服务器端口,默认:5173
proxy: { // 为开发服务器配置自定义代理规则
// 带选项写法:http://localhost:5173/api/posts -> http://jsonplaceholder.typicode.com/posts
"/h5api": {
target: "http://jsonplaceholder.typicode.com", // 目标接口
changeOrigin: true, // 是否换源
rewrite: (path) => path.replace(/^\/h5api/, ""),
}
}
}
});
- 为了 让 uniapp 解决H5跨域问题兼顾微信小程序,添加
/config.js
javascript
// 系统信息
export const SYSTEM_INFO = uni.getSystemInfoSync()
// 主机地址
export const HOST = 'https://tiyu.baidu.com';
// api服务器
export const API_HOST = SYSTEM_INFO.uniPlatform === 'web' ? '' : HOST;
// api服务代理路径
export const API_PROXY = SYSTEM_INFO.uniPlatform === 'web' ? '/h5api' : ''
- 封装common.js:
/utils/common.js
javascript
import {API_HOST,API_PROXY} from "../config.js"
/**
* 组装接口url
*/
export const packApiUrl = (url = '') => {
if (url.slice(0, 4) === 'http') return url
else return `${API_HOST}${API_PROXY}${url}`
}
- 封装 request 请求:
/utils/request.js
js
import {packApiUrl} from "./common.js"
export function request(config={}){
let {
url,
data={},
method="GET",
header={}
} = config
url =packApiUrl(url);
return new Promise((resolve,reject)=>{
uni.request({
url,
data,
method,
header,
success:res=>{
if(res.data.status==0){
resolve(res.data.data)
}else{
uni.showToast({
title:res.data.message,
icon:"none"
})
reject(res.data.data)
}
},
fail:err=>{
reject(err)
}
})
})
}
- 假设接口为http://jsonplaceholder.typicode.com/posts ,那么发送网络请求的时候就可以使用如下方式了:
/api/apis.js
javascript
import {request} from "@/utils/request.js"
export function apiNbaData(){
return request({
url:"/api/match/playerranking/match/NBA/tabId/60"
})
}
- 使用:
/pages/index/index.vue
js
<template>
<view class="content">
<view class="row" v-for="item in listData">
<image :src="item.logo" mode="aspectFill"></image>
<view class="text">{{item.playerName}}</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import {apiNbaData} from "@/api/apis.js"
const listData = ref([]);
const getData = ()=>{
apiNbaData().then(res=>{
console.log(res);
listData.value = res.data
})
}
getData();
</script>
<style lang="scss" scoped>
.content{
padding:30rpx;
.row{
padding:30rpx 0;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
image{
width: 200rpx;
height: 160rpx;
}
.text{
}
}
}
</style>
3. 解决:vue.config.js中配置代理(vue2版本)
有些同学使用的是vue2版本开发项目,vue2和vue3的构建工具不同,下面介绍一下vue2版本如何配置代理。
- 在根目录下创建vue.config.js
- 拷贝下面的代码
javascript
module.exports = {
devServer: {
disableHostCheck: true,
proxy: {
"/devapi": {
target: "http://jsonplaceholder.typicode.com",
changeOrigin: true,
secure: false,
pathRewrite: {
"^/devapi": "/"
}
}
}
}
}
- 网络请求应用
javascript
uni.request({
url:"/devapi/posts" //这里的/devapi相当于设置的target目标地址
}).then(res=>{
console.log(res);
})