Skip to content

Vue跨端框架

vue框架来啦 🎉🎉🎉 一套基于Vue3 + Uniapp + Pnpm搭建的跨端框架

本框架基于PNPM包管理。所以框架中包含了 后台管理系统uniapp系统 。可以同时进行相关开发任务。
本文档主要用于介绍框架相关信息。帮助你快速上手开发工作

环境要求

  • node >= 18
  • pnpm >= 8

对于node环境管理

Windows系统可以使用 nvm-windows 进行管理
MacOS 系统可以使用 nvmn 进行管理

实验性方案

为了解决环境管理切换的麻烦。还有一种方案是使用volta 项目级node管理方案。
注意:架构部没有真实测评过。有兴趣的可以试试

技术选型

框架针对技术选型框架中涉及的知识点不会进行详尽的解释。你可以前往相关网站自己阅读、查询与学习。

名称说明
vue3流行的MMVM框架
vue-routerVue.js 的官方路由
piniavue官方推荐状态管理库
uniapp使用 Vue.js 开发所有前端应用的框架
antd design vueantd 风格的vue组件库
unocss即时按需原子 CSS 引擎
vite下一代构建工具
awesome-vite与 Vite.js 相关的精彩内容精选列表

框架结构

先来看下项目目录结构。 整体风格与React Taro框架保持一致

txt
├──.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项目

安装

首先安装依赖

bash
pnpm install // 安装依赖

启动

启动后管/uni项目

bash
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开发框架。但是你仍旧可以使用框架进行开发。

打包

项目开发完毕后打包项目

bash
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版本基本完全一致。所以功能介绍参考这里

目录结构

txt

├──.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 状态管理目录。使用pina
  • styles 样式目录。可以自定义修改一些样式
  • utils 工具目录。提供了常用的工具函数

uniapp

本章主要介绍uniapp模块的开发。

首先为了保证React和Vue两个系统框架的一致性。减少跨框架的成本。很多内容设计我们都刻意的做了相同的设计。 比如 custom-tabbar、toast、dialog以及组件库等

对于HBuildX

uni提供了两种模板。编辑器创建(无node_modules模式)和Cli创建独立模板(传统node模式)。这里没有使用第一种的原因是

  • 不被三方强制编辑工具绑定。虽然提供了一定的便利。但是对于错误排查、学习路径和个人职业提升都是比较大的阻碍
  • 与React模板保持一致

目录

txt

├──.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 自定义tabbar
  • interceptors 请求拦截器
  • 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相关依赖。借用官方例子。具体去网站查看

不使用插件:

vue
import { computed, ref } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)

使用插件

vue
// 不需要import直接使用。并且有全量的类型提示

const count = ref(0)
const doubled = computed(() => count.value * 2)

vue-components 自动引入组件

框架使用unplugin-vue-components/vite 来自动导入组件。依然来看一个简单的示例

这是正常的写法:

vue
<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语句引入

这是使用插件的写法

vue
<template>
  <div>
    <Acard title="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

实际上。插件自动帮你补全了相关引用!

警告

在uni中还有个 easycom 也是可以自动引入组件的。这里你可以使用。但是我们并不建议。因为它没有类型提示

事件机制

先说结论: 事件统一使用v-bind模式。而不是emit方式

vue
// 推荐
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 插件创建

最简单的方式是通过公司的美萌插件创建1

使用vscode snippet创建

框架提供了语法snippet。新建文件后键入u3v3。可快速生成模板代码

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

vue
<script setup lang="ts">
import { getCurrentInstance } from 'vue'

const instance = getCurrentInstance() // 必须在 setup 顶层调用
</script>
  • 小程序样式引入图片报错(不生效)

当我们需要在样式文件中引入静态图片时。会这么写

less
.pageStyle {
  min-height: 100vh;
  background-repeat: no-repeat;
  background-image: url(./bg.png);
}

这种写法在H5是生效的。但是在小程序中会报错

txt
[渲染层网络层错误] 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起支持,我们用不了)。所以解决方案是。使用下面的写法

vue
<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>