Vue跨端框架
vue框架来啦 🎉🎉🎉 一套基于Vue3 + Uniapp + Pnpm搭建的跨端框架
本框架基于PNPM包管理。所以框架中包含了 后台管理系统 和 uniapp系统 。可以同时进行相关开发任务。
本文档主要用于介绍框架相关信息。帮助你快速上手开发工作
环境要求
- node >= 18
- pnpm >= 8
对于node环境管理
Windows系统可以使用 nvm-windows 进行管理
MacOS 系统可以使用 nvm 或 n 进行管理
实验性方案
为了解决环境管理切换的麻烦。还有一种方案是使用volta 项目级node管理方案。
注意:架构部没有真实测评过。有兴趣的可以试试
技术选型
框架针对技术选型框架中涉及的知识点不会进行详尽的解释。你可以前往相关网站自己阅读、查询与学习。
名称 | 说明 |
---|---|
vue3 | 流行的MMVM框架 |
vue-router | Vue.js 的官方路由 |
pinia | vue官方推荐状态管理库 |
uniapp | 使用 Vue.js 开发所有前端应用的框架 |
antd design vue | antd 风格的vue组件库 |
unocss | 即时按需原子 CSS 引擎 |
vite | 下一代构建工具 |
awesome-vite | 与 Vite.js 相关的精彩内容精选列表 |
框架结构
先来看下项目目录结构。 整体风格与React Taro框架保持一致
├──.editorconfig
├──.gitignore
├──.npmrc
├──.prettierignore
├──.prettierrc
├──.vscode
| ├──settings.json
| └──vue3.code-snippets
├──commitlint.config.js
├──components
| ├──mp-html
| ├──request
| ├──swagger-api-templates
| ├──vite-plugin-access-code
| ├──vite-plugin-msw
| ├──vite-plugin-tinymce-resource
| └──yun
├──lint-staged.config.js
├──package.json
├──packages
| ├──backend-template
| └──uni-template
├──patches
| └──unplugin-vue-components@0.25.2.patch
├──pnpm-lock.yaml
├──pnpm-workspace.yaml
└──README.md
目录解释(仅针对重要内容讲述)
.npmrc
npm配置.prettierrc
代码风格格式化工具。必须遵循 不允许修改.vscode/vue3.code-snippets
vue生成snippets
packages目录文件
backend-template
后管模板源码uni-template
uni模板源码
components目录文件
mp-html
小程序富文本组件request
请求库vite-plugin-access-code
后管权限插件yun
统一云上传库。支持阿里云 腾讯云
开发
项目在git创建之后 通过命令迁出项目源代码后。我们可以进行接下来的开发工作了。让我们看下如何开发一个vue项目
安装
首先安装依赖
pnpm install // 安装依赖
启动
启动后管/uni项目
cd packages/uni-template && pnpm dev // 启动微信小程序
cd packages/uni-template && pnpm dev:h5 // 启动H5开发
cd packages/backend-template && pnpm dev // 启动后台管理系统
命令执行完毕后。
- 微信小程序开发者工具 打开
packages/uni-template/dist/dev/mp-weixin
文件夹 - H5 打开终端输出地址访问页面
- 后管访问终端输出访问页面
命令
你可以在package.json中找到全部的命令。它与React框架是一致的。并且风格统一
提示
Uni 目前没有集成APP开发框架。但是你仍旧可以使用框架进行开发。
打包
项目开发完毕后打包项目
cd packages/uni-template && pnpm build // 打包微信小程序
cd packages/uni-template && pnpm build:h5 // 打包H5开发
cd packages/backend-template && pnpm build:uat // 打包后台管理系统测试环境
cd packages/backend-template && pnpm build // 打包后台管理系统
后管框架
本章节主要介绍backend-template
包中关于后台管理系统的相关介绍。
注: 系统功能与React版本基本完全一致。所以功能介绍参考这里
目录结构
├──.browserslistrc
├──.dockerignore
├──.env
├──.env.development
├──.env.production
├──.env.uat
├──.eslintignore
├──.eslintrc.js
├──.gitattributes
├──.stylelintignore
├──CHANGELOG.md
├──docker-compose.yml
├──Dockerfile
├──docs
├──index.html
├──mocks
├──openapi.config.ts
├──out.txt
├──package.json
├──public
| ├──favicon.ico
| └──iconfont.js
├──README.md
├──src
| ├──App.vue
| ├──assets
| ├──components
| | ├──basic
| | ├──business
| | └──core
| ├──config.ts
| ├──constants
| ├──enums
| ├──hooks
| ├──layout
| ├──locales
| ├──main.ts
| ├──pages
| ├──permission
| | ├──index.ts
| | └──permCode.ts
| ├──plugins
| ├──polyfill.ts
| ├──request
| ├──router
| | ├──asyncModules
| | ├──constant.ts
| | ├──helper
| | ├──index.ts
| | ├──router-guards.ts
| | └──routes
| ├──routes.ts
| ├──store
| ├──styles
| └──utils
├──stylelint.config.js
├──swaggerApi.config.js
├──tsconfig.json
├──types
├──unocss.config.ts
└──vite.config.ts
配置文件
环境变量文件。变量通过 import.meta.env.xxx获取。具体参照文档
.env
通用环境变量配置.env.development
开发环境变量.env.production
生产环境变量.env.uat
测试/UAT环境变量
swaggerApi.config.js
接口生成配置文件types
项目类型声明文件夹unocss.config.ts
unocss配置文件vite.config.ts
vite 配置文件.eslintrc.js
eslint。 不允许修改stylelint.config.js
样式lint
项目文件
index.html
首页mocks
mock数据管理public
公共文件目录
src目录文件
src目录下结构文件介绍
App.vue
项目入口组件assets
需要打包构建的静态资源文件夹。可以包含图片、js等components
组件目录。项目通用组件可以放在这里。框架默认提供了- basic : button 扩展按钮组件、 excel处理组件
- business : 素材库、云上传组件
- core : 拖拽弹窗、动态表格
config.ts
配置文件constants
常量目录enums
枚举目录hooks
通用hook目录layout
布局组件目录locales
国际化。支持提供开箱即用的国际化方案main.ts
项目入口文件pages
页面目录permission
权限相关。导出权限指令和权限code类型。关于权限管理。请看下面介绍plugins
插件目录request
接口请求目录router
路由配置文件。包含路由配置、路由导航守卫等routes.ts
路由名称map表store
状态管理目录。使用pinastyles
样式目录。可以自定义修改一些样式utils
工具目录。提供了常用的工具函数
uniapp
本章主要介绍uniapp模块的开发。
首先为了保证React和Vue两个系统框架的一致性。减少跨框架的成本。很多内容设计我们都刻意的做了相同的设计。 比如 custom-tabbar、toast、dialog以及组件库等
对于HBuildX
uni提供了两种模板。编辑器创建(无node_modules模式)和Cli创建独立模板(传统node模式)。这里没有使用第一种的原因是
- 不被三方强制编辑工具绑定。虽然提供了一定的便利。但是对于错误排查、学习路径和个人职业提升都是比较大的阻碍
- 与React模板保持一致
目录
├──.env
├──.env.development
├──.env.uat
├──.eslintrc.js
├──auto-imports.d.ts
├──components.d.ts
├──index.html
├──out.txt
├──package.json
├──pages.config.ts
├──shims-uni.d.ts
├──src
| ├──App.vue
| ├──assets
| ├──config.ts
| ├──custom-tab-bar
| ├──env.d.ts
| ├──interceptors
| ├──main.ts
| ├──manifest.json
| ├──modules
| | └──@wmeimob
| ├──pages
| ├──pages.json
| ├──request
| ├──shime-uni.d.ts
| ├──static
| ├──store
| └──uni.scss
├──swaggerApi.config.js
├──tsconfig.json
├──uni-pages.d.ts
└──vite.config.ts
uni配置文件
环境变量文件。变量通过 import.meta.env.xxx获取。具体参照文档
.env
生产环境变量.env.development
开发环境变量.env.uat
测试/UAT环境变量
pages.config.ts
uni 的 pages.json文件.eslintrc.js
eslint。 不允许修改swaggerApi.config.js
接口生成配置文件vite.config.ts
vite 配置文件
声明文件
env.d.ts
环境变量声明文件shims-uni.d.ts
声明文件auto-imports.d.ts
自动引入vue等类型声明文件components.d.ts
自动引入组件类型声明文件uni-pages.d.ts
路由配置声明文件src/env.d.ts
src/shime-uni.d.ts
uni src目录
App.vue
主入口组件assets
静态资源目录config.ts
配置文件custom-tab-bar
自定义tabbarinterceptors
请求拦截器main.ts
主文件manifest.json
modules/@wmeimob
美萌组件包 目前组件没有进行单独分包。因为还未完善。会在后面拆出独立分包pages
页面组件pages.json
请勿在此文件做任何修改。在上面的pages.config.ts中进行修改request
请求实例static
静态文件目录store
状态uni.scss
自定义uni样式
开发范式
vue + vite + uniapp 都内置提供了许多的插件或者特性。目的都是为了加速开发效率。同样的,框架也引入了许多这样的插件。这里我们挑选部分特性进行讲解
auto imort
框架使用了unplugin-auto-import/vite。来自动导入了Vue相关引用。使得你无需在组件中手动import相关依赖。借用官方例子。具体去网站查看
不使用插件:
import { computed, ref } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
使用插件
// 不需要import直接使用。并且有全量的类型提示
const count = ref(0)
const doubled = computed(() => count.value * 2)
vue-components 自动引入组件
框架使用unplugin-vue-components/vite 来自动导入组件。依然来看一个简单的示例
这是正常的写法:
<template>
<div>
<Acard title="Hello Vue 3.0 + Vite" />
</div>
</template>
<script>
import { Acard } from 'antd-design-vue'
export default {
name: 'App',
components: {
Acard
}
}
</script>
注意
上面是声明式的写法。setup写法不用声明components引入。但仍旧需要import语句引入
这是使用插件的写法
<template>
<div>
<Acard title="Hello Vue 3.0 + Vite" />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
实际上。插件自动帮你补全了相关引用!
警告
在uni中还有个 easycom 也是可以自动引入组件的。这里你可以使用。但是我们并不建议。因为它没有类型提示
事件机制
先说结论: 事件统一使用v-bind
模式。而不是emit
方式
// 推荐
interface IMMPopupProps {
/**
* 点击。使用props.onClick 而不是 emit('click')
*/
onClick?(): void
}
// 不推荐
const $emit = defineEmit('click')
我们知道在vue中。组件的事件是通过emit的方式进行定义的。并且在vue新版本支持了宏。
那么效果是:如果你在 props 定义参数 onClick。在vue的编译器编译后,父组件可以使用 @click=“”
或 :on-click=“”
形式。即同时支持v-bind 和 emit
但使用 uni 编译到 小程序后,因 uni 的编译器是基于 vue 3.2 版本的,因此 props.onClick
无法触发父组件的 @click
。即props不会自动转换为emit
并且emit
存在 写法复杂 以及 不支持Promise化。因此为保持统一,统一使用 v-bind:on-xxx
进行组件传参
创建模板代码
为了保证编码规范一致性、提升代码开发效率。我们也提供了快捷创建模板代码。让我来看下
使用vscode 插件创建
最简单的方式是通过公司的美萌插件创建
使用vscode snippet创建
框架提供了语法snippet。新建文件后键入u3
或v3
。可快速生成模板代码
Q&A
vue编辑器插件不生效?需要注意的是。
- vue2 使用的 Vetur插件。
- vue3 使用的的Vue - Official。
- 原Volar插件已经废弃。请卸载掉
- 开发vue2需要禁用vue3插件。同样的开发vue3项目需要禁用vue2插件
vue defineProps 表现形式不一致?
在uniapp和后管中使用 defineProps 泛型定义表现形式不太一样。具体为uni无法使用导入的interface类型以及extends类型。
这是因为uniapp底层版本的vue版本过低且一直不升级导致的uniapp 不支持 defineModel
是的。uniapp不支持这个宏(版本太低)。请使用defineProps + defineEmits组合
uniapp 不支持 defineSlots
同上。使用 useSlots
slot.title表现形式不一致?
有时候我们会在子组件内判断父组件是否传入了插槽。正常在vue中。是通过
slots.xxx
来进行判断的。但是这个特性在uni中会有个特殊的表现形式。 简单来说:slots.xxx 在web端返回一个函数 小程序端返回一个true。并且这个Boolean不保证父亲是否真正传递了。解决方案: 需要在 <template #title> 外再包一层 view 并在props上额外声明一个参数给父组件用于显式的声明
vue// popup.vue <MMOverlay> <slot /> <!-- 省略其他 --> <!-- 这里如果父组件传入了footer插槽。子组件才会暴露footer插槽。否则暴漏 --> <view v-if="props.slotSubTitle" class="subTitle"> <!-- 副标题自定义渲染 --> <slot name="subTitle" /> </view> </MMOverlay>
getCurrentInstance()返回null
<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance() // 必须在 setup 顶层调用
</script>
- 小程序样式引入图片报错(不生效)
当我们需要在样式文件中引入静态图片时。会这么写
.pageStyle {
min-height: 100vh;
background-repeat: no-repeat;
background-image: url(./bg.png);
}
这种写法在H5是生效的。但是在小程序中会报错
[渲染层网络层错误] pages/tabbar/home/index.wxss 中的本地资源图片无法通过 WXSS 获取,
可以使用网络图片,或者 base64,或者使用<image/>标签。
请参考文档:https://developers.weixin.qq.com/miniprogram/dev/qa.html#%E6%9C%AC%E5%9C%B0%E8%B5%84%E6%BA%90%E6%97%A0%E6%B3%95%E9%80%9A%E8%BF%87-wxss-%E8%8E%B7%E5%8F%96
原因是uni针对less只用loader进行了处理并未兼容server模式(HBuilderX 2.6.6起支持,我们用不了)。所以解决方案是。使用下面的写法
<template>
<view :style="{ backgroundImage: `url(${bg})` }"></view> // 引入
</template>
<script setup lang="ts">
import bg from './bg.png' // js引入
</script>
<style lang="less" scoped>
@import './index.module.less';
</style>