文章目录
一、微信小程序的基本知识
#去除索引提示报错
- 在setting配置向中加入"checkSiteMap": false即可
1、wxml和html的区别
-
标签名称不同HTML(div,span,img,a)
-
WXML(view,text,image,navigator)
-
属性节点不同
-
<a href="#">超链接</a> wxml <navigator url="/xx"></navigator>
-
-
2、wxss和css区别
1、新增了rpx尺寸单位
- css中要手动进行像素单位转换,例如rem
- wxss中用rpx尺寸单位,会自动在不同屏幕上自动换算
- @import的引入
2.1 rpx的实现原理
在屏幕上分成了750份
在大屏幕中一份rpx就大一点
在小屏幕中一份rpx就小一点
2、提供了全局样式表和局部样式表
- app.wxss会作用所有小程序也米娜
- 局部的Wxss只对当前页面生效
3、wxss仅支持部分css选择器,绝大多数都支持除了特别生僻的
3、小程序.js
1、app。js
- 整个项目的入口文件,通过App(函数来启动整个小程序
2、页面的。js文件
- 页面的入口文件,通过page()函数来创建并运行页面
3、普通js文件
- 封装公共函数属性供页面使用
二、小程序的宿主环境
1、运行机制
小程序启动的过程:
1、把小程序代码下到本地
2、解析app.json全局配置文件
3.执行app.js小程序入口文件调用App()创建小程序实例
4、渲染小程序首页
5.小程序启动完成
2、组件
1、试图容器
1、view 2、scroll-view 3、swiper 和 swiper-item
swiper的常用属性
2、基础内容
1、text 类似于span 行内元素
属性:
user-select 支持用户长按选择该段文字
2、rich-text 组件
里面可以用node+html标签内联样式渲染
3、image
默认是有一个宽度300px、高度240px
3、小程序的api
1、事件监听API
- 以on开头监听某些事件的触发
2、同步API
- 以Sync结尾的API
3、异步API
- 类似于$.ajax(option)函数,要success、fail、complete接受调用的结果
三、模板语法
1、事件的传参
1、
<button>
bindtap = 'btnHandle ' data-info="{{2}}"
</button>
<!-- info 参数的名字 2 参数的值 -->
btnHandle(event){
通过 event.target.dataset.info 拿到对应值 省略了{{}}传的是字符串
}
2、input传参 绑定完bindinput事件后,通过event、detai、value拿到对应的值
2、条件渲染
<view wx:if="{{条件判断}}"></view>
<view wx:elif="{{}}"></view>
<view wx:else > </view>
<view hidden="{{}}"></view> // 是否隐藏
// wx:if 和 hidden 的区别
wx:if 是动态创建和移除元素样式
hidden 切换样式的方式,display:none/block
3、循环渲染
<view wx:for="{{arr1}}">
索引是{{index}},{{item}}是默认循环项
</view>
wx: key
建议使用key来提示循环渲染的效率
key里面不需要加{{}}
<view wx:key=index></view>
四、全局配置
1.window 常用的配置项
2 tabBar 的配置
tabBar最少2个,最多5个标签
上标签只能text 不能icon
2.1 list 配置中的选项
list:{
{
pagePath:;
text:;
// 上面两个是必填项目
selecticonPath
iconPath
}
}
五、数据请求
1、发送get请求
wx.request({
url: 'https://www.escook.cn/api/get',
method:'GET',
data:{
name:'zs',
age:22,
},
// 请求成功后调用success方法
success:(res)=>{
console.log(res.data);
}
})
2、发送post请求
wx.request({
url: 'https://www.escook.cn/api/post',
method:'post',
data:{
name:'ls',
age:22,
},
// 请求成功后调用success方法
success:(res)=>{
console.log(res.data);
}
六、页面导航
1、通过navigator组件 (声明式导航)
<navigator url="/ + 地址" open-type="switchTab"></navigator>
// 如果导航到非tabBar 页面可以不写open-type 属性
open-type="navigatorBack" detail='x' // 返回 detail指明要后退的层级 只返回一级时可以省略
2、编程式导航
1 wx.switchTab
wx.switchTab({
url:'/ + xxx'
})
2wx.navigateTo
非tabBar导航
wx.navigateTo({
url:'/ + xx'
})
// 返回页面
3.wx.navigateBack
wx.navigateBack({
delta:'' // 指定返回的层级
}})
4.导航传参
<navigator url="/ xx?name=as&age=20" />
在onload(options){
通过 this.setData({
保存参数到该页面
})
}
3、下拉刷新
enablePullDownRefresh:true // 可以开启下拉刷新
bacgroundColor:"#ff0000" // 可以设置背景颜色
bacgroundTextStyle:'dark/light' // 可以设置下拉刷新的样式
// 下拉刷新的时间
onPullDownRefresh:function(){} // 下拉刷新后触发的事件
// wx.stopPullDownRefresh
调用这个方法可以结束下拉刷新效果
4、上拉触底
onReachBottom() //函数可以监听页面上拉加载事件
// 配置上拉触底距离
//在.json onReachBottomDistance 这属性可以调节 触底距离 默认是50 px
5、loading 加载提示
// 当开始调用网络请求时打开wx.showLoading函数
getColors(){
wx.showLoading({
title: '数据加载中...',
})
wx.request({
url: 'https://www.escook.cn/api/color',
method:'GET',
success:({data:res})=>{
this.setData({
colorList:[...this.data.colorList,...res.data]
})
},
// 当请求完成时回调wx.hideLoading函数
complete:()=>{
wx.hideLoading()
}
})
},
// 可以添加 data isLoading:false
//请求开始时isLoading为true
// 请求结束时isLoading再为false
// 每次请求时判断是否为true 来防止多次请求
if(this.data.isLoading){
return
}else{
this.getColors()
}
七、小程序生命周期
1、应用生命周期
- 特指小程序启动——运行——销毁的过程
//小程序初始化完成时触发的函数 只调用一次
onLauch:function(options){}
//小程序启动或小程序从后台到前台
onShow:function(options){}
// 小程序从前台进入后台
ohHide:function(){}
2、页面生命周期
- 特质小程序中,每个页面加载——渲染——销毁的过程
page({
// 监听页面加载,一个页面只调用一次 可以获取参数
onLoad : function(options) { }
onShow : function(){ } // 监听页面显示
onReady : function() {} // 监听页面初次渲染完成, 只调用一次
onHide : function() {} // 监听页面隐藏
onUnload : function() {} // 监听页面卸载,一个页面只调用一次
})
八、wxs脚本
1、内置wxs脚本的使用
{{内嵌的用法 m1.toUpper(xxx) }}
<wxs module='m1'>
module.exports.toUpper = function(str){
return str.toUpperCase()
}
</wxs>
2、定义外联的wxs脚本
function toLower(str){
return str.toLowerCaser()
}}
module.exports = {
toLower:toLower
}
3、使用外联的wxs脚本
- 再 标签中加module 和src属性
<wxs src="xxx相对路径" module="定义模块名字 (x) "></wxs>
随后就可以进行模块的调用
<view>{{ x.toLowercount }} </view>
九、自定义组件
1、组件隔离
-
默认情况下组件的样式只对组件自己起作用
-
app。wxss全局样式对组件无效
-
只有class属性有隔离效果,其他全局样式可以全局生效
-
建议组件和引用组件的页面中都用class选择器
2、组件隔离属性
// 第一种再组件.js 文件中配置
options:{
styleIsolation:"isolated"
}
//第二种在组件的.json 文件中配置
{
styleIsolation:"isolated"
}
// 属性可选值:
isolated true //启动样式隔离 使用class样式不会互相影响
apply-shared false // 表示全局wxss样式会影响到自定义组件,组件不会影响全局
shared false // 表示全部互相影响
3、组件属性
porperties:{
max:{
type:"数据类型",
value:可以设置默认值
}
}
<view max='传进去的值' />
4、数据监听器
data:{
n1:0,
n2:0,
sum:0
}
observers:{
"字段A (n1),字段B (n2)":function(字段A n1,字段B n2){
this.setData({
// 时时监听A,B数据的变换
num: 字段A + 字段B
num: n1 + n2
})
}
}
// 同时支持监听对象属性的变化
observers:{
"对象.属性A,对象.属性B":function(属性的A新值,属性B的新值){
//触发该监听器的三种情况
为属性A赋值时,为B赋值时,为对象赋值时
// this.setData({ 为this.data.对象 赋值})
}
}
// 也可以使用统配符
"rgb.***": function(obj){
// 可以监听对象所有属性改变
}
3、组件的生命周期
组件的生命周期函数
-
created 组件刚创建时调用
-
attached 在组件实例进入页面节点树时执行
-
ready 在组件视图布局完成后执行
-
moved 在组件实例被移动到节点树另一个位置时执行
-
detached 在组件实例从被页面节点树移除时执行
-
error 每当组件抛出错误时执行
1.created
组件实例刚创建好时调用
- 此时不能嗲用setData
- 通常这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性
2、attached
在组件完全初始化完毕,进入页面节点树后触发
- 此时,this。data已经初始化完毕
- 一般绝大多初始化工作在这时候进行(比如发送请求
3、detached
当离开页面节点树后触发
- 退出一个页面中,会触发页面内每个自定义组件的detached生命周期函数
- 一般用来清理数据
// 声明生命周期函数
//该声明方式优先级最高
lifetimes:{
created(){},
}
4、组件页面的周期
pageLifttimes:{
show(){}, // 组件页面展示时
hide(){}, // 组件被隐藏
resize(){} // 组件尺寸变化
}
5.自定义的插槽
- 默认情况下不支持多个插槽
- 需要多个插槽时在。js options上配置multipleSlots:true开启多个插槽
6.父子组件的通信
1、属性绑定
- 用于父组件向子组件的指定属性设置数据
// 父组件
<test3 count="{{count}}" bind:addCount="addCount"></test3>
// 父组件定义 {{count}}
// 子组件
properties: {
count:Number
},
2、事件绑定
- 子组件向父组件传递数据,可以传递任意数据
// 子组件
methods: {
addCount(){
this.triggerEvent("addCount","我是子组件发送的事件")
}
}
// 父组件
<test3 count="{{count}}" bind:addCount="addCount"></test3>
addCount(e){
this.setData({
count:this.data.count+1
})
console.log(e.detail);
},
3、获取组件实例
- 父组件可以通过this.selectComponent()获取子组件实例
- 这样就可以直接访问子组件的任意数据和方法
// 给组件定义class属性
// 父组件
Page({
data: {},
getChildComponent: function () {
const child = this.selectComponent('.my-component');
console.log(child)
}
})
4、组件的共享属性
// 创建一个 Behavior.js
module.exports = Behavior({
data:{
username:"zs"
},
methods:{}
})
// 子组件
const myBehevaior = require('../../behaviours/behavious')
Component({
// 在子组件中注册便可以拥有子组件的属性和方法
behaviors:[myBehevaior]
{{username}} // 输出zs
5、纯数据字段
- 纯数据字段是一些不用于界面渲染的 data 字段,可以用于提升页面更新性能
有些情况下,某些 data
中的字段(包括 setData
设置的字段)既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。
此时,可以指定这样的数据字段为“纯数据字段”,它们将仅仅被记录在 this.data
中,而不参与任何界面渲染过程,这样有助于提升页面更新性能。
// 指定“纯数据字段”的方法是在 Component 构造器的 options 定义段中指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。
Component({
options: {
pureDataPattern: /^_/ // 指定所有 _ 开头的数据字段为纯数据字段
},
data: {
a: true, // 普通数据字段
_b: true, // 纯数据字段
},
methods: {
myMethod() {
this.data._b // 纯数据字段可以在 this.data 中获取
this.setData({
c: true, // 普通数据字段
_d: true, // 纯数据字段
})
}
}
})
上述组件中的纯数据字段不会被应用到 WXML 上:
<view wx:if="{{a}}"> 这行会被展示 </view>
<view wx:if="{{_b}}"> 这行不会被展示 </view>
十、使用npm包
1、API Promise 化
npm i -s miniprogram-api-promise
// 安装完再构建完npm包后再小程序入口文件aap.js
// 调用一次promisefyAll()方法即可实现异步APIPromise化
ipmort { promisifyAll } from 'miniprogram-api-promise'
const wxp = wx.p = {} // 两个指向同一个地址,后续可以通过wx.p调用promise化后的api
promisifyAll(wx,wxp) // 将wx所有回调函数promise化后的api挂载到wxp上
2、调用api
<van-button type="primary" bindtap="sendApi">发送api请求</van-button>
async sendApi(){
const {data:res} = await wx.p.request({
methods:"get",
url:"https://www.escook.cn/api/get",
data:{
name:'zs',
age:20
}
})
console.log(res);
},
十一、全局数据共享(状态管理)
1、安装Mobx
npm i -s mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
2、在store.js中创建实例
import { observable,action } from 'mobx-miniprogram'
export const store = observable({
// 数据字段
numA:1,
numB:2,
// 计算属性
get sum(){ // get 修饰代表这属性只读
return this.numA + this.numB
},
// action 方法,用来修改store 的值
upDataNum1:action(function(step){ // 需用action包裹住function
this.numA += step
}),
upDataNum2:action(function(step){
this.numB += step
})
})
3、将store成员绑定到页面
import { createStoreBindings } from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
/** 生命周期函数--监听页面加载*/
onLoad: function (options) {
this.storeBindings = createStoreBindings(this,{ // 给this页面对象绑定对应store属性
store,
fields:['numA','numB','sum'],
actions:['upDataNum1','upDataNum2']
})
},
/** 生命周期函数--监听页面卸载 */
onUnload: function () { // 页面关闭时清空
this.storeBindings.destroyStoreBindings()
},
4、在页面中使用store
<view>{{numA}}+{{numB}} = {{sum}}</view>
<button bindtap="btnHandle1" data-step="{{1}}">numA + 1</button>
<button bindtap="btnHandle2" data-step="{{-1}}">numB - 1</button>
<<!-- 调用store的action 方法改变数据,需要在页面中actions进行挂载 -->> <
btnHandle1(d){
this.upDataNum1(d.target.dataset.step)
},
btnHandle2(d){
this.upDataNum2(d.target.dataset.step)
},>
5、在组件中使用store
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Component({
behaviors:[storeBindingsBehavior], // 通过storeBindingsBehavior 实现把规定
storeBindings:{
store, // 指定store 源
fields:{ // 绑定的数据
numA:"numA", // 第一种方式 ()=> store.numA
numB:"numB", // 第二中方式 store => store.numB
sum:"sum" // 第三种方式
},
actions:{ // 要绑定的方法
upDataNum1:"upDataNum1",
upDataNum2:"upDataNum2"
}
}
})
6、在组件中使用store
<view>{{numA}}+{{numB}} = {{sum}}</view>
<button bindtap="btnHandle1" data-step="{{-1}}">numA - 1</button>
<button bindtap="btnHandle2" data-step="{{1}}">numB + 1</button>
methods: {
btnHandle1(e){
this.upDataNum1(e.target.dataset.step)
},
btnHandle2(e){
this.upDataNum2(e.target.dataset.step)
}
}
十二、分包
1、什么是分包
- 分包指的是把一个完整的小程序项目,按需求分为不同的子包,再构建时打包成不同的分包,用户使用时按需进行加载
2、分包的好处
- 优化小程序首次启动的下载时间
- 多团队开发可以更好的解耦写作
3、分包前的项目构成
- 所有资源都在主页面
4、分包后的项目构成
- 一个主包+多个分包
- 主包:一般只有启动页面跟TabBar,里面的公共资源所有分包都能用
- 分包:只包含私有的页面跟资源
5、分包的加载规则
- 默认会进入主包并加载主包的资源
- 等进入分包后才会加载分包的资源
6、体积限制
- 整个小程序所有分包大小不超过 20M
- 单个分包/主包大小不能超过 2M
12.1 使用分包
1、配置方法
{
"pages":[
"pages/index",
"pages/logs"
],
"subpackages": [ // 创建分包
{
"root": "packageA", // 分包的根目录
"pages": [
"pages/cat", // 分包的文件
"pages/dog"
]
}, {
"root": "packageB",
"name": "pack2", // 分包的别称
"pages": [
"pages/apple",
"pages/banana"
]
}
]
}
2、打包原则
- 声明
subpackages
后,将按subpackages
配置路径进行打包,subpackages
配置路径外的目录将被打包到 app(主包) 中 - app(主包)也可以有自己的 pages(即最外层的 pages 字段)
subpackage
的根目录不能是另外一个subpackage
内的子目录tabBar
页面必须在 app(主包)内
3、引用原则
- 主包不能使用分包的私有资源
- 分包之间不能互相使用各种资源
- 分包可以使用主包的公共资源
12.2 独立分包
独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。
从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。
配置方法
- 在
app.json
的subpackages
字段中对应的分包配置项中定义independent
字段声明对应分包为独立分包。
{
"pages": [
"pages/index",
"pages/logs"
],
"subpackages": [
{
"root": "moduleA",
"pages": [
"pages/rabbit",
"pages/squirrel"
]
},
// MoudleB 加了 "independent": true 即为独立分包
{
"root": "moduleB",
"pages": [
"pages/pear",
"pages/pineapple"
],
"independent": true
}
]
引用原则
- 独立包不能用主包资源
- 其他同普通分包
12.3 分包预下载
- 开发者可以通过配置,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度。
- 对于独立分包,也可以预下载主包
配置方法
-
预下载分包行为在进入某个页面时触发,通过在
app.json
增加preloadRule
配置来控制。// preloadRule 中,key 是页面路径,value 是进入此页面的预下载配置,每个配置有以下几项: "preloadRule": { "pages/index": { // 触发分包预下载的key(页面路径) "network": "all", //在指定网络下预下载,可选值为:all: 不限网络 wifi: 仅wifi下预下载 // 默认为wifi "packages": ["important"] // packages表示 进入页面后预下载分包的 root 或 name。__APP__ 表示主包。 }, "indep/index": { "packages": ["__APP__"] } }
下载限制
-
同一个分包中的页面享有共同的预下载大小限额 2M,限额会在工具中打包时校验。
如,页面 A 和 B 都在同一个分包中,A 中预下载总大小 0.5M 的分包,B中最多只能预下载总大小 1.5M 的分包。
-