Appearance
uni-app基础
学习目标:
- 能够搭建 uni-app 基础开发环境
- 知道 uni-app 跨端开发的基本思路
- 掌握安卓真机运行环境配置步骤
- 掌握 uni-app 中关于配置、组件以及 API 的使用
- 掌到 uni-app 跨平台兼容的处理方式
一、搭建基本开发环境
在本节要求大家掌握 uni-app 项目的创建、运行、以及 Android 真机环境配置,内容侧重于动手操作,需要理解的部分较少,操作过程中遇到错误后,可以从头重新进行操作,直到环境正常运行。
1.1 创建项目
在使用 uni-app 框架进行开发时有两种方式来创建项目,一种使用 cli 方式创建,另一种是通过 HBuilder X 方式创建,这两种方式本质上并无差别,采用哪种方式取决于自已项目的定位。
1.1.1 HBuilder X 方式
安装 HBuilder X
HBuilder X 是由 DCloud 推出的开发工具(类似于 VS Code),针对不同的操作系统安装方式也有差异:
- Windows 系统下载的为压缩包,解压缩后找到
HBuilderX.exe双击即可启动 HBuilder X 了,为了方便使用可以创建桌机快捷方式。注意千万不要将 HBuilder X 放到中文目录中! - Mac OS 系统下载的为典型的 Mac OS 的安装
.dmg程序 - 首次启动可根据自已的喜好设置主题和快捷键的风格,如下图所示

- Windows 系统下载的为压缩包,解压缩后找到
HBuilder X 可视化界面创建项目
如下图所示,在【菜单栏】 => 【文件】 => 【新建】 => 【项目】

在打开的窗口中配置项目的基本属性,如项目名称、项目位置、Vue 的版本等,如下图所示

至此我们便完成了 uni-app 项目的创建,如下图所示

1.1.2 vue-cli 方式
uni-app 是基于 Vue.js 开发的框架,如果采用 Vue2 的语法可以使用 vue-cli 来创建项目:
bash
# vue-cli 创建 uni-app 项目
vue create -p dcloudio/uni-preset-vue my-project如果采用 Vue3 的语法可以通过 degit 从 github 仓库下载项目模板方式创建项目:
bash
# 下载 git 仓库中的项目模板
npx degit dcloudio/uni-preset-vue#vite my-vue3-project以上是使用 cli 方式创建基于 Vue2 和 Vue3 项目的操作步骤,一般会使用 VS Code 做为开发工具,这种方式创建的项目在 App 运行、调试、打包方面有所欠缺,因此如果要开发 App 的话,一般不采用该种方式。
1.2 项目运行
在创建的项目中可以看到 Vue 的单文件组件,即 uni-app 创建的项目本质上就是 Vue 的项目,代码逻辑的细节我暂时先不去分析,先来看看 uni-app 的项目是如何启动的。
在 HBuilder X 菜单栏中找到【运行】或者按快捷键 Ctrl + R(Command + R)

- 运行到浏览器,即将项目打包成了 H5 版本了
- 运行到小程序模拟器,即将项目打包成小程序了
- 运行到手机或模拟器,即将项目打包成 App了
至此便不难理解何谓跨端开发了,就是通过编定一套代码,分别打包不同平台的应用。
1.2.1 H5端
H5 端运行有两种方式,一种是运行到浏览器,另一种是运行到内置浏览器,当选择内置浏览器时会提示安装【内置浏览器】插件。

1.2.2 小程序端
运行到小程序端里需要做两种事情,分别是设置小程序的【AppID】 和开启【服务端口】,以微信小程序为例:
设置 AppID

启用服务端口,目的是通过 HBuilder X 自动启动运行小程序开发者工具,启用服务端口的步骤如下:
- 打开微信开发者工具(需要自行安装并登录)
- 【菜单栏】 => 【设置】=> 【安全设置】


1.2.3 App 端
运行到 App 端时需要先安装【真机运行插件】,如下图所示:

等待【真机运行插件】安装完毕后,再次打开【运行】=> 运行到手机或模拟器

从上图中可以看到,运行到 App 时 Android 和 IOS 分别又分为运行到【真机】和【模拟器】
真机,顾名思义就是真实的 Android 和 iPhone 手机
模拟器,是在电脑上虚拟出来的手机环境,Android 需要安装 Android Studio,IOS 需要安装 Xcode
选择【真机】还是【模拟器】呢?
Android 建议使用真机,IOS 建议使用模拟器
======================================================================================
开发 IOS 时只能在 Mac OS 平台下,Android 则在 Mac OS 和 Windows 下都可以,基于这个情况咱们介绍一下如何将 uni-app 项目运行到 Android 真机上。
- 使用 USB 线连接电脑和 Android 手机
- 安装驱动程序(Mac OS 不用安装)
- 开启 USB 调试模式
- 找到【系统设置】=>【系统】=> 【关于手机】=> 【版本号】
- 连续点击版本号,直到提示【开启开发者模式】为止
- 找到【系统设置】=>【系统】=> 【开发者选项】=> 【USB调试】,开启该选项
=======================================================================================
以上的步骤都是准备工作,接下来回到 HBuilder X 中,选择【运行】=>【运行到 Android App 基座】

首次在 App 中运行时还会自动安装【uni-app(Vue3)编译器】,安装完毕后【重新运行】就可以在手机中运行 uni-app 项目了。

没有 Android 手机怎么办?
可以第三方平台的【云手机】服务(一般都是付费的,但是有试用额度),推荐使用腾讯的 WeTest。
1.3 Hbuilder X 插件
HBuilder X 的插件市场提供了大量的插件来提升项目开发的效率,刚刚在运行 uni-app 时就自动安装几个插件,本小节介绍一下 HBuilder X 插件的安装、管理以衣配置。
1.3.1 注册账号
点击 HBuilder X 左下角的用户登录

注册完账号后,再次回到这里来进行登录。
1.3.2 插件市场
找到【菜单】=>【工具】=>【插件安装】,在新打开的窗口中可以看到当前已经安装的插件


1.3.3 安装插件
在插件市场通过搜索方式找到 Prettier 插件

点载下载插件并导入 HBuilder X 会自动打开 HBuilder X,并要求是否确认安装插件

1.3.4 管理/配置插件
打开 HBuilder X 的设置或使用快捷键 Ctrl + , (Command + ,)

安装了 Prettier 插件后默认为启用状态,需要大家补充的是自定义 Prettier 的生效文件范围,添加对 .js 文件的支持,接下来在项目的根目录中创建 .prettierrc 并添加如下配置:
json
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"vueIndentScriptAndStyle": true
}1.3.5 其它配置
除上插件相关配置外,大家还需要对 HBuilder X 本身的设置做一些调整,主要有以下几个方面:
- 项目管理器字体大小
- 编辑器字体大小
- 编辑字体(中文/英文)
- 制表符长度
- 空格代替制表符
- 保存时自动格式化
- 代码折叠时显示最后一行



当配置了【保存自动格式】时,会自动的根据插件来进行代码格式化的处理,由于我们安装了 Prettier 插件,所以此时 HBuilder X 会提示我们是否要选择使用 Prettier 来格式化代码。

二、uni-app 基础知识
uni-app 是组合了 Vue 和微信小程序的相关技术知识,要求大家同时俱备 Vue 和原生小程序的开发基础。
2.1 全局文件
在小程序中有全局样式、全局配置等全局性的设置,为此在 uni-app 中也有一些与之相对应的全局性的文件。
2.1.1 uni.scss
uni-app 项目在运行时会自动将 uni.scss 会自动被注入到页面样式当中,根据这个特性可以在 uni.scss 中定义一些全局 SASS 变量,统一页面的样式风格,如主色调、边框圆角等。
css
/* uni.scss */
/* 在原有 sass 变量基础上添加新的变量 */
$uni-bg-color: #f4f4f4;2.1.2 App.vue
App.vue 在 uni-app 中是一个特殊的文件
html
<script>
// 相当于小程序的 app.js
export default {
onLaunch: function () {
console.log('App Launch')
},
onShow: function () {
console.log('App Show')
},
onHide: function () {
console.log('App Hide')
}
}
</script>
<!-- 组件模板需要被省略 -->
<template></template>
<!-- 组件模板需要被省略 -->
<style>
/* 相当于 app.wxss */
page {
background-color: $uni-bg-color;
}
</style>template组件模板须要省略script相当于小程序的app.jsstyle相当于小程序的app.wxss,为其指定lang="scss"属性后,会自动安装dart-sass插件

2.1.3 pages.json
pages.json 文件即包含了小程序的【全局配置】也包含了【页面配置】:
json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "学习uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}上述是 pages.json 初始的代码,其中
pages对应的是【页面配置】,path指定页面的路径,style为该路径的相关配置,如背景色、导航栏等globalStyle对应【全局配置】的window,用来全局配置页面背景色、导航栏等
那其它的全局配置如何定义呢?比如 tabBar、subPackages
答案是其它的【全局配置】与 globalStyle 平级就可以了
===========================================
重点:tabBar 的图片必须要放到 static 目录下,否则小程序中无法运行
===========================================
先来看关于 tabBar 的配置:
json
{
"pages": [],
"globalStyle": {},
"tabBar": {
"color": "",
"selectedColor": "",
"borderStyle": "",
"position": "",
"list": [
{
"text": "",
"pagePath": "",
"iconPath": "",
"selectedIconPath": ""
}
]
},
"uniIdRouter": {}
}再来看 subPackages 的配置:
json
{
"pages": [],
"globalStyle": {},
"tabBar": {},
"subPackages": [
{
"root": "",
"pages": [
{
"path": "",
"style": {}
}
]
}
],
"uniIdRouter": {}
}其它的【全局配置】,也都采用与 globalStyle 平级的方式来写就可以了。
2.2 组件
在 uni-app 中组件分成内置组件和扩展组件。
2.2.1 内置组件
uni-app 把微信小程序的内置组件都做了重新实现,保证能够在不同的平台表现尽量一致,因此在学习使用uni-app 的组件时,只需要参照微信小程序内置组件即可。
xml
<view class="message">hello uni-app!</view>
<image src="" mode="" />
<swiper autoplay>
<swiper-item>
<image src="" />
</swiper-item>
<swiper-item>
<image src="" />
</swiper-item>
<swiper>内置组件的使用与原生组件基本一致,这里就不过多的演示了。
2.2.2 扩展组件
在 uni-app 中的扩展组件(uni ui)大多是一些业务性与交互性比较强的组件,比如倒计时组件、日历组件、文件上传等,扩展组件是需要下载到项目录目录中才可以使用。

参照文档来使用相应的组件,插件市场也有许多第三方的优秀组件库,如 uView(不支持 Vue3)
2.3 生命周期
在 uni-app 中生命周期也微信小程序一样也分成3个类别,分别是应用级生命周期、页面级生命周期和组件级生命周期,其支持情况可见下表:
| 类型 | 名称 | 应用是否可用 | 页面是否可用 | 组件是否可用 |
|---|---|---|---|---|
| 应用生命周期 | onLauch | 是 | 否 | 否 |
| onShow | 是 | 否 | 否 | |
| onHide | 是 | 否 | 否 | |
| 页面生命周期 | onLoad | 否 | 是 | 否 |
| onShow | 否 | 是 | 否 | |
| onHide | 否 | 是 | 否 | |
| onReady | 否 | 是 | 否 | |
| Vue生命周期 | beforeCreate | 是 | 是 | 是 |
| created | 是 | 是 | 是 | |
| beforeMount | 是 | 是 | 是 | |
| mounted | 是 | 是 | 是 | |
| beforeUpdate | 是 | 是 | 是 | |
| updated | 是 | 是 | 是 | |
| activated | 仅H5 | 仅H5 | 仅H5 | |
| deactivated | 仅H5 | 仅H5 | 仅H5 | |
| beforeDestoryed | 是 | 是 | 是 | |
| destoryed | 是 | 是 | 是 |
当然上表是不需要大家死记硬背的,大家记这样一个原则即可:
【应用生命周期】和【页面生命周期】采用小程序的生命期,自定义【组件生命周期】使用 Vue 的生命周期。
结合 Vue3 的 setup 语法使用【应用生命周期】和【页面生命周期】需要用到 @dcloudio/uni-app 包
html
<script setup>
// Vue 组件生命周期
import { onMounted } from 'vue'
// 应用/页面生命周期(小程序生命周期)
import { onLaunch, onLoad } from '@dcloudio/uni-app'
// ...
</script>2.4 API 调用
2.4.1 命名空间
uni-app 把微信小程序绝大部分的 API 做了重新实现,使其尽量能在不同的平台(H5的限制比较多)中使用,所不同的是在调用这些 API 时,需要将命名空间换成 uni,举例来说明,原来的调用方法为 wx.request 在 uni-app 中则换成 uni.request 即可。
html
<script setup>
import { onLoad } from '@dcloudio/uni-app'
// 页面加载后获取接口数据
onLoad(() => {
// 原来的 wx.request 换成 uni.request
uni.request({
url: '',
success(result) {
console.log(result)
}
})
})
</script>2.4.2 Promise
在原生小程序中有部分的 API 是不支持 Promise 的,比如 wx.request、wx.uploadFile 等,在 uni-app 中对这些 API 的调用方法做了规订,使其即能支持 Promise 也可以支持 callback 方式,它是这样规定的:
- 在调用 API 时,传入
success、fail、complete任意回调函数,即为 callback 方式
javascript
// 回调方式,不返回 Promise
uni.request({
url: 'https://your.api.com/xxx',
success: (result) => {
console.log(result)
}
})
// 如果在调用 API 时传入了 success fail complete 那么不会返回 Promise- 在调用 API 时,没有传入任意回调函数,即为 Promise 方式
javascript
// Promise 方式
const result = uni.request({
url: 'https://your.api.com/xxx'
})
// Promise 对象
console.log(result)返回值为 Promise 时方便配置 async/wait 来获取结果。
2.5 条件编译
uni-app 目标是通过编写一套代码,实现跨端的开发,但是不同的平台之间存在的差异也是事实,很难做到完全一套代码在各个平台都能够兼容,比如 uni.login 这个 API 在 H5 平台就无法被支持,再比如 keep-alive 只能用在 H5 端。
为了解决平台的差异性,特殊情况下需要为不同平台编写合适的代码,且要保证这些代码只在某个的平台下运行,uni-app 提供了条件编译的技术解决方案。
2.5.1 基本语法
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
语法格式为:
#ifdef 平台名称 || 平台名称
特定平台要执行的代码
#endif
#ifndef 平台名称
除了特定平台之外其它平台要执行的代码
#endif下面以 H5 平台来给大家演示具体的语法:
html
<script setup>
// #ifdef H5
console.log('这段代码只在 H5 端才会运行')
// #endif
</script>
<template>
<!-- #ifdef H5 -->
<view class="iconfont icon-search"></view>
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="iconfont icon-scan"></view>
<!-- #endif -->
</template>
<style lang="scss" scoped>
.iconfont {
color: #666;
font-size: 30rpx;
/* #ifdef H5 */
font-size: 28rpx;
/* #endif */
}
</style>2.5.2 平台名称
不同的不台对应了不同的名称,这些名称都是 uni-app 内置提供的,比如 H5、MP-WEIXIN、APP-PLUS 等
| 值 | 生效条件 |
|---|---|
| VUE3 | Vue 版本为 Vue3 |
| APP-PLUS | App 平台,包括 Android 和 IOS |
| APP-ANDROID | Android 平台 |
| APP-IOS | IOS 平台 |
| H5 | H5 平台 |
| MP | 小程序平台,包括所有小程序 |
| MP-WEIXIN | 微信小程序 |
| MP-ALIPAY | 阿里小程序 |
2.6 节点信息
2.6.1 创建查询器
调用APIuni.createSelectorQuery创建一个查询实例uni.createSelectorQuery
js
import { onReady } from '@dcloudio/uni-app'
onReady(() => {
const querySelector = uni.createSelectorQuery()
querySelector.selectAll('.box').boundingClientRect((res) => {
console.log(res)
})
// 获取视口,查找视口的尺寸、滚动位置等信息
querySelector.selectViewport().boundingClientRect((res) => {
console.log(res)
})
// scrollOffset节点滚动位置,仅支持scroll-view组件或者页面viewport
querySelector.selectViewport().scrollOffset((offset) => {
console.log(offset)
})
querySelector.exec()
})注意事项:
- 需要在onMounted或者onReady生命周期中调用
- 选择自定义组件中的节点时,需要调用in方法并传入当前页面实例
js
// vue2
const querySelector = uni.createSelectorQuery().in(this)
// vue3 getCurrentInstance()相当于vue2的this
const querySelector = uni.createSelectorQuery().in(getCurrentInstance())2.7 安全区域
安全区域是指屏幕边缘预留的非内容显示区域,用于避免UI元素被系统组件(如状态栏、底部导航栏)遮挡。在全面屏设备中,安全区域的顶部和底部距离尤为重要。例如:
顶部安全距离:状态栏高度(如iPhone的刘海区域) 底部安全距离:设备底部的传感器区域或虚拟按键区域
在uni-app中,可以通过以下两种方式动态获取安全区域距离:
- JavaScript API:使用 uni.getSystemInfoSync() 获取系统信息
- CSS环境变量:通过 env(safe-area-inset-xxx) 和 constant(safe-area-inset-xxx) 实现样式适配
js
const systemInfo = uni.getSystemInfoSync()
const { safeAreaInsets } = systemInfo
console.log('顶部安全距离:', safeAreaInsets.top)
console.log('底部安全距离:', safeAreaInsets.bottom)css
/* 底部安全区域适配 */
.container {
padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */
}
/* 顶部安全区域适配 */
.header {
padding-top: env(safe-area-inset-top);
}2.8 组件样式隔离
在原生小程序中自定义组件如果引用其他的自定义组件时,通过:deep也无法对组件内部样式进行修改,通过设置原生小程序的样式隔离解决这个问题
vue
<script setup>
// 组合式setup语法糖
defineOptions({
options: {
styleIsolation: 'shared' // 设置样式隔离为共享模式
}
})
</script>
<script>
// 选项式
export default {
options: {
styleIsolation: 'shared'
// 默认值为isolated表示启用样式隔离
}
}
</script>2.9 多色图标
多色图标通过svg支持的,但是微信小程序目前不支持svg格式图片,所以uni-app中多色图标只能用普通图片代替。
- 安装iconfont-tools工具来处理多色图标,将图片转成base64格式的图片
text
npm install -g iconfont-tools mac前面加sudo- 通过命令行切换到多色字体文件所在目录,执行iconfont-tools
text
iconfont-tools
根据引导生成支持多色图标的文件,每个步骤中指定的名称自己任意指定
- 把生成的字体文件color-fonts.css放到项目中,让后在App.vue文件中全局引入
vue
<!-- App.vue -->
<style lang="scss">
// 多色图标
@import 'color-fonts.scss';
</style>2.10 登录后重定向到原页面
在登录页面获取到登录前的页面地址,通常有两种方式:一是通过URL传递参数,另一种是通过Pinia状态管理,但是由于小程序中借助地址传参时存在局限性,因此我们只能选择用Pinia状态管理实现
js
// stores/user.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
// 函数形式 组合式(Setup)语法
export const useUserStore = defineStore(
'user',
() => {
const token = ref('')
// 登陆成功后要跳转的页面,默认为首页
const redirectUrl = ref('/pages/index/index')
// 跳转页面的方式
const openType = ref('switchTab')
return { token, redirectUrl, openType }
},
{
persist: {
paths: ['token', 'redirectUrl', 'openType']
}
}
)小程序中提供了多种路由跳转的API,如uni.switchTab、uni.redirectTo、uni.navigateTo等,tabBar的页面跳转只能使用uni.switchTab,因此登录成功后进行跳转时需要判断页面地址是否为tabBar页面,如果是只能用uni.switchTab跳转,否则用uni.redirectTo跳转
js
// utils/http.js
// tabBar页面路径
const tabBarList = ['pages/index/index', 'pages/wiki/index', 'pages/notify/index', 'pages/my/index']
// 重新登录
function reLogin() {
// 动态读取当前页面的路径
const pageStack = getCurrentPages()
console.log(pageStack, 'pageStack')
const currentPage = pageStack[pageStack.length - 1]
console.log(currentPage, 'currentPage')
// 完整的路由(包含地址中的参数)
const redirectURL = currentPage.$page.fullPath
// 是否为 tabBar 中定义的路径
const openType = tabBarList.includes(currentPage.route) ? 'switchTab' : 'redirectTo'
// 用户相关数据
const userStore = useUserStore()
// 将来再跳转回这个页面
userStore.recirectURL = redirectURL
// 页面(路由)跳转方式
userStore.openType = openType
uni.redirectTo({
url: '/pages/login/index'
})
}uni.reLaunch:关闭所有页面,打开到应用内的某个页面
2.11 跳转后动态设置当前页面的标题
js
uni.setNavigationBarTitle({
title: '新的标题'
})2.12 Socket.IO库
Socket.IO是基于WebSocket进行的二次封装,封装了更多的业务层面的逻辑,如身份认证、事件驱动等。
Socket.IO不仅仅封装了WebSocket,还有基于Ajax的长轮询机制,在不支持WebSocket的环境中会自动降级为Ajax的长轮询机制。
长轮询机制可以粗暴的理解为在一个定时器中不断重复的发Ajax请求,以实现与服务器实时通信的功能。
三、面试题
3.1 请介绍一下优医咨询项目
产品方面:优医咨询是基于uni-app开发的跨平台的在线医疗项目,支持H5、小程序和Android3个平台,包含有医生、患者、药品、百科、订单等多个功能模块
技术栈层面:uni-app跨平台框架、Vue3和Pinia
业务功能层面:有即时通讯、云存储、云函数、在线支付、地图服务等
3.2 举例说明优医咨询项目中应用到哪些技术点
项目中有应用到了许多的技术点
- 腾讯位置服务,结合云函数实现查询物流信息(路线规划)的功能
- uni ui组件库,时间日期组件、倒计时组件、表单组件、文件上传组件、侧滑组件等,获取良好用户体验的同时提升开发项目的效率
- 基于Socket.IO实现了医生与患者的即时通讯
- 解决了在小程序中无法使用多色图标的缺陷
- Pinia管理数据状态并进行持久化处理
3.3有没有使用过分包,介绍分包的使用方式及意义
在使用分包时将具有关联性的页面和资源放到独立的目录中,然后再pages.json中配置该分包的目录位置及该分包中所包含的页面
使用分包的意义在于分包能够优化小程序的性能,配置了分包后只有分包的页面被访问时才会被下载下来相当于实现了按需加载的功能,避免一次性下载全部的代码,用户可以更快速的打开小程序
在配置了分包后还可以结合分包预加载进一步优化分包的加载,在访问某个页面时提前去加载一个即将被访问的分包
使用分包还有一个原因就是小程序限制单个包的文件体积不能超过2M,需要通过分包的方式解决
3.4 介绍一下uni-app中跨端兼容的处理方案并举例说明
使用uni-app的条件编译功能,条件编译在语法上看是代码注释,但在打包代码时会根据该注释为不同的平台生成不同的代码
- 在样式方面,处理不同的平台的样式兼容及刘海屏安全区域
- 在页面结构方面,在不同的平台展示或隐藏某些功能,如在线支付时不同的平台支持不同的支付渠道
3.5 在uni-app项目中使用的组件库
uni-app官方提供了uni ui组件库,该组件库可以从uni-app的插件市场下载,该组件库符合官方的easycom规范,因此无需全局注册即可直接使用
除了uni ui组件库外经常用到的还有uView、uView plus等
3.6 如何在uni-app项目中对标签列表进行缓存
在Vue中可以借助comonent组件和keep-alive来对组件进行缓存,然而在uni-app中无法跨平台兼容keep-alive和component,为了解决这个问题,项目中配合v-show和v-if来实现,v-if保证列表组件只被创建1次,v-show实现切换标签时显示/隐藏列表组件
3.7 项目中即时通讯功能如何实现的
使用Socket.IO即时通讯库来实现的,使用on方法监听事件获取数据,使用emit触发事件发送数据,但是Socket.IO不能支持原生小程序,解决这个问题使用了另一个即时通讯库@hyoga/uni-socket.io该组件库是在Socket.IO的基础上做的二次封装
3.8 在小程序中能否使用多色图标,如何实现
原生小程序不支持使用svg,因此无法直接使用多色图标,为了解决这个问题实用工具iconfont-tools将多色字体图标转换成base64格式的照片,虽然是以图片形式存在的,但是能够像使用字体图标一样来使用,即一个类名对应一个图标
