wx:if和hidden
<view wx:if="{{isShow}}">wx:if</view> <view hidden="{{isShow}}">hidden</view>
区别:
wx:if : 切换的时候销毁或重新渲染;wx:if
是惰性的,在初始条件为 false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
hidden : 组件始终会被渲染,只是简单的控制显示与隐藏。
使⽤
频繁切换使⽤ hidden , 运⾏时条件变化使⽤ wx: if
网络请求
网络请求限制
出于安全考虑,小程序对数据接口的请求有要求:
只能请求https类型的接口
必须将接口的域名添加到信任列表中
配置合法域名
登录小程序公众平台--->开发管理---->开发设置--->服务器域名--->修改合法域名
发起GET请求
wx.request({ url: 'example.php', //仅为示例,并非真实的接口地址 method:'GET', data: { x: '', y: '' }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { console.log(res.data) } })
在页面刚加载时请求数据
/** * 生命周期函数--监听页面加载 */ onLoad(options) { this.getData() },
getData(){ wx.request({ url: 'https://www.escook.cn/slides', //仅为示例,并非真实的接口地址 method:'GET', header: { 'content-type': 'application/json' // 默认值 }, success:(res)=>{ // console.log(res.data) this.setData({ banners:res.data }) } }) },
发起Post请求
wx.request({ url: 'example.php', //仅为示例,并非真实的接口地址 method:'POST', data: { x: '', y: '' }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { console.log(res.data) } })
跳过request合法域名校验
后端程序员仅仅提供了http协议的接口,需要不校验合法域名
微信开发者工具---->详情---->不校验合法域名
没有跨域
跨域只存在于浏览器的web开发中,小程序是运行在微信环境中,小程序不存在跨域问题
Ajax技术的核心是依赖于浏览器的 XMLHttpRequest 对象,小程序是运行在微信环境中没有这个对象,小程序不能叫做ajax请求 叫做发起网络数据请求
页面导航
页面导航的两种方式
-
声明式导航
在页面上声明 <navigator>导航组件,url属性是导航地址
-
编程式导航
调用小程序的导航API,实现页面跳转
声明式导航
导航到tabBar页面
tabBar页面是被配置为tabBar的页面
navigator组件,需要指定url属性和open-type属性
url: 跳转页面的地址 必须以 / 开头
open-type 跳转的方式 值为switchTab
<navigator url="/pages/home/home" open-type="switchTab">跳转到home</navigator>
导航到非tabBar页面
tabBar页面是被配置为tabBar的页面
navigator组件,需要指定url属性和open-type属性
url: 跳转页面的地址 必须以 / 开头
open-type 跳转的方式 值为navigate
<navigator url="/pages/cart/cart" open-type="navigate">cart</navigator>
导航到非tabBar页面时,open-type="navigate" 可以省略
后退导航
如果要后退到上一页面或多级页面,需要指定open-type和delta属性
open-type 的值必须是navigateBack ,表示要进行后退导航
delta 的值必须是数字,表示后退的层级
<navigator open-type="navigateBack" delta="1">返回</navigator>
如果只是返回到上一页面,可以省略delta=“1”,因为默认值为1
传参
/pages/cart/cart?id=2&name=zs
-
参数和路径直接使用?分割
-
参数名和参数值之间用 =
-
不同参数用 & 分割
<navigator url="/pages/cart/cart?id=2&name=zs" open-type="navigate">跳转到home</navigator> <navigator url="/pages/cart/cart?id={{num}}&name=zs" open-type="navigate">跳转到home</navigator>
编程式导航
导航到tabBar
wx.switchTab({ url: '/pages/home/home', })
导航到非tabBar
wx.navigateTo({ url: '/pages/cart/cart', })
后退导航
wx.navigateBack({ delta:1 })
传参
wx.switchTab({ url: '/pages/cart/cart?id=23&name=zs', }) wx.switchTab({ url: `/pages/cart/cart?id=${this.data.num}&name=zs`, })
在onLoad中接收参数
onLoad(options) { console.log(options,"options") //{id: "23", name: "zs"} },
页面事件
下拉刷新
手指在屏幕上下拉滑动操作,重新加载页面数据
步骤
1启动下拉刷新
-
全局开启下拉刷新
在app.json 的window节点中,enablePullDownRefresh:true
-
局部开启下拉刷新
在页面的.json文件中,enablePullDownRefresh:true
2配置下拉刷新窗口样式
backgroundTextStyle:dark 下拉的loading的效果
backgroundColor 窗口的背景颜色
3监听下拉刷新事件
通过onPullDownRefresh()监听用户下拉事件
4停止下拉刷新动作
// 数据重置成功,调用该函数,关闭下拉刷新的效果 wx.stopPullDownRefresh()
上拉加载
手指在屏幕上上拉滑动操作,加载更多数据
步骤
配置上拉触底距离
-
全局配置 onReachBottomDistance:60
-
局部配置 onReachBottomDistance :60
监听页面的上拉触底事件
/** * 页面上拉触底事件的处理函数 */ onReachBottom() { console.log("触发了上拉触底事件") },
上拉触底案例
-
定义获取随机颜色的方法
-
在页面加载时获取初始数据onLoad
-
渲染页面结构 美化效果
-
上拉触底时调用获取随机颜色的方法
-
添加loading提示效果
定义获取随机颜色的方法
// 1定义获取随机颜色的方法 getColors(){ wx.request({ url: 'https://www.escook.cn/api/color', method:'GET', success:(data)=>{ console.log(data.data.data) this.setData({ colorList:data.data.data }) } }) },
在页面加载时获取初始数据
/** * 生命周期函数--监听页面加载 */ onLoad(options) { this. getColors() },
渲染页面解构 美化效果
<view class="box" wx:for="{{colorList}}" wx:key="*this" style="background-color:rgb({{item}}) ;">{{item}}</view>
上拉触底时调用获取随机颜色的方法
赋值一定要进行数组的合并
/** * 页面上拉触底事件的处理函数 */ onReachBottom() { console.log("触发了上拉触底事件") this.getColors() },
// 1定义获取随机颜色的方法 getColors(){ wx.request({ url: 'https://www.escook.cn/api/color', method:'GET', success:(data)=>{ console.log(data.data.data) this.setData({ colorList:[...this.data.colorList,...data.data.data] }) } }) },
添加loading加载
-
请求前添加loading
-
请求完成关闭loading
getColors(){ // 开启loading wx.showLoading({ title: '数据加载中', }) wx.request({ url: 'https://www.escook.cn/api/color', method:'GET', success:(data)=>{ console.log(data.data.data) this.setData({ colorList:[...this.data.colorList,...data.data.data] }) }, // 接口调用结束的回调函数 complete:()=>{ wx.hideLoading() } }) },
封装网络请求
引入组件
全局引入
组件可以在每个小程序页面中使用
多个页面都会用到该组件使用 全局
app.json
注册组件
"usingComponents":{ "my-com":"/components/myCom/myCom" },
使用组件
<my-com></my-com>
局部引入
组件只能在当前被引入的页面中使用
页面的json中
{ "usingComponents": { "my-text":"/components/myText/myTest" } }
使用组件
<my-text></my-text>
组件和页面的区别
都是由4个文件组成 .js .json .wxml .wxss
组件
组件的json文件中需要声明 "component": true,
组件的 .js文件中调用Component() 函数
组件的事件处理函数需要定义到methods中
页面
页面的 .js中调用 Page()方法
样式
一般情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的ui结构
app.wxss中的全局样式对组件无效
只有class选择器有样式隔离的影响,id,标签,属性选择器不受样式隔离的影响
建议使用class选择器
data数据
定义组件的数据
data: { count:0 },
methods方法
事件处理函数 和自定义方法定义到methods中
methods: { addCount(){ this.setData({ count:this.data.count+1 }) this.showCount() }, showCount(){ wx.showToast({ title: 'count值为'+this.data.count, }) } }
properties
父传子
properties是组件的对外属性,用来接收外界传递给组件中的数据
//父组件 <my-com tit="2202A大哥们好" num="{{20}}"></my-com>
properties: { tit:{ type:String, //数据类型 value:'hello' //默认值 }, num:Number },
properties和data的区别
methods: { addCount(){ console.log(this.data) //{count: 0, tit: "2202A大哥们好", num: 20} console.log(this.properties) // 本质上一样的,都是可读可写的 console.log(this.properties===this.data) //true } }
使用setData修改properties的值
this.setData({ num:this.properties.num+2 })
数据监听器
监听和响应任何属性和数据字段的变化,从而执行特定的操作
Component({ observers:{ '字段A,字段B':function(字段A的新值,字段B的新值){ //代码 } } })
代码
<view class="box"> <view>{{n1}}+{{n2}}={{sum}}</view> <button bindtap="addN1">n1+1</button> <button bindtap="addN2">n2+1</button> </view>
Component({ /** * 组件的初始数据 */ data: { n1:0, n2:0, sum:0 }, observers:{ 'n1,n2':function(newN1,newN2){ this.setData({ sum:newN1+newN2 }) } }, /** * 组件的方法列表 */ methods: { addN1(){ this.setData({ n1:this.data.n1+1 }) }, addN2(){ this.setData({ n2:this.data.n2+1 }) } } })
监听对象属性的变化
支持监听对象中单个或多个属性的变化
Component({ observers: { 'some.field.**': function(field) { // 使用 setData 设置 this.data.some.field 本身或其下任何子数据字段时触发 // (除此以外,使用 setData 设置 this.data.some 也会触发) field === this.data.some.field }, }, attached: function() { // 这样会触发上面的 observer this.setData({ 'some.field': { /* ... */ } }) // 这样也会触发上面的 observer this.setData({ 'some.field.xxx': { /* ... */ } }) // 这样还是会触发上面的 observer this.setData({ 'some': { /* ... */ } }) } })
案例
wxml
{{fullColor}} <view style="background-color:rgb({{fullColor}});" class="colorbox"> {{fullColor}} </view> <button bindtap="changR" size="mini">R</button> <button bindtap="changG" size="mini">G</button> <button bindtap="changB" size="mini">B</button>
js
Component({ /** * 组件的初始数据 */ data: { rgb:{ r:0, g:0, b:0, }, fullColor:'0,0,0' }, // 监听对象中属性的变化 observers:{ 'rgb.r,rgb.g,rgb.b':function(r,g,b){ this.setData({ fullColor:`${r},${g},${b}` }) } }, /** * 组件的方法列表 */ methods: { changR(){ this.setData({ 'rgb.r':this.data.rgb.r+5>255?255:this.data.rgb.r+5 }) }, changG(){ this.setData({ 'rgb.g':this.data.rgb.g+5>255?255:this.data.rgb.g+5 }) }, changB(){ this.setData({ 'rgb.b':this.data.rgb.b+5>255?255:this.data.rgb.b+5 }) } } })
纯数据字段
不用于界面渲染的 data 字段
某些
data
中的字段(包括setData
设置的字段)既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。可以指定这样的数据字段为“纯数据字段”纯数据字段 有助于提升页面更新性能
在 Component
构造器的 options
定义段中指定 pureDataPattern
为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。
Component({ options:{ pureDataPattern: /^_/ // 指定所有 _ 开头的数据字段为纯数据字段 }, data: { // 将rgb改为以_开头的纯数据字段 _rgb:{ r:0, g:0, b:0, }, fullColor:'0,0,0' }, })
组件生命周期
组件全部生命周期
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 | 1.6.3 |
attached | 无 | 在组件实例进入页面节点树时执行 | 1.6.3 |
ready | 无 | 在组件在视图层布局完成后执行 | 1.6.3 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | 1.6.3 |
detached | 无 | 在组件实例被从页面节点树移除时执行 | 1.6.3 |
error | Object Error | 每当组件方法抛出错误时执行 | 2.4.1 |
组件主要生命周期
在小程序组件中,最重要的生命周期函数有3个,分别是created,attached,detached
组件实例刚刚被创建好的时候,created生命周期函数会被触发
组件完全初始化完毕,进入页面节点树后,attached生命周期函数会触发
组件离开页面节点树后,detached生命周期函数会触发
lifetimes节点
Component({ lifetimes: { attached: function() { // 在组件实例进入页面节点树时执行 }, detached: function() { // 在组件实例被从页面节点树移除时执行 }, }, // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容 attached: function() { // 在组件实例进入页面节点树时执行 }, detached: function() { // 在组件实例被从页面节点树移除时执行 }, // ... })
组件所在页面的生命周期
自定义组件的行为依赖于页面状态的变化,就需要用到组件所在页面的生命周期
每当触发页面的show生命周期函数的时候,我们希望能够重新生成一个随机的RGB颜色值
生命周期函数 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在页面被展示时执行 |
hide | 无 | 组件所在页面被隐藏时执行 |
resize | Object Size | 组件所在页面尺寸变化时执行 |
Component({ pageLifetimes: { show: function() { // 页面被展示 }, hide: function() { // 页面被隐藏 }, resize: function(size) { // 页面尺寸变化 } } })
页面展示的时候,重新生成一个随机的RGB颜色值
Component({ pageLifetimes:{ show(){ this._randomColor() } }, methods:{ _randomColor(){ this.setData({ _rgb:{ r:Math.floor(Math.random()*256), g:Math.floor(Math.random()*256), b:Math.floor(Math.random()*256) } }) } } })
插槽
什么是插槽
组件的wxml中可以提供一个<slot>节点,用于承载组件引用时提供的子节点。
传递单个slot
需要使用多 slot 时,可以在组件 js 中声明启用。
options: { multipleSlots: true // 在组件定义时的选项中启用多 slot 支持 },
组件
<text>components/myTest/myTest.wxml</text> <view>hello</view> <slot name="one"></slot> <view>good</view> <slot name="two"></slot>
页面
<my-test> <view slot="one"> <text>123</text> </view> <view slot="two"> <text>345</text> </view> </my-test>
父子组件通信
父子组件之间通信的 3 种方式
① 属性绑定
② 事件绑定
③ 获取组件实例
属性绑定
属于父传子,只能传递普通类型的数据,不能传递方法
父组件
data: { count:0 },
<my-com count="{{count}}"></my-com> <view>------------</view> <view>count的值{{count}}</view>
子组件在properties节点中声明对应的属性count并使用
properties: { count:{ type:Number, value:0 } }, <text>子组件--count的值为{{count}}</text>
事件绑定
子向父,可以传递任意类型的数据
第一步:父组件中定义函数
//1 在父组件的js中,定义一个函数,这个函数通过自定义事件的形式传递给子组件 asyncCount(e){ console.log(e.detail) this.setData({ count:this.data.count+e.detail }) },
第二步:父组件的wxml中,定义自定义事件
<!-- 2在父组件的wxml中,定义自定义事件,事件对应的函数为上面定义的函数 --> <my-com bind:countEve="asyncCount" count="{{count}}"></my-com>
第三步:子组件的js中,通过this.triggerEvent('自定义事件名',参数),将数据发送给父组件
methods: { addCount(){ this.triggerEvent('countEve',7) } }
第四步在父组件的js中,通过e.detail获取子组件传递过啦的数据
asyncCount(e){ console.log(e.detail) this.setData({ count:this.data.count+e.detail }) },
获取组件实例
在父组件里调用this.selectComponent('id或者是class选择器'),获取子组件实例对象就可以访问到子组件的任意数据和方法,调用时传入选择器
getCom(){ // console.log(this.selectComponent("#comCountA")) console.log(this.selectComponent("#comCountA").data.count) this.selectComponent("#comCountA").addCount() },
npm
js脚本语言,不能单独运行,嵌套在html中使用,在浏览器中运行
浏览器有js引擎,解析js代码的,逐行解析
ECMAScript,BOM,DOM
node
让js运行在服务端的开发环境
node使用的js的语法 ECMAScript 有自己的api ,fs,http,path
模块化开发
一个js文件就是一个模块 每个模块之间是相互独立的 互不影响
模块中定义的内容 必须暴露出去
使用模块 必须引入
module.exports={} require 该导入导出遵循COmmonJS规范,只能应用于服务端
export default import 该导入导出是遵循ES6规范,可以用在前端也可以用在服务端
node的模块
系统模块
按照完node后就自动有的模块 fs,path,http
自定义模块
自己定义的模块
第三方模块
别人写的模块
npm 这个地方可以查询有哪些第三方模块
https://www.npmjs.com/ 网站上搜索自己所需要的包 https://registry.npmjs.org/ 服务器上下载自己需要的包
怎么下载第三方模块
包管理工具 npm cnpm
yarn
下载
npm install --global yarn yarn --version
小程序中对npm的支持
小程序一级开始支持npm按照第三方包,可以提高小程序的开发效率
原生小程序中使用vant
npm i @vant/weapp@1.3.3
全局数据共享
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等。而我们微信小程序常用的全局共享方案是:MobX
使用
在小程序中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享。其中:
mobx-miniprogram 用来 创建 Store 实例对象 mobx-miniprogram-bindings 用来 把 Store 中的共享数据或方法 , 绑定到组件或页面中使用
安装Mobx相关的包
npm i --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
mobx相关的包安装完后,删除mini-program-npm ,重新构建npm(工具---构建npm)
创建store实例
根目录下新建store/index.js
import {observable,action} from 'mobx-miniprogram' // 创建store实例 export const store = observable({ // 定义共享数据 数据字段 numA:1, numB:1, // 计算属性 get sum(){ return this.numA+this.numB }, // actions 方法 用来修改state中的数据 updateNuma:action(function(n){ this.numA+=n }), updateNumb:action(function(n){ this.numB+=n }) })
把store中的成员绑定到页面中
使用store的手工绑定方式 应用于页面或者组件, 使用createStoreBindings 创建绑定,会返回一个清理函数的对象用于取消绑定
在页面的onUnload(组件detached) 调用清理函数,否则会导致内存泄露
页面的wxml
<view> {{ numA}}+{{numB}}={{sum}} </view> <button data-n="{{4}}" bindtap="handClick">numA</button>
页面的js文件
import {createStoreBindings} from 'mobx-miniprogram-bindings' import {store} from '../../store' Page({ handClick(e){ this.updateNuma(e.target.dataset.n) }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // 返回一个清理函数的对象用于取消绑定 this.storeBinds=createStoreBindings(this,{ // 绑定store实例 指定要绑定的store store, // fields:['numA','numB','sum'], //数组形式 把store中的数据拿来 // fields:{ //映射形式 // a:'numA', //this.data.a=store.numA // b:'numB' //this.data.b=store.numB // }, // 函数形式 fields:{ numA:()=>store.numA, numB:()=>store.numB, sum:'sum' }, actions:['updateNuma','updateNumb'] }) }, onUnload() { // 调用清理函数 否则将造成内容泄露 this.handClick.destroyStoreBindings() }, })
behavior
behavior绑定适用于Component构造器,使用storeBindingsBehavior和storeBindings定义数据段
语法
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings' Component({ behaviors:[storeBindingsBehavior], storeBindings:{ //配置项 store, fields:['numA','numB'], actions:{ buttonTap:'updateNuma' } } })
组件的wxml
<view>{{numA}}+{{numB}}={{sum}}</view> <button data-n="{{5}}" bindtap="handClick">numA</button>
组件的js
// components/myNumber/myNumber.js import {storeBindingsBehavior} from 'mobx-miniprogram-bindings' import {store} from '../../store' Component({ behaviors:[storeBindingsBehavior], storeBindings:{ // 配置项 store, fields:['numA','numB','sum'], actions:['updateNuma'] }, methods: { handClick(e){ console.log(123) this.updateNuma(e.target.dataset.n) } } })
behaviors
behaviors
是用于组件间代码共享的特性
分包
把一个完整的小程序项目,按照需求划分为不同的子包,最终打包成不同的分包,用户在使用时按需进行加载
好处:
优化小程序首次启动的下载时间
分包后项目构成
分包后小程序由1个主包和多个分包组成
分包体积限制
app.json中声明分包的结构
//声明分包的结构 "subPackages": [ { "root":"packageA", //第一个分包的根目录 "pages": [ //分包下所有页面的存放路径 "pages/detail/detail" ] }, { "root":"packageB", "pages": [ "pages/goods/goods" ] } ],
自定义tabBar
根目录下自定义组件新建custom-tab-bar/index
把点击的active定义为共享的数据
store.js
// 创建store实例 export const store = observable({ // 定义共享数据 数据字段 activeTabBarIndex:0, //点击的下标 updateActiveIndex:action(function(index){ this.activeTabBarIndex = index }) })
wxml
<van-tabbar active="{{ active }}" bind:change="onChange"> <van-tabbar-item info="{{item.info?item.info:''}}" wx:for="{{list}}" wx:key="index"> <image slot="icon" src="{{item.iconPath}}" style="width: 25px; height: 25px;" mode="aspectFit"></image> <image slot="icon-active" src="{{item.selectedIconPath}}" style="width: 25px; height: 25px;" mode="aspectFit"></image> {{item.text}} </van-tabbar-item> </van-tabbar>
js
import {storeBindingsBehavior} from "mobx-miniprogram-bindings" import {store} from '../store' Component({ behaviors:[storeBindingsBehavior], storeBindings:{ store, fields:{ sum:'sum', active:'activeTabBarIndex' }, actions:{ updateActive:"updateActiveIndex" } }, observers:{ 'sum':function(val){ this.setData({ 'list[1].info':val }) } }, /** * 组件的初始数据 */ data: { "list": [ { "pagePath": "/pages/home/home", "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":1 }, { "pagePath": "/pages/contact/contact", "text": "联系我们", "iconPath": "/images/tabs/contact.png", "selectedIconPath": "/images/tabs/contact-active.png" }, { "pagePath": "/pages/contact/contact", "text": "联系我们", "iconPath": "/images/tabs/contact.png", "selectedIconPath": "/images/tabs/contact-active.png" } ] }, /** * 组件的方法列表 */ methods: { onChange(event) { // event.detail 的值为当前选中项的索引 // this.setData({ active: event.detail }); this.updateActive(event.detail) wx.switchTab({ url: this.data.list[event.detail].pagePath, }) }, } })
配置信息
-
utils/request.js
/* options={ url,method,data,success } */ function request(options){ wx.showLoading({ title: '数据加载中', }) wx.request({ url: options.url, //仅为示例,并非真实的接口地址 data: options.data, method:options.method, header: { 'content-type': 'application/json' // 默认值 }, success (res) { // console.log(res.data) options.success(res.data) }, complete:()=>{ wx.hideLoading() } }) } module.exports={ request }
-
页面中使用
const {request}=require('../../utils/request')
// 1定义获取随机颜色的方法 getColors(){ request({ url:"https://www.escook.cn/api/color", method:'GET', data:{}, success:(res)=>{ this.setData({ colorList:[...this.data.colorList,...res.data] }) } }) },
-
组件
复用性强
创建组件
-
项目根目录下,新建components
-
components---->新建文件夹 mycom--->myCom文件夹右击 新建component 输入组件的名称回车自动生成4个文件
-
组件myCom的样式不会影响组件myText
-
组件myCom的样式不会影响小程序页面
-
小程序页面的样式不会影响组件myCom和组件myText
-
小程序的组件中,properties属性和data属性用法相同,都是可读可写的但是:
-
data更倾向于存储组件的私有数据
-
properties 存储外界传递给组件的私有数据
-
-
不能调用setData
-
用于给组件的this添加一些自定义的属性字段
-
this.data已被初始化完毕
-
初始化工作,比如发请求
-
退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
-
清理性质的工作
-
用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容的数据
-
用于子组件向父组件传递数据,可以传递任意数据
-
父组件还可以通过 this.selectComponent() 获取子组件实例对象
-
这样就可以直接访问子组件的任意数据和方法
-
在父组件的js中,定义一个函数,这个函数通过自定义事件的形式传递给子组件
-
在父组件的wxml中,定义自定义事件,事件对应的函数为上面定义的函数
-
在子组件的js中,通过this.triggerEvent('自定义事件名',参数),将数据发送给父组件
-
在父组件的js中,通过e.detail获取子组件传递过啦的数据
-
不支持nodeJS内置的包
-
不支持浏览器内置对象的包
-
不支持c++插件的包
-
npm安装(@1.3.3)
-
去掉app.json 中的"style":"v2"
-
修改 project.config.json
{ ... "setting": { ... "packNpmManually": true, "packNpmRelationList": [ { "packageJsonPath": "./package.json", "miniprogramNpmDistDir": "./" } ] } }
-
构建npm
-
把nodemodules中的@vant拿到项目目录中
-
引入组件 app.json
"usingComponents": { "van-button": "@vant/weapp/dist/button/index" }
-
主包:一般只包含项目的启动页面或Tabbar页面
-
分包:只包含和当前分包有关的页面和资源
-
整个小程序所有包大小不超过16M(主包+分包)
-
单个分包/主包大小不能超过2M
-
在
app.json
中的tabBar
项指定custom
字段,同时其余tabBar
相关配置也补充完整。 -
所有 tab 页的 json 里需声明
usingComponents
项,也可以在app.json
全局开启"tabBar":{ "custom":true, "list":[] }