快速上手开发微信小程序(含npm包使用及mobx状态管理)

文章目录

一、微信小程序的基本知识

#去除索引提示报错

  • 在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.jsonsubpackages字段中对应的分包配置项中定义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 的分包。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值