uniapp知识点
uniapp知识点
Kahvia在vscode中开发uniapp
使用命令行创建uniapp项目
此处是vue3+ts。
1 | npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project |
安装插件
- uni-create-view
- uni-helper
- uniapp小程序扩展
TS相关
在根目录创建 tsconfig.json
文件,并进行个性化配置,个性化配置是可选的,没有tsconfig.json
时会自动使用默认配置运行。推荐配置如下:
1 | // tsconfig.json |
vueCompilerOptions以及nativeTags的配置是必须的。否则uniapp的标签比如view会出现类型错误。
baseUrl 和 paths 用于映射@/开头的 import 路径。详情参考TypeScript: TSConfig。
安装TS类型支持包。前者是微信小程序组件的TS类型,后者是uniapp组件的TS类型。这些类型已在上方配置文件中的types添加。
1 | npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types |
json文件相关
在 uniapp 项目中,我们可能会在 json 文件中有注释,vscode 识别 json 文件时,不允许有注释在其中,会报错,如下图所示。
解决方法:在 vscode 的设置中,搜索 associations ,添加文件关联键值对,即 xxx.json jsonc 。如下图所示,报错已消失。
注:.json 文件是标准的 json 格式,除了不允许有注释以外,还有其它的一些严格规则。.jsonc 文件则是拓展的 json 格式,能有注释在其中,以及可以省略 key 的引号等等。像 package.json 这种文件,最好还是不要加注释在里面。
uni-ui
uni-ui 介绍 | uni-app官网 (dcloud.net.cn)
安装 uni-ui 所需的 sass 预处理器和加载器
安装 sass
1 | npm i sass -D 或 yarn add sass -D |
安装 sass-loader
1 | npm i sass-loader@10.1.1 -D 或 yarn add sass-loader@10.1.1 -D |
安装uni-ui
1 | npm i @dcloudio/uni-ui 或 yarn add @dcloudio/uni-ui |
配置uni-ui组件自动导入
1 | // pages.json |
安装 uni-ui 的 ts 类型包
1 | npm i -D @uni-helper/uni-ui-types |
然后在 tsconfig.json 中的 types 里写上对应的类型。现在就可以在 uni-ui 的组件标签上看到对应的类型了。
Pinia
pinia本体
本人采用 vue 版本 3.4.21, pinia 版本 2.0.36,不会发生依赖冲突以及各种报错。
1 | npm i pinia@2.0.36 |
创建 pinia 实例。
1 | import { createApp } from 'vue' |
常用操作
使用 storeToRefs() 取出 store 中的响应式数据。
1 | import { useUserStore } from '../../stores/piniaStores' |
pinia的持久化插件
Home | pinia-plugin-persistedstate (prazdevs.github.io)
1 | npm i pinia-plugin-persistedstate |
注意:是 pinia-plugin-persistedstate 这个插件,而非 pinia-plugin-persist 这个坑比插件。后者使用自定义 Storage 的时候,比如我是用的 uni 的storage,会报错说没有sessionStorage,这让我研究了一下午自己的官方文档,怀疑是自己的问题,最后得出结论是插件官方的问题。
在 main.ts 中配置持久化。
1 | import { createPinia } from 'pinia' |
我配置完成后是如下所示。
1 | import { createSSRApp } from "vue"; |
因为是为了 uniapp 采用的 pinia ,而 uniapp 没有 sessionStorage ,所以在定义 store 的时候需要自定义 storage。参考代码如下。
1 | import { defineStore } from 'pinia' |
关于插件的其它可选配置,可以参照官方文档。
为 uniapp 的请求添加拦截器
拦截器的作用是,在请求发送前拦截请求,或收到请求结果后拦截结果,对请求或结果作一定的处理后,再放行。常用于简化操作,比如发送请求前统一添加域名前缀,或收到请求结果后提取关键数据、展示错误信息等。减少了代码的冗余。ps:比如我以前做项目的时候,都是在一个 js 文件中定义常量 baseUrl,在有请求的页面引入该 js 文件,采用 baseUrl + ‘/user/upload’ 这种形式的代码,这意味着我有多少个请求,我就写了多少个这样的拼接代码,的确写了很多无用代码。
以下代码块则展示了如何添加请求发送前的拦截器。
1 | //utils/http.ts |
uniapp 中没有关于请求结果的拦截器,得用 Promise 手动封装。
1 | //utils/http.ts |
这样一来,自己封装的网络请求模块就完成了。在需要的地方导入使用即可。
注:泛型 T 的使用是为了更好地处理数据。每个请求返回的 data 部分都是变化的,有的是字符数组,有的是对象数组,根据选择使用。
1 | import {http} from '@/utils/http' |
当请求的结果有效,即 resolve 后,该 Promise 对象的状态会变成 fulfilled(已兑现),变量 res 有了有效值,继续执行下面的 log 语句。当请求的结果无效,即 reject 后,该 Promise 对象的状态变为 rejected(已拒绝),此时异步函数直接结束,不会执行下面的 log 语句。
注:Promise 对象的初始状态为 pending(待定)。
uniapp知识点
svg
uniapp 中不支持 svg 标签,所以涉及到的 svg 图片可以转换成 base64 进行使用。
SVG在线工具。通过这个工具我们可以实现上述操作。我就用这个工具将 iconfont 上面的图标转换成了 base64 ,用 img 标签进行了插入。
1 | <img class="searchIcon" src="data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTEwMjQgOTYzLjdMNzU2LjggNjk2LjVjNjAuMi03My42IDk2LjUtMTY3LjUgOTYuNS0yNjkuOEM4NTMuMyAxOTEuNCA2NjEuOSAwIDQyNi43IDBTMCAxOTEuNCAwIDQyNi43czE5MS40IDQyNi43IDQyNi43IDQyNi43YzEwMi4zIDAgMTk2LjMtMzYuMyAyNjkuOC05Ni41TDk2My43IDEwMjRsNjAuMy02MC4zek00MjYuNyA3NjhDMjM4LjUgNzY4IDg1LjMgNjE0LjkgODUuMyA0MjYuN1MyMzguNSA4NS4zIDQyNi43IDg1LjMgNzY4IDIzOC41IDc2OCA0MjYuNyA2MTQuOSA3NjggNDI2LjcgNzY4eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=="> |
自定义导航栏
设置 navigationStyle 为 custom 以取消默认导航栏。然后手写导航栏组件添加到页面中使用即可。
1 | { |
image标签
uniapp 中不能使用 img 标签。使用 img 标签后,会被解析成 image 标签,导致为 img 写的 css 样式失效。
样式隔离
在某些情况下,比如我写了一个组件,里面用到了 uniapp 提供的内置组件,如 uni-file-picker ,当我尝试通过 vue 的样式穿透去修改内置组件的样式时,怎么改都不行,用上 !important 也不行,在调试的时候看穿透的样式根本没修改成功。这时候或许就是 uniapp 自带的样式隔离起了作用。使用以下代码进行样式隔离的取消,可以解决问题。
1 | <script lang="ts"> |
非常傻逼的一个问题。样式隔离。这个文档是微信官方文档,因此推断是微信小程序的特有设定。
禁止手指滑动
在自定义的加载遮罩显示时,需要禁止手指滑动,以防下面的页面被滑动。
在最外层添加 @touchmove.stop.prevent=“() => { }” 。
1 | <template> |
自定义遮罩的位置问题
在 uniapp 中,App.vue 文件中并不能写 template ,所以全局遮罩并不方便实现。 所以需要定义一个遮罩组件,在每个页面分别引入使用。
然而,遮罩放在每个页面的根节点下有时也并不方便。举个例子,遮罩的高度一般是100vh,假设我通过绝对定位对页面进行上左对齐,当页面可以滚动的时候,即页面高度大于100vh的时候,如果我在页面底部触发了遮罩,由于遮罩高度不够,页面底部就是无遮罩状态。如果我对遮罩的高度预设成300vh,可以达到遮住底部的效果,但是遮罩中间的加载用的提示信息又跑到了别处,而不在屏幕中间。想要动态控制遮罩的高度或者其中的文字位置是不现实的,每个页面的高度都不一样,而 uniapp 中又不容易获取滚动高度。
因此,固定遮罩的高度为100vh,尝试调整遮罩的引入位置以及对齐位置才是更合理的做法。比如我在页面底部触发了从底部弹出的弹出层,那么封装一个组件,引入弹出层和遮罩层,将自定义组件标记为相对定位,遮罩层标记为绝对定位,并使遮罩下左对齐。
scroll-view 滚动条问题
在微信小程序中,仅设置 show-scrollbar = “false” 是没用的,同时还要设置 enhanced = “true”。
1 | <scroll-view :scroll-y="true" class="cats" :show-scrollbar="false" :enhanced="true"> |
别用uniapp的这个组件写 flex 布局。因为flex布局中的 align-content 会无效,调了一下午没吊用。🐕都不用。自己写的 flex 布局盒子好用的一批。
第三方组件引入问题
以 NutUi 为例,配置 easycom 自动导入的代码如下所示。
1 | "easycom": { |
可以看到引入规则中的组件名称是短横线命名法。因此在使用组件时,也应使用短横线命名,因为大驼峰命名会导致自动引入出问题,我甚至曾怀疑是 uniapp 的问题,毕竟是真不太好用。
1 | <!-- 有效 --> |
当然有时也会出现大驼峰名称能用的情况,这种情况通常是短横线名称的组件以意想不到的方式被引入了。比如上面代码中两种写法,如果同时存在,你会发现大驼峰形式的也能正常用,因为短横线写法已经引入了这个组件。至于为什么大驼峰不能正常引入组件,我只能猜测 easycom 就是浅显地凭借所写标签名称进行自动引入的。