最近接手了一个小程序开发,从头开始。使用了 uniapp 搭建,以前没有做过小程序开发,着手看文档、查文档。一步一步完成了任务的开发。特此记录开发过程中的问题。

开发建议:

  • 使用 HBuilderX 工具进行开发。通过工具创建项目
  • 遇到原来的 vue 写法怎么不生效,别犹豫去看文档,可能就是不支持。
  • 有时间熟读文档。
  • 跨端最大的问题就是兼容性。

1. 不能采用全局注册的方式注册组件

通常在 components 目录会存放项目中共用的组件,然后暴露install,全局引用安装

  1. // components/index.js
  2. // 各种组件
  3. import Page from "./page.vue";
  4. //
  5. const Components = [Page];
  6. export default {
  7. install: (app) => {
  8. // 注册
  9. Components.forEach((component) => app.component(component.name, component));
  10. },
  11. };
  12. // 然后在 main.js 引用注册
  13. import Vue from "vue";
  14. import Component from "@/components";
  15. // 注册 就可以全局使用了。
  16. Vue.use(Component);

但是在 uniapp 中不生效,有两种方式实现组件注册:

1.1 导入到 main.js 中进行注册

所有的组件直接导入到 mian.js 中,通过 Vue 对象注册即可在其他页面中引用。

要注意的是,注册的组件名必须是字符串,不能是page.name

  1. import Vue from "vue";
  2. import Page from "@/components/page.vue";
  3. Vue.component("page", page);

1.2 特有的 easycom 模式注册组件

只要符合components/组件名称/组件名称.vue 文件存储路径,则不需要手动注册,可直接引用组件。

而且这有助于打包时剔除掉没有使用到的组件。

那现在我们的功能组件存放路径改为components/page/page.vue ,即可全局使用。

也可以在pages.json 配置自定义设置,定义哪些匹配的组件。

  1. {
  2. "easycom": {
  3. "autoscan": true,
  4. "custom": {
  5. // uni-ui 规则如下配置
  6. "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
  7. }
  8. }
  9. }

新加的组件注意清除缓存,重新运行生效。

2. 小程序真机调试包太大,无法上传,分包处理

由于开始项目,所有的 UI 设计图都放在了前端,导致编译后整个包大小超过了 4M。开发时并没有提示这个问题,准备真机测试时,提示无法上传。就去找解决方案。

在采用方案之前耗费了好多时间去手动删除一些不用的文件、删除不用的代码。再一看无济于事,看来代码并占不了多少。

2.1 将所有静态资源都存放到远程服务器上

2.2 采用分包的方式,将主包的体积降下来

分包的方式,刚开始的时候所有的文件都是放在pages下的,pages.jon中 也都配置在 pages中。

需要将初始加载无关的模块拆出来,同 pages 同级目录下。

  1. |———————————————————————————————————— 项目
  2. |—————————————— integral
  3. |——————— rank
  4. |——————— log
  5. |——————— mall
  6. |—————————————— pages
  7. |——————— index
  8. |——————— login
  9. |——————— user
  10. |—————————————— pages.json

pages.jong 通过属性subPackages 配置分包编译。

root 为分包的主目录,pages 目录下的页面,path为相对路径。

  1. {
  2. "pages": [
  3. {
  4. "path": "pages/index/index",
  5. "style": {
  6. "navigationBarTitleText": "首页"
  7. }
  8. },
  9. {
  10. "path": "pages/login/login",
  11. "style": {
  12. "navigationBarTitleText": "登录"
  13. }
  14. }
  15. // ...
  16. ],
  17. "subPackages": [
  18. {
  19. "root": "integral",
  20. "pages": [
  21. {
  22. "path": "rank/rank",
  23. "style": {
  24. "navigationBarTitleText": "排行榜"
  25. }
  26. }
  27. // ...
  28. ]
  29. }
  30. ]
  31. }

然后重新运行,再次真机调试,没有此前的包过大的提示。顺利打开小程序。

分包之后,检查此前已写好的模块之间的跳转。页面路径已经变化,

可以通过预加载的方式帮助我们在进入某个页面时,由框架自动预下载可能需要的分包,提高后续页面进入的启动速度。

以下配置,帮助我们在进入首页后,加载全部的分包。也可以指定加载分包的某个页面,具体查看官网preloadrule

  1. {
  2. "preloadRule": {
  3. "pages/index/index": {
  4. "network": "all",
  5. "packages": ["__APP__"]
  6. }
  7. }
  8. }

3. 内置组件不能绑定 class 的问题

在使用扩展的 UI 组件,比如 uni-ui、uView 等给这些组件绑定 class 时,渲染并不能渲染成功。

只能在给他们包一层view 自定义 calss 。避免全局的样式污染。

4. 定位 API 调用,需要增加授权配置manifest.json

增加配置,允许小程序调用位置的权限接口。然后通过requiredPrivateInfos定义你需要哪些方法。

  1. {
  2. /* 小程序特有相关 */
  3. "mp-weixin": {
  4. // ...
  5. "permission": {
  6. "scope.userLocation": {
  7. "desc": "请求获取地理信息"
  8. }
  9. },
  10. "requiredPrivateInfos": [
  11. "getLocation",
  12. "chooseAddress",
  13. "choosePoi",
  14. "chooseLocation"
  15. ]
  16. }
  17. }

如果我们如果想在小程序中功能使用定位功能,则需要申请高德、腾讯或其他地图的 SDK ,通过拿到的经纬度查询详细地址信息。

uni.getLocation(options)获取当前地理位置。

不能获取到地址中文描述,只能拿到经纬度等其他参数,可以在通过第三方地图服务,获取详细的位置信息。

address 地址信息仅 APP 端支持。

uni.chooseLocation(options) 提供给用户选择位置信息

可以拿到经纬度、位置名称以及详细的 address 中文描述。

5. 主包不能引用分包的组件

通过分包后,降低了主包的大小。但也出现了一个问题就是主包不能复用分包的组件,很容易理解就是访问主包的页面时,分包还不一定加载。

6. 小程序不支持 $attrs \ $listeners

通过对组件进行二次封装、三次封装。底层组件定义的属性、事件如果每层都定义接收,就很麻烦,

在 vue 中,通过属性inheritAttrs: false 不然根元素承载这些属性、时间,然后通过$attrs \ $listeners 绑定到目标元素上。

  1. <template>
  2. <view class="dictionary-picker">
  3. <data-picker v-bind="$attrs" v-on="$listeners"></data-picker>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. inheritAttrs: false,
  9. };
  10. </script>

在 uniapp 中,则是不可以的。他没有 $attrs \ $listeners 这两个属性。

7. 不支持自定义双向绑定model

在 vue 中定义一个组件的输入、输出通过绑定值、然后监听抛出事件处理逻辑,

  1. <script>
  2. export default {
  3. name:'data-picker',
  4. model:{
  5. prop:'value',
  6. event:'change',
  7. },
  8. methods:{
  9. handleChange(val){
  10. this.$emit('change',val)
  11. }
  12. }
  13. }

这样在调用组件时可通过v-model绑定。<data-picker v-model='value' />

在 uniapp 中,则是不可以的。 小程序不支持

8. 不能绑定给 style、class 对象

小程序端不支持绑定对象给 class、style

  1. <template>
  2. <view class="dictionary-picker">
  3. <view :class="boxStyle"></view>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. computed: {
  9. boxStyle() {
  10. return {
  11. active: this.activeTab ? true : false,
  12. };
  13. },
  14. },
  15. };
  16. </script>

这样是不行的,渲染后的元素节点显示 object 。 不通过计算属性,直接在属性上绑定逻辑。

  1. <template>
  2. <view class="dictionary-picker">
  3. <view :class="[activeTab ? 'active' : '']"></view>
  4. </view>
  5. </template>

9. 适配 iphone 底部刘海

在需要适配的页面,元素增加样式。特有的变量safe-area-inset-bottom \ safe-area-inset-bottom

建议这种通用性设置,提供一个基础公共组件page. 通过定义插槽 nav \ header \ main \ footer 插入内容。这是一些公共的样式就不用每个页面去设置。

  1. .footer {
  2. padding-bottom: 0;
  3. // IOS <11.2
  4. padding-bottom: constant(safe-area-inset-bottom);
  5. // iso >11.2
  6. padding-bottom: env(safe-area-inset-bottom);
  7. // 安全距离设置后,一定要设置背景,不然滚动的内容在下方可以看到
  8. background-color: #fff;
  9. }

10. 一些全局的配置色彩,字号 注意单位、格式。

在配置pages.json的一些设置,颜色都是必须是十六进制颜色,不能是 rgb 或 rgba

  • globalStyle.navigationBarBackgroundColor 导航栏背景颜色

  • globalStyle.backgroundColor 下拉显示出来的窗口的背景色

  • tabBar.color tab 上的文字默认颜色

  • tabBar.backgroundColor tab 的背景色

  • tabBar.fontSize 文字默认大小

  • tabBar.iconWidth 图标默认宽度(高度等比例缩放)

  • ...

11. 自定义手机顶部的导航栏。

通常手机顶部信号、电量等一些状态占据手机的部分位子。想让这部分区域也融入到我们的程序中。

配置pages.jons

  1. {
  2. "globalStyle": {
  3. "navigationStyle": "custom"
  4. }
  5. }

设置自定义导航样式,这样你的页面会以手机屏幕的最顶端开始。顶部标题、返回都需要自己去定义了。

12. 在视图中不能直接使用绑定在Vue.prototype上的全局变量

直接在视图使用Vue.prototype上的变量是访问不到的。向下面这样:

  1. <template>
  2. <view>
  3. <img :src="$baseUrl + data.imgUrl" />
  4. </view>
  5. </template>

可以通过计算属性,或者提供一个变量值.

  1. <template>
  2. <view>
  3. <img :src="avatarUrl" />
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. data() {
  9. return {
  10. //
  11. data:{}
  12. }
  13. },
  14. computed: {
  15. avatarUrl() {
  16. return this.$baseUrl + '/upload' + this.data.imgUrl;
  17. }
  18. },

13. 二次封装 uni-ui 组件,更改的组件样式未生效。

微信小程序里的组件之间的样式隔离,只需要增加选项配置,

  1. <script>
  2. export default {
  3. name: 'confirmDialog',
  4. options: {
  5. styleIsolation: 'shared' // 解除样式隔离
  6. },
  7. }

微信官方文档说明 - 样式隔离

14. 使用微信小程序插件 plugin

主要是小程序插件 plugin 的开发文档,在manifest.json 中配置

  1. {
  2. "mp-weixin": {
  3. "appid": "",
  4. "usingComponents": true,
  5. "plugins": {
  6. "myPlugin": {
  7. "version": "版本号",
  8. "provider": "wx8**********75"
  9. }
  10. }
  11. }
  12. }

14.1 在这边引入的插件可全局引用,在需要引入的页面中配置,pages.json

  1. {
  2. "pages": [
  3. {
  4. "path": "pages/login/login",
  5. "style": {
  6. "navigationBarTitleText": "登录",
  7. "enablePullDownRefresh": false,
  8. // 定义微信插件
  9. "mp-weixin": {
  10. "usingComponents": {
  11. "login": "plugin://myPlugin/login"
  12. }
  13. }
  14. }
  15. }
  16. ]
  17. }

然后在页面 login.vue 中使用组件

  1. <template>
  2. <view class="login-box">
  3. <login
  4. :config="loginConfig"
  5. ></login>
  6. </template>

14.2 分包引入插件,只能在分包中使用

pages.json配置,同一个插件不能被多个分包引入,直接放入主包中配置。

  1. {
  2. "subPackages": [
  3. {
  4. "root": "integral",
  5. "pages": [
  6. {
  7. "path": "integralMall/list"
  8. }
  9. ],
  10. "plugins": {
  11. "pluginName": {
  12. "version": "版本号",
  13. "provider": "wx8**********75"
  14. }
  15. }
  16. }
  17. ]
  18. }

15. 拦截器uni.addInterceptor(API,Options)

对于 uni 可调用的全局 API,可通过拦截器来批量处理逻辑,常用就是拦截请求,控制权限。

App.vue 中调用拦截,定义拦截器在未注册时控制某些页面不可访问。

  1. import { Not_register_access_page } from "@/utils/config.js";
  2. export default {
  3. onLaunch: function () {
  4. // 跳转拦截
  5. uni.addInterceptor("navigateTo", {
  6. invoke(config) {
  7. if (
  8. !$this.isRegister &&
  9. !Not_register_access_page.includes(config.url)
  10. ) {
  11. // 不允许访问,则将前置访问的page地址置空
  12. config.url = "";
  13. }
  14. },
  15. });
  16. },
  17. };

拦截器options参数

  • invoke 拦截前触发
  • success 成功回调触发
  • fail 失败回调触发
  • complete 完成回调后触发

uni.removeInterceptor(API)删除拦截器

uniapp 开发微信小程序问题笔记的更多相关文章

  1. 使用uni-app开发微信小程序

    uni-app 开发微信小程序 前言 9月份,开始开发微信小程序,也曾调研过wepy/mpvue,考虑到后期跨端的需求,最终选择使用了uni-app,本文主要介绍如何使用uni-app搭建小程序项目, ...

  2. uni-app开发微信小程序引入UI组件库(Vant-weapp)步骤

    uni-app开发微信小程序引入UI组件库(Vant-weapp)步骤 这里以vant-weapp为例 uni-app官方文档介绍引入组件的方法 1. 新建相关目录 根目录下创建 wxcomponen ...

  3. 使用uView UI+UniApp开发微信小程序

    在前面随笔的介绍中,我们已经为各种框架,已经准备了Web API.Winform端.Bootstrap-Vue的公司动态网站前端.Vue&Element的管理前端等内容,基本都是基于Web A ...

  4. 使用uView UI+UniApp开发微信小程序--判断用户是否登录并跳转

    在<使用uView UI+UniApp开发微信小程序>的随笔中,介绍了基于uView UI+UniApp开发微信小程序的一些基础知识和准备工作,其中也大概介绍了一下基本的登录过程,本篇随笔 ...

  5. 使用uView UI+UniApp开发微信小程序--微信授权绑定和一键登录系统

    在前面随笔<使用uView UI+UniApp开发微信小程序>和<使用uView UI+UniApp开发微信小程序--判断用户是否登录并跳转>介绍了微信小程序的常规登录处理和验 ...

  6. 使用uni-app开发微信小程序之登录模块

    从微信小程序官方发布的公告中我们可获知:小程序体验版.开发版调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败,需使用 <button open-type=" ...

  7. uni-app开发微信小程序的几天时间

    人只有在不断的学习,才能不断的给自己充电,如果我们停止了学习,就像人没有了血脉,就会死亡,近来学习比较忙,压力比较大,整天面对着电脑,敲击代码,从中虽然收获了快乐,但是换来的确实身体的伤痛,最近虽然自 ...

  8. uniapp开发微信小程序跳转出现navigateTo:fail page "pages/user/pages/user/address/address" is not found

    在app.json文件中pages中: ,{ "path" : "pages/user/address/address", "style" ...

  9. 微信小程序入门笔记-开通云开发(3)

    1.介绍 开发者可以使用云开发开发微信小程序.小游戏,无需搭建服务器,即可使用云端能力. 云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API ...

  10. 基于uni-app的微信小程序之分包

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 目录 0. 缘由 1. 关于分包 1.0 这是 官方文档 1.1 注意事项 2.使用方法 2.1 首先你得有个uniapp的微信小程序项目 2.2 ...

随机推荐

  1. C语言------循环结构II

    仅供借鉴.仅供借鉴.仅供借鉴(整理了一下大一C语言每个章节的练习题.没得题目.只有程序了) 文章目录 1 .实训名称 2 .实训目的及要求 3 .源代码及运行截图 4 .小结 1 .实训名称 实训6: ...

  2. 齐博x1头部底部菜单高亮设置

    下面这段是默认模板头部的导航菜单: {php}$menu_choose=config('system_dirname')?config('system_dirname'):'index';{/php} ...

  3. vue3中$attrs的变化与inheritAttrs的使用

    在vue3中的$attrs的变化 $listeners已被删除合并到$attrs中. $attrs现在包括class和style属性. 也就是说在vue3中$listeners不存在了.vue2中$l ...

  4. 如何实现一个SQL解析器

    ​作者:vivo 互联网搜索团队- Deng Jie 一.背景 随着技术的不断的发展,在大数据领域出现了越来越多的技术框架.而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进 ...

  5. SpringBoot→Maven项目快速搭建

    使用软件 :SpringToolSuite4 打开软件后在Package Explorer 栏中点击右键 Spring starter project 等待反应 填写完毕之后点击next     fi ...

  6. 深度剖析Java的volatile实现原理,再也不怕面试官问了

    上篇文章我们讲了synchronized的用法和实现原理,我们总爱说synchronized是重量级锁,volatile是轻量级锁.为什么volatile是轻量级锁,体现在哪些方面?以及volatil ...

  7. Mysql之PXC高可用

    PXC高可用 1.环境准备 pxc1: centos7 10.0.0.7 pxc2: centos7 10.0.0.17 pxc3: centos7 10.0.0.27 pxc4: centos7 1 ...

  8. Pictionary 方法记录

    [COCI2017-2018#5] Pictionary 题面翻译 题目描述 在宇宙一个不为人知的地方,有一个星球,上面有一个国家,只有数学家居住. 在这个国家有\(n\)个数学家,有趣的是,每个数学 ...

  9. Dropout原理分析

    工作流程 dropout用于解决过拟合,通过在每个batch中删除某些节点(cell)进行训练,从而提高模型训练的效果. 通过随机化一个伯努利分布,然后于输入y进行乘法,将对应位置的cell置零.然后 ...

  10. 河北首家城商行传统核心业务国产化,TDSQL突破三“最”为秦皇岛银行保驾护航

    11 月 1 日,秦皇岛银行新一代分布式核心系统成功投产并稳定安全运行超过三个月,标志着秦皇岛银行数字化转型应用和服务水平登上了一个新台阶. 这是秦皇岛银行有史以来规模最大.范围最广.难度最高的一次系 ...