概述

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到 H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台,并且在 HBuilderX 中可直接打包生成 Android、iOS App。

参考:

DCLOUD-官网

DCLOUD社区:DCloud_heavensoft:DCloud产品综述

DCLOUD:uni小程序 SDK

DCLOUD:uniCloud

凤凰架构:无服务时代

CSDN树洞菇凉:weex、nvue、uni-app 和 nvue开发与vue开发的常见区别

相关

uniCloud

uniCloud 是 DCloud 联合阿里云、腾讯云,为开发者提供的基于 serverless 模式和 js 编程的云开发平台。

  • 免运维,无需关心扩容和攻击
  • 比传统服务器更便宜
  • 全栈,js开发前后端
  • 与uni-app搭配有更高的开发效率

凤凰架构:无服务时代 无服务架构对一些适合的应用确实能够降低开发和运维环节的成本,譬如不需要交互的离线大规模计算,又譬如多数 Web 资讯类网站、小程序、公共 API 服务、移动应用服务端等都契合于无服务架构所擅长的短链接、无状态、适合事件驱动的交互形式;但另一方面,对于那些信息管理系统、网络游戏等应用,又或者说所有具有业务逻辑复杂,依赖服务端状态,响应速度要求较高,需要长连接等这些特征的应用,至少目前是相对并不适合的。

综合以上个人的理解使用serverless(无服务)这个说的有些夸张了,serverless目前来说是一个未来的蓝图,其并不成熟,uniCloud所谓的serverless也没仔细看,时间紧迫先不深究。

uni小程序SDK

  • uni小程序sdk 使用场景是你已经有原生App,在此基础上扩展宿主App的小程序能力,或者用小程序替换原生App的部分功能模块,仅支持uni-app并使用v3编译器
  • App离线sdk 使用场景是你没有原生App,用DCloud的工具来开发App,又不想使用云打包,则可以使用App离线sdk打包发布为原生App,App离线sdk支持5+ App、uni-app,不支持wap2app。虽然App离线sdk也可以集成到已有原生App中,但自从uni小程序sdk推出后,将不再推荐这种用法

词汇

参考:

博客园-这样就好了:uniapp之nvue

nvue(native vue)

weex的Uniapp升级版

  • 不开发App,那么不需要使用nvue
  • 实现app页面的性能优化,使用原生渲染,原生更快
  • 解决前端控件无法覆盖原生控件的层级问题
  • 原生组件问题
  • 等…

除了一些特殊考虑,涉及到app的东西,最好就是看下vue支不支持,不得已再用nvue。

快应用

说白了就是反 微信、支付宝、百度、字节跳动等各家小程序 的垄断,搞了一个支持两种渲染方式的android程序。

安装

准备好NodeJS、Npm

参考:

DCLOUD-Uniapp文档:快手上手

安装Vue cli

Vue CLI是用来创建Vue项目的工具,目前新的Vue3版本项目创建工具是Vite CLI

1
npm install -g @vue/cli

创建模板

1
vue create -p dcloudio/uni-preset-vue [项目名]-frontend
  • 默认模板有两个,其中带(typescript)即可用typescript开发逻辑
  • hello uniapp是Uniapp组件库示例模板
  • 自定义模板,需要填写 uni-app 模板地址,这个地址其实就是托管在云端的仓库地址。以 GitHub 为例,地址格式为 userName/repositoryName

编译&运行

平台
app-plus app平台生成打包资源(支持npm run build:app-plus,可用于持续集成。不支持run,运行调试仍需在HBuilderX中操作)
h5 H5
mp-alipay 支付宝小程序
mp-baidu 百度小程序
mp-weixin 微信小程序
mp-toutiao 字节跳动小程序
mp-lark 飞书小程序
mp-qq qq 小程序
mp-360 360 小程序
mp-kuaishou 快手小程序
mp-jd 京东小程序
mp-xhs 小红书小程序
quickapp-webview 快应用(webview)
quickapp-webview-union 快应用联盟
quickapp-webview-huawei 快应用华为

芝士

参考:

DCLOUD:白话uni-app

GitHub:dcloudio:hello-uniapp

DCLOUD插件市场-DCloud前端团队:hello-uniapp 示例工程

uView官网

DCLOUD插件市场-uViewUI:uView2.0重磅发布,利剑出鞘,一统江湖

目录结构

一个uni-app工程,默认包含如下目录及文件(来自Uniap官网),其中标注*的是Hello uni-app的模板所包含的文件夹/目录,此项目是官方uni-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
┌─uniCloud              云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─src/components *符合vue组件规范的uni-app组件目(同Vue)
│ └─comp-a.vue 可复用的a组件
├─utssdk 存放uts文件(移动原生开发相关)
├─src/pages *业务页面文件存放的目录(Vue为views)
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─src/static *存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此(同Vue)
├─src/uni_modules *存放[uni_module](/uni_modules)。
├─src/platforms *存放各平台专用页面的目录,详见
├─nativeplugins App原生语言插件 详见
├─nativeResources App端原生资源目录
│ └─android Android原生资源目录 详见
├─hybrid *App端存放本地html文件的目录,详见
├─src/wxcomponents *存放小程序组件的目录,详见
├─unpackage 非工程代码,一般存放运行或发行的编译结果
├─AndroidManifest.xml Android原生应用清单文件 详见
├─src/main.js *Vue初始化入口文件(同Vue)
├─src/App.vue *应用配置,用来配置App全局样式以及监听 应用生命周期
├─src/manifest.json *配置应用名称、appid、logo、版本等打包信息,详见
├─src/pages.json *配置页面路由、导航条、选项卡等页面类信息,详见
└─uni.scss *这里是uni-app内置的常用样式变量

如果你熟悉小程序开发的话,对比变化如下:

  • 原来app.json被一拆为二。
    • 页面管理,被挪入了uni-app的pages.json;
    • 非页面管理,挪入了manifest.jso
  • 原来的app.js和app.wxss被合并到了app.vue中

开源

分析一个基于前端Uniapp开发的开源项目,名为RF商城,其前后端均开源,后端PHP开发。

参考:

GitHub-stavyan:TinyShop-UniApp

GitHub-stavyan:TinyShop

技术栈

Vue2

不多介绍

Vuex

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。说白了就是页面中的一个状态定义到Vuex的Store中其他地方也同时被共享过去,比如全局主题中的配置参数就需要共享状态。但小程序似乎多了一个步骤,即setStoragegetStorage

参考:

Vue官网:Vuex

/TinyShop-UniApp/src/store/index.js

image-20230222110326398

  • state(存储介质):Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。每个应用将仅仅包含一个 store 实例。存储在 Vuex 中的数据和 Vue 实例中的 data 遵循相同的规则

  • getters(获取):获取state中的参数,一般用三种种方式传参,成员中可以加入计算代码,计算后以缓存方式存入,存入后只要state/传入数据不变就不会再次计算,从而提高性能,详见

    • 属性访问
    • 方法访问
    • mapGetters 辅助函数
  • mutations(修改):更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。详见

    • 事件类型 (type),store.commit('<mutations中的函数>')
    • 回调函数 (handler),store.commit('increment', 10)/store.commit('increment', {amount: 10})大多数情况下,载荷应该是一个对象
  • Action 类似于 mutation,不同在于:

    • Action 提交的是 mutation,而不是直接变更状态。

    • Action 可以包含任意异步操作

      例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // 假设 getData() 和 getOtherData() 返回的是 Promise

      actions: {
      async actionA ({ commit }) {
      commit('gotData', await getData())
      },
      async actionB ({ dispatch, commit }) {
      await dispatch('actionA') // 等待 actionA 完成
      commit('gotOtherData', await getOtherData())
      }
      }

以上常见的访问方式:

  • this.$store前提挂载store全局访问Vue.prototype.$mStore = store
  • mapGetters、mapMutations、mapActions等辅助函数访问

sass-loader

查官网的时候一共有两种sass-loader,分别为 Dart SassNode Sass,其中Dart Sass是官方推荐的,也是本项目所用。它们的作用是将Sass代码经打包转化为css代码,乍一想其实就是安装在devDependencies下的依赖,无需安装在dependencies中,其实几乎所有Node开发的依赖,在使用文档中有安装命令的,无需考虑安装在dependencies/devDependencies,按照依赖包的说明安装基本就没啥大的问题。

官网上声明装一个就好,但此项目Dart SassNode Sass两个都装了。。。

参考:

webpack:sass-loader

安装

1
2
# 装为开发环境依赖
yarn add sass-loader sass -D

flyio

官网在网络请求中有提及,如果选用三方拦截器即可选择flyio/axios。

参考:

DCLOUD-uni-app文档:网络 发起请求

GitHub-wendux:fly

此项目中好像没有用到flyio的拦截器,倒是又导入了一个axios,也是没有用到,本来也想着用axios来实现请求API操作,不过 uni.request 是Uniapp官网提供的,axios可能还不支持多种移动端http请求,看了flyio请求方式支持好多端(官方:目前Fly.js支持的平台包括:Node.js微信小程序WeexReact NativeQuick App 和浏览器,这些平台的 JavaScript 运行时都是不同的。)。

其他依赖

有些非常底层的依赖注释没写,可自行研究。

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
"dependencies": { 
...
// TS语言规范工具(官网说明安装在devDependencies即可)
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"axios": "^0.19.0",
// 官网在网络请求中有提及,如果选用三方拦截器即可选择flyio/axios
"flyio": "^0.6.2",
// 这个包实现了一个全功能的源代码转换,它采用 ECMAScript 2015 或 ES2015 的生成器/收益语法和异步迭代提议,并吐出行为相同的高效 JS-of-today (ES5)。
"regenerator-runtime": "^0.12.1",
// 此处的依赖可能有一个是多余,来自https://webpack.docschina.org/loaders/sass-loader/(webpack官方) sass-loader 需要预先安装 Dart Sass 或 Node Sass(可以在这两个链接中找到更多的资料)。这可以控制所有依赖的版本, 并自由的选择使用的 Sass 实现。
"node-sass": "^4.13.0",
...
}

"devDependencies": {
...
// 规范Git提交说明
"commitizen": "^3.1.2",
// 从 git 元数据生成变更日志
"conventional-changelog-cli": "^2.0.23",
"cz-conventional-changelog": "^2.0.0",
// 现代原生 git 钩子变得简单,在使用git hooks的时候,我们一般会使用husky工具,它可以使本地git hooks变的更加的简单,我们一般会这样使用;
"husky": "^3.0.0",
// 针对暂存的 git 文件运行 linters,不要让它溜进你的代码库!
"lint-staged": "^8.0.0",
// 支付宝小程序的 TypeScript 声明文件。
"mini-types": "0.0.5",
// 自动化版本控制和包发布,使用release-it自动管理版本号和生成CHANGELOG
"release-it": "^10.0.0",
// 微信小程序 API 的 TypeScript 类型定义文件
"miniprogram-api-typings": "^2.9.4",
// Allow postcss to support inline comments,官方文档说明需要安装postcss才可以使用,说明这个依赖没用
"postcss-comment": "^2.0.0",
...
}

MyProject

依赖

除上述开源介绍依赖之外,展示本项目独有依赖。

参考:

uView

uView依赖SCSS,您必须要安装此插件,否则无法正常运行。

至于为什么不使用Uniapp原生,这个火,更好看。

参考:

uView官方文档

安装

1
yarn add uview-ui@2.0.31  

顽固问题

样式不生效

Uniapp中有一个很坑的问题就是你在H5端样式明明没啥问题,但是编译到其他平台出现样式不生效,这个就是常说的“Uniapp坑多”原因之一吧。

以下代码是uView中Radio单选框组件,此组件placement="row"属性使得Radio 单选框显示为横排,但编译在微信小程序不生效,只能竖排显示。

1
2
3
4
5
6
7
8
9
10
 <u-radio-group
class="select-perm"
v-model="sValue"
placement="row"
size="200"
@change="groupChange"
>
<u-radio name="1" label="管理员" size="20" labelSize="18"> </u-radio>
<u-radio name="0" label="普通用户" size="20" labelSize="18"></u-radio>
</u-radio-group>

::v-deep其实是Vue2中提供的深度选择器,可强制将样式穿透到子组件中。这样你可以在父组件的样式表中定义样式,并使其应用到子组件的元素上。

1
2
3
4
5
6
::v-deep .u-radio-group--row {
display: flex;
flex-direction: row;
justify-content: space-evenly;
padding-top: 40rpx;
}