微信小程序开发学习6(基础加强之使用npm包和全局数据共享及分包【Tab底栏案例改进】)
微信小程序开发学习6(基础加强之使用npm包和全局数据共享及分包)
1、使用npm包
小程序对npm包的支持
目前,小程序中已经支持使用p安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用npm包有如下3个限制:
- 不支持依赖于Node.js内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于C++插件的包
虽然npm上的包有千千万万,当是可以为小程序使用的却不多
1.1、Vant Weapp
Vant Weapp是有赞前端团队开源的一套小程序UI组件库,助力开发者快速搭建小程序应用。它所使用的是MT开源许可协议,对商业使用比较友好。
官方参考文档如下:介绍 - Vant Weapp (youzan.github.io)
1.2、安装Vant组件库
初始化包管理配置文件
npm init -y
初始化成功会在项目的根目录中生成一个package.json文件
1.2.1、通过npm安装(建议指定版本为@1.3.3)
npm i @vant/weapp@1.3.3 -S --production
1.2.2、构建nmp包
目前开发者工具是没有使用npm模块
选项了,构建npm包之后直接使用
1.2.3、修改app.json文件
将 app.json 中的 "style": "v2"
去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。
1.3、使用Vant组件
安装完Vant组件库之后,可以在app.json的usingComponents
节点中引入需要的组件,即可在wxml中直接使用组件。示例代码如下:
"usingComponents": {"van-button": "@vant/weapp/button/index"
}
在Vant Weapp官网对应的组件库中可以看到具体的引入信息
引入组件之后就可以在全局访问了
<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
1.4、定制全局主题样式
Vant Weapp使用css变量
来实现定制主题,基本用法参考:使用 CSS 自定义属性(变量) - CSS(层叠样式表) | MDN (mozilla.org)
基本用法
1.4.1、定义变量
element声明是有作用域的
element {--main-bg-color: brown;
}
1.4.2、使用变量
使用一个局部变量时用 var() 函数包裹以表示一个合法的属性值:
element {background-color: var(--main-bg-color);
}
在小程序中定义主题样式
1.4.3、在app.json中写入css变量,即可对全局生效
在小程序中page就是项目的根节点
page{/*定制警告按钮的背景颜色和边框颜色*/--button-danger-backgrount-color:#C00000;--button-danger-border-color:#C60000;
}
关于定制变量的名称可以查看官方给出的进行修改:vant-weapp/var.less at dev · youzan/vant-weapp (github.com)
1.5、API Promise化
默认情况下,小程序官方提供的异步API都是基于回调函数
实现的
缺点:容易造成回调地狱
的问题,代码可读性、维护性差
API Promise化,指的是通过
额外的配置
,将官方提供的、基于回调函数的异步API,升级改造为基于Promise的异步APl
,从而提高代码的可读性、维护性,避免回调地狱的问题。
1.5.1、实现API Promise化
在小程序中,实现API Promise化主要依赖于miniprogram-api-promise
这个第三方的npm包,安装和使用如下
npm install --save miniprogram-api-promise@1.0.4
每安装一个包都要进行构建
构建之前先将miniprogram_npm
文件夹删除再构建
在小程序入口文件中(app.js)只需要调用一次promisifyAll()方法,即可实现异步API的promise化
// app.js
// 导入miniprogram-api-promise
import {promisifyAll} from 'miniprogram-api-promise'
// 定义成员
const wxp = wx.p = {}
// 调用promisifyAll方法实现promise化【wx被promise化后会挂载到wxp对象】
// 后面就可以使用wx.p来调用promise化后的API了
promisifyAll(wx,wxp)
1.5.2、调用Promise化的异步API
按钮调用
<van-button type="primary" bindtap="getInfo">主要按钮</van-button>
在对应页面.js文件中定义方法
async getInfo(){const {data:res} = await wx.p.request({url:'https://applet-base-api-t.itheima.net/api/get',method:'get',data:{naem:'zs',age:20}})console.log(res)
}
2、全局数据共享
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。
开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。
2.1、小程序中的全局数据共享方法
在小程序中,可以使用mobx-miniprogram
配合mobx-miniprogram-bindings
实现全局数据共享
- mobx-miniprogram用来创建
Store实例对象
- mobx-miniprogram-bindings用来把
Store中的共享数据或方法,绑定到组件或页面中使用
2.2、安装Mobx相关的包
在项目中允许如下命令,安装Mobx相关的包
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
记住删除miniprogram_npm目录
后再构建npm
2.3、创建Stor实例
在项目的根目录中创建一个store的文件夹存放store.js文件
// 在这个js文件中,专门来创建Store的实例对象
import {observable,action} from 'mobx-miniprogram'
// 导出供外界使用
export const store = observable({// 声明共享数据NumA:1,NumB:2,// 计算属性的值,get只读属性不允许修改get sum(){return this.NumA + this.NumB},// 我们不可以在外界直接修改共享的数据,必须通过调用方法的方式进行修改// actions方法,用来修改store中的数据updateNum1:action(function(step){this.NumA += step}),updateNum2:action(function(step){this.NumB += step})
})
2.4、将Store中的成员绑定到页面中
// pages/message/message.js
// 导入指定的方法
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Page({/*** 页面的初始数据*/data: {},/*** 点击按钮调用+1或-1*/btnHandler1(e){console.log(e)this.updateNum1(e.target.dataset.step)},/*** 生命周期函数--监听页面加载*/onLoad(options) {// 将需要的属性字段和方法绑定到当前页面的yhisthis.storeBindings=createStoreBindings(this,{// 数据源store,// 需要绑定的数据和计算值绑定到页面fields:['NumA','NumB','sum'],// 需要绑定的方法actions:['updateNum1','updateNum2']})},/*** 生命周期函数--监听页面卸载*/onUnload() {this.storeBindings.destroyStoreBindings()}
})
绑定之后就可以在页面中进行调用了
<!--pages/message/message.wxml-->
<text>numA的值:{{NumA}}</text>
<view>numB的值:{{NumB}}</view>
<view>{{NumA}} + {{NumB}} = {{sum}}</view>
<view></view>
<van-button type="primary" bindtap="btnHandler1" data-step="{{1}}">NumA+1</van-button>
<van-button type="danger" bindtap="btnHandler1" data-step="{{-1}}">NumA-1</van-button>
2.5、将Store中的成员绑定到组件中
2.5.1、在项目根目录中创建一个numbers
组件
2.5.2、在项目的app.json中注册组件
"usingComponents": {"my-numbers": "./components/numbers/numbers"
}
2.5.3、在页面中使用自定义组件
<my-numbers></my-numbers>
2.5.4、在组件的js文件中绑定store的成员
// components/numbers/numbers.js
// 按需导入
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
// 导入实例
import {store} from '../../store/store'
Component({// 实现自动绑定behaviors:[storeBindingsBehavior],// 绑定关系storeBindings:{// 数据源store,fields:{// 映射的字段:store里的字段被映射NumA:'NumA',NumB:'NumB',sum:'sum'},actions:{updateNum2:'updateNum2'}}
})
2.5.5、在组件中如何使用Store中的成员
<!--components/numbers/numbers.wxml-->
<text>numA的值:{{NumA}}</text>
<view>numB的值:{{NumB}}</view>
<view>{{NumA}} + {{NumB}} = {{sum}}</view>
<view></view>
<van-button type="primary" bindtap="btnHandler2" data-step="{{1}}">numB+1</van-button>
<van-button type="danger" bindtap="btnHandler2" data-step="{{-1}}">NumB-1</van-button>
在组件的js文件中的methods节点创建上面的方法
/*** 组件的方法列表*/
methods: {btnHandler2(e){// 调用映射过来的updateNum2方法this.updateNum2(e.target.dataset.step)}
}
效果
3、分包
分包指的是把一个
完整的小程序项目
,安装需求划分为不同的子包,在构建时打包成不同的分包,用户在实用时按需进行加载
好处:
- 可以优化小程序首次启动的下载时间
- 在多人团队共同开发时可以更好的解耦协作
3.1、分包前后对比
分包前
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后
分包后,小程序项目由1个主包+多个分包
组成
- 主包:一般只包含项目的
启动页面
或TabBar页面
,以及所有分包所需要用到的一些公共资源 - 分包:只包含和当前分包有关的页面和私有资源
3.2、分包的加载规则
在小程序启动时,默认回
下载主包
并启动主包页面
tabBar页面需要放到主包中
当用户进入分包内某个页面时,
客户端回把对应的分包进行下载
,下载后再进行展示非tabbar页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
3.3、分包的体积限制
- 整个小程序所有分包大小不超过16M(主包+所有分包)
- 单个分包/主包大小不可以超过2M
3.4、在项目里面实现分包
在项目的app.json文件中通过
subPackages
节点进行添加分包的路径,与pages节点同级关系
{"pages":["pages/index/index","pages/message/message","pages/contact/contact"],"subPackages": [{"root": "pkgA", // 存放分包的根目录"name": "p1", // 给分包起别名"pages": [ // 当前分包下的所有页面的相对路径"pages/cat/cat","pages/dog/dog"]},{"root": "pkgB","name": "p2","pages": ["pages/apple/apple","pages/dog2/dog2"]}]
}
输入路径之后保存开发者工具就会自动的生成分包的文件信息
3.5、查看主包和分包的体积
在小程序详情的基本信息
页面即可看到
3.6、打包的基本准则
- 小程序按
subpackages
的配置进行分包,subpackages之外的目录将被打包到主包中 - 主包也可以有自己的pages(即最外层的pages字段)
- tabBar页面必须在主页面内
- 分包之间不能相互嵌套
3.7、引用原则
- 主包
无法引用
分包内的私有资源 - 分包之间
不能相互引用
私有资源 - 分包
可以引用
主包内的公共资源
独立分包
独立分包
本质上也是分包
,只不过它比较特殊,可以独立于主包和其他分包而独立运行
1、独立分包和普通分包的区别
是否依赖于主包才能运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下独立运行
2、独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面
配置到独立分包
中:
- 当小程序从普通分包页面启动时,需要先下载主包
- 而独立分包不依赖主包即可运行,可以很大程度上提示分包页面的启动速度
注意:一个小程序中可以有多个独立分包
3、独立分包的建立
在app.json文件中定义,于普通分包的区别就是多了一个independent
属性来绝定为独立分包
"subPackages": [{"root": "pkgB","name": "p2","pages": ["pages/apple/apple","pages/dog2/dog2"],"independent": true}]
}
4、引用原则
独立分包和普通分包以及主包之间是相互隔离的,不能相互引用彼此的资源
- 主包
无法引用
独立分包内的私有资源 - 独立分包之间,不能i相互引用私有资源
- 独立分包和普通分包之间
不能相互引用私有资源
- 特别注意:独立分包中不能引用主包内的公共资源
分包预下载
分包预下载指的是:在进入小程序的某个页面时,
由框架自动预下载可能需要用到的分包
,从而提示进入后续分包页面时的启动速度
1、配置分包预下载
预下载分包的行为,会在进入指定的页面时触发
在app.json中,使用preloadRule
节点定义分包的预下载规则,代码如下
// 分包预下载的规则节点
"preloadRule": {// 指定进入指定页面进行预下载路径"pages/contact/contact": {// 表示在指定的网络模式下进行预下载【all不限网络、wifi为默认】"network": "all",// 表示进入页面后,预下载哪一个分包【通过分包的root或name都可以进行指定】 "packages": ["pkgA"]}}
2、分包预下载的限制
同一个分包中的页面享有
共同的预下载大小限额2M
4、案例-自定义TabBar
用到的知识点:
- 自定义组件
- vant组件库
- Mobx数据共享
- 组件样式隔离
- 组件数据监听器
- 组件的behaviors
- Vant样式覆盖
4.1、实现步骤
自定义tabBar
分为3答步骤,分别是:
配置信息
- 在
app.json
中的tabBar
项指定custom
字段,同时其余tabBar
相关配置也补充完整。 - 所有 tab 页的 json 里需声明
usingComponents
项,也可以在app.json
全局开启。
对应list数组必须要保留,不然可能底版本的不能兼容
"tabBar": {"custom": true, "list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "/images/tabs/home.png","selectedIconPath": "/images/tabs/home-active.png"},{"pagePath": "pages/message/message","text": "消息","iconPath": "/images/tabs/message.png","selectedIconPath": "/images/tabs/message-active.png"},{"pagePath": "pages/contact/contact","text": "我的","iconPath": "/images/tabs/contact.png","selectedIconPath": "/images/tabs/contact-active.png"} ] }
- 在
添加tabBar代码文件
在项目的根目录中创建custom-tab-bar文件夹,命名必须是这一个不能改,并且在文件里面创建一个index组件名称也是不能改的
当index组件创建完成后我们原有的tabBar中的list数组就会被该index.wxml页面结构所覆盖
编写tabBar代码
<van-tabbar active="{{ active }}" bind:change="onChange"><van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info ? item.info:''}}"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item> </van-tabbar>
/*** 组件的初始数据*/ data: {active: 0,list: [{"pagePath": "pages/index/index","text": "首页","iconPath": "/images/tabs/home.png","selectedIconPath": "/images/tabs/home-active.png"},{"pagePath": "pages/message/message","text": "消息","iconPath": "/images/tabs/message.png","selectedIconPath": "/images/tabs/message-active.png",info:0},{"pagePath": "pages/contact/contact","text": "我的","iconPath": "/images/tabs/contact.png","selectedIconPath": "/images/tabs/contact-active.png"}] }
渲染tabBar上的数字徽标
在<van-tabbar-item>标签上通过
info='0'
属性可以指定生成的徽标数,但是不是每一个tabbar都会用到,可以在定义的data数据源中的tabbar需要的选项后面添加info:0
字段来完成指定的选项添加徽标的溢出的解决
在没有解决之前图片的底部是由一个margin-bottom样式撑着导致放大后会看到徽标溢出
在自定义组件中使用 Vant Weapp 组件时,需开启
styleIsolation: 'shared'
选项【在组件.js文件中】// custom-tab-bar/index.js Component({options:{// 启用覆盖样式styleIsolation:'shared'} })
覆盖的样式如下
/* custom-tab-bar/index.wxss */ .van-tabbar-item {--tabbar-item-margin-bottom:0 }
在组件中使用Mobx
// custom-tab-bar/index.js import {selectedIconPath} from 'mobx-miniprogram-bindings' import {store} from '../store/store' Component({behaviors:[selectedIconPath],storeBindings:{store,fields:{sum:'sum'},actions:{}},/*** 数据监听器*/observers:{'sum':function(str){// 修改tabBar中的消息数据this.setData({'list[1].info':str})}} })
效果图
实现tabBar栏的切换
onChange(event) {this.setData({ active: event.detail });// 获取到地址进行跳转wx.switchTab({url: this.data.list[event.detail].pagePath,}) }
解决点击TabBar栏的索引问题
原因:当点击其他的tabbar栏的时候被选中的标识不一定会出现在点击的那个tab栏上
将切换的索引
active
放到公共的组件store
中存储同时也要将
index.wxml
页面所使用的active进行移除在
store.js
公共文件中声明一个方法专门修改索引的updateActiveTabBarIndex:action(function(index){this.activeTabBarIndex = index })
在
index.js
文件中映射store中的新添加字段和修改方法storeBindings:{store,fields:{sum:'sum',active:'activeTabBarIndex' // 映射的索引},actions:{updateActive:'updateActiveTabBarIndex' // 修改索引的方法} }
在页面被切换的时候调用
修改索引方法
onChange(event) {this.setData({ active: event.detail });// 修改切换的索引this.updateActive(event.detail)// 获取到地址进行跳转wx.switchTab({url: this.data.list[event.detail].pagePath,}) }
在页面的标签中添加
action
属性<van-tabbar active="{{active}}" bind:change="onChange"></<van-tabbar>
修改tabBar选中项的文本颜色
在标签上通过active-color="#13A7A0"属性进行修改
<van-tabbar active="{{active}}" bind:change="onChange" active-color="#13A7A0"/>
可以参考官方文档手册:自定义 tabBar | 微信开放文档 (qq.com)
微信小程序开发学习6(基础加强之使用npm包和全局数据共享及分包【Tab底栏案例改进】)相关推荐
- 微信小程序开发学习4(视图与逻辑)
微信小程序开发学习4(视图与逻辑) 1.学习目标 能够知道如何实现页面之间的导航跳转 能够知道如何实现下拉刷新效果 能够知道如何实现上拉加载更多效果 能够知道小程序中常用的生命周期函数 2.页面导航 ...
- web前端-微信小程序开发学习
web前端-微信小程序开发学习 1. 小程序的概述 2. 小程序的项目结构 2.1 小程序项目结构分析 2.2 WXML模版 2.3 小程序的宿主环境 3. 组件 3.1 视图容器类组件 3.2 常用 ...
- 微信小程序开发数据缓存基础知识辨析以及运用实例
微信小程序开发数据缓存基础知识辨析以及运用实例 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的 ...
- bilibili微信小程序开发学习总结
bilibili微信小程序开发学习总结 用来半天学习了微信小程序模仿做了个B站小程序,其实如果有编程基础特别熟悉Vue语法与web的话那小程序基本就是随便玩玩,整体写法与vue一致,页面搭建与web也 ...
- 【微信小程序开发学习篇】
微信小程序开发学习篇 概述 相关信息 笔记制作时间:2022-9-25 参考视频:黑马视频 参考文档:微信小程序官方开发文档 文章目录 微信小程序开发学习篇 概述 相关信息 小程序基础 1.数据绑定与 ...
- 微信小程序开发学习1(小程序的入门知识)
微信小程序开发学习1(小程序的入门知识) 1.制定学习目标: 能够知道如何创建小程序项目 能够清楚小程序项目的基本组成结构 能够知道小程序页面的几个组成部分 能够知道小程序中常见的组件如何使用 能够知 ...
- 微信小程序开发学习5(自定义组件)
微信小程序开发学习5(自定义组件) 1.学习目标 能够知道如何自定义小程序组件 能够知道小程序组件中behaviors的作用 能够知道如何安装和配置vant-weapp组件库 能够知道如何使用MobX ...
- 微信小程序开发学习2(模板与配置)
微信小程序开发学习2(模板与配置) 1.学习目标 能够使用WXML模板语法渲染页面结构 能够使用WXSS样式美化页面结构 能够使用app,json对小程序进行全局性配置 能够使用page.json对小 ...
- 基于有Vue基础的微信小程序开发学习笔记
微信小程序开发 文章目录 微信小程序开发 一.微信小程序介绍 二.小程序结构目录 1.小程序的文件结构 2.基本项目目录 三.配置文件详解 1.全局配置文件 2.页面配置文件 3.sitemap配置 ...
最新文章
- 如何购买指定配置的ECS服务器【新手小白攻略】...
- 实现Nginx https
- linux 系统工程师 面试 开放式问答
- ”盒模型“之如何防止边框和内边距把元素撑开
- *【PAT天梯】分而治之(并查集,暴力)
- 如何连接网站小马php,PHP连接mysql示例
- 面试官:这货一听就是一个水货...
- cocos2D icon
- 几近完美的手机电脑无缝共享剪贴板神器,终于被我找到了!
- 第三方支付平台如何对接?
- windows自带hyperv安装虚拟机ubuntu与分辨率修改
- redis 保存大量数据
- Hbase篇(7)-Region的分裂
- 山东标梵网站制作项目启动流程详解
- Linux切换中英文环境
- 桌上有一空盘,最多允许存放一个水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。	试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。
- 限量版 情感智能机器人Pepper今天发售了!
- 优学院电子商务理论与实务试题及答案
- How to GROUD?
- 最新UI设计师教程(学习路线+课程大纲+视频教程+面试题+学习工具)
热门文章
- FLAT:Flat-LAttice Transformer
- oracle故障分析报告,Oracle 数据库异常宕机错误分析:ORA-01092
- Vue+ElmentUI 实现表格可变表头,可变多级表头,自定义报表
- P5535 【XR-3】小道消息
- Python 图片转ICO
- 上市公司财务报告的那点事(5):从新手试练到股票建仓,美丽的老板出海卖电器
- 继云盘精灵关闭后,又一云盘宣布关闭
- 贫苦家庭与野生公有云之间的 WireGuard Mesh 组网策略
- JS对象创建 Object.create() 方法
- Linux 开机 logo 修改