关于新建uniapp项目时的一些基本问题

木头的喵喵拖孩

主要都是写 Web 端,有时候会需要写 uniapp,但是老是会忘记一些基础概念,所以这里记录一下。

使用 vscode 编写 uniapp 项目

我自己使用 vscode 写代码比 hbuilderx 顺手,并且 vscode 会有一些插件是 hubuilderx 没有的,所以需要使用 vscode 来替代 hbuilderx 编写和管理 uniapp 项目。

当然如果你还是喜欢用 hbuilderx 编写代码,这一章可以不看。

vscode 插件

  • uni-helper
    提供 uni-app API 的代码提示和语法高亮。例如“// #ifdef APP-PLUS”这种语法
  • uni-create-view
    右键快速创建页面、组件,并自动在 pages.json 中注册。
  • uniapp 小程序扩展
    标签可用属性提示,鼠标悬停查看组件文档等功能。

从新建项目开始

基于 vue2 的 uniapp 项目创建命令如下:

1
2
3
4
5
6
7
# 安装vue2命令行工具,如果你已经安装过,可以忽略,如果你不想全局安装,可以忽略 -g 参数
npm install -g @vue/cli
# 创建vue2 for uniapp项目
vue create -p dcloudio/uni-preset-vue my-vue2-for-uniapp
npm install
# 运行/打包,这一步具体命令可以参考项目根目录下的package.json 文件
npm run dev:h5

基于 vue3 的 uniapp 项目创建命令如下:

1
2
3
4
5
6
7
# 安装degit命令行工具,如果你不想全局安装,可以忽略 -g 参数
npm install -g degit
# 创建vue3 for uniapp项目
degit dcloudio/uni-preset-vue#vite my-vue3-project
npm install
# 运行/打包,这一步具体命令可以参考项目根目录下的package.json 文件
npm run dev:h5

基于 vue3 + ts 的 uniapp 项目创建命令如下:

1
2
3
4
5
6
7
# 安装degit命令行工具,如果你不想全局安装,可以忽略 -g 参数
npm install -g degit
# 创建vue3 for uniapp项目
degit dcloudio/uni-preset-vue#vite-ts my-vue3-ts-project
npm install
# 运行/打包,这一步具体命令可以参考项目根目录下的package.json 文件
npm run dev:h5

注意:

  • 对于微信小程序的项目,命令执行后,用微信开发者工具导入项目下的 dist/dev/mp-weixin 目录即可预览和调试。
  • APP 平台限制:这是最重要的一点。如果你需要开发 APP,并且希望直接打包成 apk 或 ipa 文件,那么最终还是需要用到 HBuilderX 的云端打包功能。CLI 方式只能生成用于离线打包的 wgt 包

jsonc 处理

普通的 json 文件不允许使用注释,但是 jsonc(JSON with Comments) 文件允许使用注释。对于 uniapp 项目里的 manifest.json 文件和 pages.json 文件,建议改为 jsonc 文件格式。
改动方式为:打开文件,在 vscode 编辑器的右下角会显示当前文件类型,此时为 JSON,点击 JSON 图标,切换为 jsonc 文件格式。

从已有项目开始

通常情况下,一个 uniapp 项目都是在 hbuilderx 里创建的,如果想要将一个一直使用 hbuilderx 管理的项目转为 vscode 可以管理的项目,有哪些办法呢?

有两种办法可以用 vscode 来接手一个 hbuilderx 创建的项目:

  1. 第一是使用 vscode 从头新建一个 uniapp 项目,然后将 hbuilderx 管理的 uniapp 项目的代码迁移到 vscode 里。
  2. 第二是使用 vscode 插件uniapp-run 来调用 hbuilderx 的命令行功能。
    这种方法还是需要安装 hbuilerx,只是不用启动 hbuilderx,直接在 vscode 中使用插件调用 hbuilderx 提供的命令行工具即可。
    这里安装的 hbuilderx 需要是全功能的,一般安装包或者安装目录的名字中带有 “full” 的名字,才能完整的使用其提供的命令行工具。

这里介绍第二种方法。

首先去 vscode 中安装插件uniapp-run
右键点击插件,再点击配置,在配置中填写到你的 hbuilderx 的安装根目录,以及填写你的微信开发者工具的安装根目录
使用 vscode 左侧菜单的运行和调试功能,第一次使用这个功能需要创建一个.vscode/launch.json 文件,点击创建一个 launch.json 文件后,选择插件提供的 Uniapp run 命令来创建 launch.json 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// .vscode/launch.json

{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "uniapp-run",
"request": "launch",
"name": "Uniapp Run",
"platform": "mp-weixin", // mp-weixin、h5、app-plus等平台,和uniapp的平台名称一致。注意!如果你想打包到app-plus平台,目前uniapp-run没办法自动选择基座并安装app包,解决办法是打开hbuilderx然后使用其的“运行”和“发行”功能。
"openDevTool": true, // 显示设置此项为 true ,才能打开微信开发者工具
"vueVersion": "v2"
}
]
}

最后就可以在 vscode 中调试 uniapp 项目了。使用 vscode 左侧菜单的 资源管理器 里面的 运行 UNIAPP 可以方便地开发和构建 uniapp 项目。

如果无法自动启动微信开发者工具,可能是以下原因:

  1. 微信开发者工具没有开启服务端口
  2. manifest.json 中配置的 AppID 是否正确并且确认你已使用有该小程序开发权限的微信号扫码登录了微信开发者工具
    如果只是本地测试,可以尝试在 manifest.json 中暂时不填写 AppID(使用测试号),但部分功能可能会受限

其他问题可以参考uniapp-run

第三方库问题

uniapp 的第三方库管理,一般会使用uni_modules ,主要是为了满足多端开发的兼容性需求。

并不是说 uniapp 就不能使用 node_modules 来管理第三方库了,如果你一定要使用 node_modules 来管理第三方库,那么你一定要注意兼容性问题,比如某些浏览器的特性 API,在小程序里是不能使用的。

页面跳转问题

  • uni.navigateTo
    保留当前页面,跳转到下一个页面,跳转时可以在 url 中传参。跳转后可以使用 uni.navigateBack 方法返回。
  • uni.redirectTo
    uni.navigateTo 类似,关闭当前页面,跳转到下一个页面,跳转后不能返回。
  • uni.reLaunch
    uni.navigateTo 类似,关闭所有页面,跳转到下一个页面,跳转后不能返回。
  • uni.switchTab
    关闭所有其他非 tabBar 页面,跳转到指定 tabBar 页面,url 需要在 pages.json 的 tabBar 中配置,且跳转时不能携带参数。

页面通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template></template>
<script>
export default {
onLoad(query) {
// query 是页面跳转时携带的参数,例如“?id=1” 解析为 { id: 1 }
console.log(query);
},
onLunch(options) {
let query = options.query;
// query 是首次打开小程序携带的参数,例如“?id=1” 解析为 { id: 1 }
console.log(query);
},
};
</script>
<style lang="scss" scoped></style>

如果想在页面之间传递大量数据,可以使用uni.$emit 以及uni.$on
示例如下:

1
2
3
4
5
6
7
8
9
10
<!-- 发送方 -->
<template></template>
<script>
export default {
mounted() {
uni.$emit("myEvent", { msg: "页面更新" });
},
};
</script>
<style lang="scss" scoped></style>
1
2
3
4
5
6
7
8
9
10
<!-- 接受方 -->
<template></template>
<script>
export default {
mounted() {
uni.$on("myEvent", (data) => console.log(data));
},
};
</script>
<style lang="scss" scoped></style>

生命周期问题

应用生命周期

应用生命周期仅可以在 App.vue 中定义,不能在页面中定义。

页面生命周期

vue 组件生命周期

屏幕安全区域问题

如果你的页面需要自定义顶部和底部的样式,比如:

1
2
3
4
5
6
7
8
9
10
11
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom" // 自定义导航栏
}
}
]
}

此时页面会开放屏幕上所有区域供你操作,像 APP 端和小程序端都是在手机上运行的,手机会有顶部状态栏胶囊按钮(小程序特有)以及底部导航栏,这些区域一般是不能放置内容的,不然会出现界面错乱。

如果你使用了第三方组件库的顶部导航栏和底部菜单栏,那么组件库会帮你解决这些安全区域问题。

但如果你就是想自定义导航栏,那么就需要自己去获取安全区域,获取安全区域高度的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// mixin.js

export default {
computed: {
/**
* 安全区域距离顶部高度
*/
safeTop() {
return this.safeAreaInsets.top || 0;
},
/**
* 安全区域距离底部高度
*/
safeBottom() {
return this.safeAreaInsets.bottom || 0;
},
/**
* 小程序胶囊高度
*/
menuButtonHeight() {
return this.menuButtonBoundingClientRect.height || 0;
},
/**
* 小程序胶囊距离顶部高度
*/
menuButtonTop() {
return this.menuButtonBoundingClientRect.top || 0;
},
/**
* 安全区域(包括小程序胶囊)距离顶部高度
*/
safeTopWithMenuButton() {
// #ifdef MP
return this.menuButtonHeight + this.menuButtonTop;
// #endif

return this.safeTop;
},
},

mounted() {
this.initSafeArea();
},

methods: {
/**
* 初始化屏幕安全区域
*/
initSafeArea() {
this.safeAreaInsets = uni.getSystemInfoSync().safeAreaInsets;

// #ifdef MP
this.menuButtonBoundingClientRect = uni.getMenuButtonBoundingClientRect();
// #endif
},
},
};

使用这些安全区域变量的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<view class="container" :style="{ paddingTop: safeTopWithMenuButton + 'px', paddingBottom: safeBottom + 'px' }">
<view class="safe-area">
</view>
</template>

<script>
// 引入mixin
import mixin from "@/mixin.js";

export default {
mixins: [mixin],
};
</>

<style lang="scss" scoped>
.container {
height: 100vh;
background-color: black;
box-sizing: border-box;
.safe-area {
height: 100%;
background-color: gray;
}
}
</style>

图表(charts)开发

推荐使用秋云 uCharts ,简单使用可以在下载页面 下载组件版本如果想自定义一些样式,可以下载原生版本
下载的第三方库需要导入进 uni_modules 文件夹。

演示模板代码
详细文档

地图开发

如果要展示地图,一般会使用 uniapp 自带的map 内置组件 ,其实本质上还是调用第三方地图服务商的资源,所以需要到对应的地图服务商去申请 KEY,
然后将申请到的 KEY 添加到 manifest.json 文件中(一般是配置在“web 配置”或者“安卓/ios 模块配置”)

注意:如果你想更好地使用 map 组件,那么推荐使用nvue 文件
原因有二:第一是 vue 文件中会存在 view 组件无法覆盖原生 map 组件的问题;第二是 nvue 比 vue 能使用的 map 组件的功能更多

获取地理位置城市名

注意:如果你已经在 manifest.json 文件中配置了第三方地图服务商,那么直接使用 uni.getLocation 方法即可,如果返回数据中没有地名,那么可以参考下面的方法

获取地理位置城市名,可以使用 uni.getLocation 方法,但是这个方法获取到的是经纬度,还需要使用 uni.request 方法调用地图服务商获取地理位置信息。

使用 uni.getLocation 这类获取用户隐私信息的 API,都需要在 manifest.json 文件中配置权限。

1
2
3
4
5
6
7
8
9
10
11
12
{
"mp-weixin": {
"appid": "你的appid",
// 添加权限
"permission": {
"scope.userLocation": {
"desc": "获取地址"
}
},
"requiredPrivateInfos": ["getLocation"]
}
}

使用第三方地图服务商提供的 API 时,需要在其开放平台上注册账号获取 KEY,并且为 KEY 配置逆地址解析权限。

对于小程序,需要将所有 uni.request 使用到的域名添加到白名单中。这个操作需要去微信开放平台 中小程序-开发管理里面添加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// mixin.js
export default {
methods: {
getLocationInfo() {
const mapKey = "你的地图服务商KEY";

return new Promise((resolve, reject) => {
uni.getLocation({
type: "gcj02", // 建议使用gcj02,和高德、腾讯地图是兼容的
geocode: true, // 是否解析地址信息,仅App平台支持(安卓需指定 type 为 gcj02 并配置三方定位SDK)
success: (res) => {
let { longitude, latitude, address } = res;

// 如果有地址信息,直接获取地址信息
if (address) {
resolve(res);
return;
}

// 否则使用 request 调用地图服务商获取地址信息
uni.request({
url: "https://restapi.amap.com/v3/geocode/regeo", // 使用高德地图 API 获取地址信息,需要在其官网申请KEY,然后配置“逆地址解析”权限
data: {
key: mapKey,
location: `${longitude},${latitude}`, // 经度在前,纬度在后
output: "JSON",
},
success: (apiRes) => {
if (apiRes.statusCode === 200 && apiRes.data.status === "1") {
const addressComponent =
apiRes.data.regeocode.addressComponent;
resolve({
...res,
address: addressComponent,
});
} else {
reject(apiRes);
}
},
fail: reject,
});
},
fail: reject,
});
});
},
},
};

使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<view>{{ cityName }}</view>
</template>

<script>
// 引入mixin
import mixin from "@/mixin.js";
export default {
mixins: [mixin],
data() {
return {
cityName: "",
};
},
async mounted() {
let locationInfo = await this.getLocationInfo();
this.cityName = locationInfo.address.city;
},
};
</script>

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

nvue

nvue 介绍
nvue 开发与 vue 开发的常见区别

简单介绍:

  • 标题: 关于新建uniapp项目时的一些基本问题
  • 作者: 木头的喵喵拖孩
  • 创建于: 2025-11-25 12:27:44
  • 更新于: 2025-12-23 15:53:58
  • 链接: https://blog.xx-xx.top/2025/11/25/关于新建uniapp项目时的一些基本问题/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。