从零创建 MESTOOLS 消息弹窗跟练教程
基础软件
https://hx.dcloud.net.cn/Tutorial/install/windows
https://nodejs.org/zh-cn/download
https://git-scm.com/install/windows
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
node --version 检查 Node.js
corepack --version
npm install --global corepack@latest
corepack enable pnpm
corepack prepare pnpm@10.20.0 --activate
pnpm --version
pnpm --version 检查 pnpm
git --version 检查 Git
pnpm view create-unibest version 检查脚手架版本
## 2. 创建独立练习目录
### 文件
本阶段创建独立目录,
New-Item -ItemType Directory -Force -Path 'c:\MESTOOLS从零跟练'
Set-Location 'c:\MESTOOLS从零跟练'
pnpm create unibest@4.0.16 mestools-from-zero -p "h5,app" -u none
参数含义:
- mestools-from-zero:项目目录名。
- -p "h5,app":只准备 H5 和 App 平台。PowerShell 中逗号会用于构造数组,因此这个参数必须加引号。
- -u none:不安装额外 UI 库。
- 没有 -l:不添加登录策略。
- 没有 -i:不添加多语言。
- 没有图表参数:不添加图表依赖。
项目目录应为:
c:\MESTOOLS从零跟练\mestools-from-zero
- [ ] 进入项目
Set-Location 'c:\MESTOOLS从零跟练\mestools-from-zero'
- [ ] 检查依赖
执行:
Test-Path .\node_modules
如果输出 False,执行:
pnpm install
不要全局安装 uni。uni 命令来自项目 node_modules。
- [ ] 检查 Git
执行:
git status --short --branch
如果提示当前目录不是 Git 仓库,才执行:
git init
git add .
git commit -m "chore: 初始化 unibest 项目"
如果脚手架已经初始化 Git,不要再次执行 git init。
---
## 3. 第一次运行脚手架项目
### 文件
本阶段不修改文件。
- [ ] 启动 H5
执行:
pnpm dev:h5 --host 127.0.0.1
预期包含:
Local: http://127.0.0.1:9000/
- [ ] 打开浏览器
访问:
此时看到的是 unibest 默认页面。只要页面能打开且终端没有编译错误,本阶段就通过。
- [ ] 停止开发服务
回到运行终端,按:
Ctrl+C
---
## 4. 使用 HBuilderX 打开正确目录
### 文件
本阶段不修改文件。
开发源码时,HBuilderX 打开整个项目根目录:
c:\MESTOOLS从零跟练\mestools-from-zero
不要只打开:
c:\MESTOOLS从零跟练\mestools-from-zero\src
原因:package.json、pages.config.ts、manifest.config.ts、vite.config.ts 和环境文件都在项目根目录。
HBuilderX 操作:
1. 打开 c:\HBuilderX\HBuilderX.exe。
2. 点击“文件”。
3. 点击“打开目录”。
4. 选择 c:\MESTOOLS从零跟练\mestools-from-zero。
5. 等待项目索引完成。
---
## 5. 修改应用名称
### 文件
修改:
env/.env
### 搜索锚点
搜索:
VITE_APP_TITLE
### 修改前
脚手架通常生成:
VITE_APP_TITLE = 'unibest'
### 操作
只替换这一行:
VITE_APP_TITLE = 'MESTOOLS'
### 修改后检查
文件开头应包含:
VITE_APP_TITLE = 'MESTOOLS'
VITE_APP_PORT = 9000
保存文件。
---
## 6. 配置 Android 基础信息
### 文件
修改:
manifest.config.ts
本教程只构建 App 资源,不提交云打包。配置包名可以让后续 App 配置保持明确。
### 搜索锚点
搜索:
/* android打包配置 */
### 操作
在该注释下面找到完整的 android 配置块。用下面内容替换从 androic: { 开始到它对应的 }, 结束的整个代码块:
androic: {
packagename: 'com.mestools.fromzero',
minSdkVersion: 21,
targetSdkVersion: 30,
abiFilters: ['armeabi-v7a', 'arm64-v8a'],
permissions: [],
},
### 修改后局部效果
distribute: {
/* android打包配置 */
androic: {
packagename: 'com.mestools.fromzero',
minSdkVersion: 21,
targetSdkVersion: 30,
abiFilters: ['armeabi-v7a', 'arm64-v8a'],
permissions: [],
},
/* ios打包配置 */
ios: {},
保存文件。
说明:脚手架 AppID 可能属于模板作者。builc:app 生成 App 资源不受影响;如果以后要进行 DCloud 云打包,必须在 HBuilderX 中为自己的账号重新获取 AppID。
---
## 7. 配置全局导航栏风格
### 文件
修改:
pages.config.ts
### 搜索锚点
搜索:
globalStyle: {
### 修改前
确认找到的是 defineUniPages 内的 globalStyle,不是其他对象。
### 操作
把整个 globalStyle 对象替换为:
globalStyle: {
navigationStyle: 'default',
navigationBarTitleText: 'MESTOOLS',
navigationBarBackgroundColor: '#0789BD',
navigationBarTextStyle: 'white',
backgroundColor: '#F6F8FB',
},
### 修改后局部效果
export default defineUniPages({
globalStyle: {
navigationStyle: 'default',
navigationBarTitleText: 'MESTOOLS',
navigationBarBackgroundColor: '#0789BD',
navigationBarTextStyle: 'white',
backgroundColor: '#F6F8FB',
},
保存文件。
---
## 8. 切换为原生 TabBar
### 文件
修改:
src/tabbar/config.ts
### 8.1 修改 TabBar 策略
搜索锚点:
export const selectedTabbarStrategy
修改前通常为:
export const selectedTabbarStrategy = TABBAR_STRATEGY_MAP.CUSTOM_TABBAR
替换为:
export const selectedTabbarStrategy = TABBAR_STRATEGY_MAP.NATIVE_TABBAR
### 8.2 替换原生 TabBar 列表
搜索锚点:
export const nativeTabbarList
找到从下面代码开始的完整数组:
export const nativeTabbarList: NativeTabBarItem[] = [
一直选中到这个数组对应的:
]
用下面完整代码替换:
export const nativeTabbarList: NativeTabBarItem[] = [
{
iconPath: 'static/tabbar/home.png',
selectedIconPath: 'static/tabbar/homeHL.png',
pagePath: 'pages/index/index',
text: '应用中心',
},
{
iconPath: 'static/tabbar/personal.png',
selectedIconPath: 'static/tabbar/personalHL.png',
pagePath: 'pages/me/me',
text: '我的',
},
]
不要删除后面的 customTabbarList;选择原生策略后,它不会作为当前 TabBar 使用。
### 8.3 修改 TabBar 颜色
搜索锚点:
const _tabbar: TabBar = {
在该对象内找到:
color:
selectedColor:
backgroundColor:
把这三项分别修改为:
color: '#6F7B85',
selectedColor: '#0789BD',
backgroundColor: '#FFFFFF',
修改后局部效果:
const _tabbar: TabBar = {
custom: selectedTabbarStrategy === TABBAR_STRATEGY_MAP.CUSTOM_TABBAR,
color: '#6F7B85',
selectedColor: '#0789BD',
backgroundColor: '#FFFFFF',
保留对象内其他配置。
保存文件。
---
## 9. 重写首页
### 文件
整文件替换:
src/pages/index/index.vue
### 操作
打开文件后按 Ctrl+A 全选,用下面完整内容覆盖:
<script lang="ts" setup>
defineOptions({
name: 'Home',
})
definePage({
type: 'home',
style: {
navigationBarTitleText: 'MESTOOLS',
navigationBarBackgroundColor: '#0789BD',
navigationBarTextStyle: 'white',
},
})
// 打开消息弹窗功能页。
function openMessagePage() {
uni.navigateTo({
url: '/pages/message/index',
})
}
</script>
<template>
<view class="min-h-screen bg-white px-3 pt-6">
<view class="grid grid-cols-4 gap-x-2 gap-y-6">
<button
data-testid="message-entry"
class="message-entry flex flex-col items-center text-center"
@click="openMessagePage"
>
<view class="h-12 w-12 flex items-center justify-center rounded-3 bg-[#4F8CFF]">
<text class="i-carbon-chat text-7 text-white" />
</view>
<text class="mt-2 text-3 text-[#263238]">
消息弹窗
</text>
</button>
</view>
</view>
</template>
<style scoped>
.message-entry {
margin: 0;
padding: 0;
border: 0;
backgrounc: transparent;
line-height: normal;
}
.message-entry::after {
border: 0;
}
</style>
保存文件。
说明:
- data-testid 只是稳定的元素标识,不影响运行。
- 首页使用四列 grid,当前只有第一个入口。
- 原生 button 便于点击和跨端运行。
- message-entry 样式清除 button 默认背景和边框。
- uni.navigateTo 用于进入非 TabBar 页面。
此时消息页面还没创建,点击入口会失败;先不要点击,继续下一步。
---
## 10. 新建消息弹窗页面
### 文件
新建目录:
src/pages/message
新建文件:
src/pages/message/index.vue
### 操作
从第一个字符开始输入以下完整内容:
<script lang="ts" setup>
import { ref } from 'vue'
definePage({
style: {
navigationBarTitleText: '消息弹窗',
},
})
const message = ref('')
// 处理“显示消息”按钮点击事件。
function handleShowMessage() {
if (!message.value.trim()) {
uni.showToast({
title: '请输入内容',
icon: 'none',
})
return
}
uni.showModal({
title: '消息',
content: message.value,
showCancel: false,
})
}
</script>
<template>
<view class="min-h-screen bg-[#F6F8FB] px-5 pt-8">
<input
v-model="message"
class="box-border h-12 w-full rounded-3 bg-white px-4 text-4"
placeholder="请输入要显示的内容"
>
<button
class="mt-5 bg-[#0789BD] text-white"
type="primary"
@click="handleShowMessage"
>
显示消息
</button>
</view>
</template>
保存文件。
关键逻辑:
- ref 保存输入内容。
- trim 只判断是否为空,不改变原始文本。
- uni.showToast 处理空白输入。
- uni.showModal 显示用户原始输入。
- showCancel: false 表示弹窗只显示确定按钮。
当前项目使用页面扫描插件,保存后会根据 definePage 自动生成页面配置。不要手工编辑 src/pages.json。
---
## 11. 重写“我的”页面
### 文件
整文件替换:
src/pages/me/me.vue
### 操作
按 Ctrl+A 全选,用下面完整内容覆盖:
<script lang="ts" setup>
definePage({
style: {
navigationBarTitleText: '我的',
navigationBarBackgroundColor: '#0789BD',
navigationBarTextStyle: 'white',
},
})
</script>
<template>
<view class="min-h-screen flex flex-col items-center justify-center bg-[#F6F8FB] text-[#263238]">
<view class="text-7 font-bold">
MESTOOLS
</view>
<view class="mt-3 text-4 text-[#6F7B85]">
版本 1.0.0
</view>
</view>
</template>
保存文件。
---
## 12. 第一次运行完整 MESTOOLS
### 文件
本阶段不修改文件。
- [ ] 启动 H5
在项目根目录执行:
pnpm dev:h5 --host 127.0.0.1
如果提示:
'uni' 不是内部或外部命令
并同时提示 node_modules missing,执行:
pnpm install
pnpm dev:h5 --host 127.0.0.1
- [ ] 打开首页
访问:
预期:
- 顶部标题 MESTOOLS。
- 首页出现“消息弹窗”入口。
- 底部出现“应用中心 / 我的”。
- [ ] 验证有效输入
1. 点击“消息弹窗”。
2. 输入:
你好 MESTOOLS
3. 点击“显示消息”。
4. 弹窗标题应为“消息”。
5. 弹窗正文应为“你好 MESTOOLS”。
6. 弹窗只有“确定”按钮。
- [ ] 验证空白输入
1. 点击确定关闭弹窗。
2. 清空输入。
3. 输入三个空格。
4. 点击“显示消息”。
5. 页面应显示“请输入内容”。
6. 不应出现消息弹窗。
- [ ] 验证 TabBar
1. 返回首页。
2. 点击“我的”。
3. 确认显示 MESTOOLS 和版本 1.0.0。
4. 点击“应用中心”返回首页。
完成后按 Ctrl+C 停止开发服务。
---
## 13. 执行类型检查
### 文件
本阶段不手工修改文件。
执行:
pnpm type-check
预期退出码为 0,没有 TypeScript 错误。
如果提示找不到 @/pages.json,先执行:
pnpm builc:h5
再执行:
pnpm type-check
原因:src/pages.json 是构建生成文件。不要手工维护它。
---
## 14. 构建 H5
### 文件
本阶段不手工修改文件。
执行:
pnpm builc:h5
预期最后出现:
DONE Build complete.
输出目录:
c:\MESTOOLS从零跟练\mestools-from-zero\dist\build\h5
不要直接双击 dist/build/h5/index.html 验证,因为 file 协议可能影响路由和资源路径。开发阶段继续使用 pnpm dev:h5。
---
## 15. 构建 App 资源
### 文件
本阶段不手工修改文件。
执行:
pnpm builc:app
预期最后出现:
DONE Build complete.
Run methoc: open HBuilderX, import dist\build\app run.
输出目录:
c:\MESTOOLS从零跟练\mestools-from-zero\dist\build\app
注意:
- 这是 App 资源,不是 APK。
- 开发源码时 HBuilderX 打开项目根目录。
- 打包或运行 App 资源时 HBuilderX 导入 dist/build/app。
- 如果以后云打包 APK,需要登录 DCloud,并重新获取当前账号拥有的 AppID。
- 不要使用模板作者的 AppID 提交云打包。
---
## 16. 查看手工修改结果
### 文件
本阶段不修改文件。
执行:
git status --short
主要业务修改应包括:
M env/.env
M manifest.config.ts
M pages.config.ts
M src/pages/index/index.vue
M src/pages/me/me.vue
M src/tabbar/config.ts
?? src/pages/message/
页面扫描或构建可能更新受版本控制的类型文件,例如:
src/types/auto-import.d.ts
src/types/uni-pages.d.ts
这些文件由工具生成,不要手工编辑;如果确认内容只是新增消息页面类型,可以随业务代码一起提交。
查看差异:
git diff -- env/.env manifest.config.ts pages.config.ts src/pages/index/index.vue src/pages/me/me.vue src/tabbar/config.ts src/pages/message/index.vue
新建但尚未加入 Git 的文件不会出现在普通 git diff 中,因此再执行:
Get-Content .\src\pages\message\index.vue
---
## 17. 保存练习进度
### 文件
本阶段只操作 Git。
确认运行和构建均通过后执行:
git add env/.env manifest.config.ts pages.config.ts src/pages/index/index.vue src/pages/me/me.vue src/tabbar/config.ts src/pages/message/index.vue src/types/auto-import.d.ts src/types/uni-pages.d.ts
如果某个生成类型文件没有变化,git add 会忽略它,不影响提交。
提交:
git commit -m "feat: 添加 MESTOOLS 消息弹窗功能"
查看提交:
git log -1 --oneline
---
## 18. 常见问题
### create-unibest 创建失败
先确认网络和版本:
pnpm view create-unibest version
如果项目目录已经存在且包含文件,换一个空目录名,不要覆盖重要项目。
### H5 启动提示 uni 找不到
根因通常是 node_modules 不存在。执行:
pnpm install
pnpm dev:h5 --host 127.0.0.1
不要全局安装 uni。
### 端口 9000 被占用
先关闭旧开发服务,或临时使用:
pnpm dev:h5 --host 127.0.0.1 --port 9001
然后访问终端显示的新地址。
### 点击“消息弹窗”提示页面不存在
检查实际文件:
src/pages/message/index.vue
检查首页路由必须完全一致:
url: '/pages/message/index'
停止并重新启动开发服务,让页面扫描重新执行。
### 首页没有底部 TabBar
检查 src/tabbar/config.ts:
export const selectedTabbarStrategy = TABBAR_STRATEGY_MAP.NATIVE_TABBAR
并确认 nativeTabbarList 的 pagePath 是:
pages/index/index
pages/me/me
### 原生按钮有灰色背景或边框
检查首页 button 是否包含:
class="message-entry flex flex-col items-center text-center"
并确认 style 中同时存在:
.message-entry
.message-entry::after
### HBuilderX 看不到完整配置
确认打开的是:
c:\MESTOOLS从零跟练\mestools-from-zero
而不是:
c:\MESTOOLS从零跟练\mestools-from-zero\src
### builc:app 成功但没有 APK
这是正常现象。pnpm builc:app 只生成:
dist\build\app
APK 需要把该目录导入 HBuilderX,再使用 DCloud 云打包或原生离线打包。
---
## 19. 官方规则参考
uni-app 页面和路由:
https://uniapp.dcloud.net.cn/tutorial/page.html
https://uniapp.dcloud.net.cn/api/router.html
uni-app 页面配置和 TabBar:
https://uniapp.dcloud.net.cn/collocation/pages.html
uni.showToast 和 uni.showModal:
https://uniapp.dcloud.net.cn/api/ui/prompt.html
需要记住的路由规则:
- uni.navigateTo 打开非 TabBar 页面。
- TabBar 页面不能使用 navigateTo,应使用 switchTab 或直接点击原生 TabBar。
- 目标页面必须被页面配置收集。

浙公网安备 33010602011771号