微信小程序组件通讯方式
2021年8月19日前言
数据通信在开发中是必不可少的一个环节,也是我们必须掌握的知识。知道得越多的数据通信方式,实现业务会更加得心应手。
下面我将这些通信方式归类介绍:
- 组件通信
- 全局通信
- 页面通信
组件通信
properties
父组件向子组件通信,与 Vue 的 props 作用相同。
父组件向子组件传数据:
|
1 2 |
<span class="hljs-tag"><<span class="hljs-name">my-component</span> <span class="hljs-attr">list</span>=<span class="hljs-string">"{{list}}"</span>></span><span class="hljs-tag"></<span class="hljs-name">my-component</span>></span> |
子组件接收数据:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
Component({ <span class="hljs-attr">properties</span>:{ <span class="hljs-attr">list</span>:{ <span class="hljs-attr">type</span>: <span class="hljs-built_in">Array</span>, <span class="hljs-attr">value</span>: [] } }, <span class="hljs-function"><span class="hljs-title">attached</span>()</span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this.data</span>.list) } }) |
triggerEvent
子组件向父组件通信,与 Vue 的 $emit 作用相同
子组件触发自定义事件:
|
1 2 3 4 5 6 |
Component({ <span class="hljs-function"><span class="hljs-title">attached</span>()</span>{ <span class="hljs-built_in">this</span>.triggerEvent(<span class="hljs-string">'customEvent'</span>,{ <span class="hljs-attr">id</span>: <span class="hljs-number">10</span> }) } }) |
父组件接收自定事件:
|
1 2 |
<span class="hljs-tag"><<span class="hljs-name">my-component</span> <span class="hljs-attr">list</span>=<span class="hljs-string">"{{list}}"</span> <span class="hljs-attr">bind:customEvent</span>=<span class="hljs-string">"customEvent"</span>></span><span class="hljs-tag"></<span class="hljs-name">my-component</span>></span> |
|
1 2 3 4 5 6 |
Page({ <span class="hljs-function"><span class="hljs-title">customEvent</span>(<span class="hljs-params">e</span>)</span>{ <span class="hljs-built_in">console</span>.log(e.detail.id) } }) |
selectComponent
使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象,类似 Vue 的 ref
|
1 2 |
<span class="hljs-tag"><<span class="hljs-name">my-component</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"mycomponent"</span> <span class="hljs-attr">list</span>=<span class="hljs-string">"{{list}}"</span>></span><span class="hljs-tag"></<span class="hljs-name">my-component</span>></span> |
|
1 2 3 4 5 6 7 8 9 |
Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ <span class="hljs-keyword">let</span> mycomponent = <span class="hljs-built_in">this</span>.selectComponent(<span class="hljs-string">'#mycomponent'</span>) mycomponent.setData({ <span class="hljs-attr">list</span>: [] }) } }) |
selectOwnerComponent
选取当前组件节点所在的组件实例(即组件的引用者),返回它的组件实例对象,类似 Vue 的 $parent
|
1 2 3 4 5 6 7 |
Component({ <span class="hljs-function"><span class="hljs-title">attached</span>()</span>{ <span class="hljs-keyword">let</span> parent = <span class="hljs-built_in">this</span>.selectOwnerComponent() <span class="hljs-built_in">console</span>.log(parent) } }) |
全局通信
globalData
将数据挂载到 app.js,这种方式在开发中很常用。通过getApp(),我们能够在任何一个页面内访问到app实例。
app.js
|
1 2 3 4 5 6 |
App({ <span class="hljs-attr">globalData</span>:{ <span class="hljs-attr">list</span>:[] } }) |
page1.js
|
1 2 3 4 5 6 7 8 9 |
<span class="hljs-keyword">const</span> app = getApp() Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ app.globalData.list.push({ <span class="hljs-attr">id</span>: <span class="hljs-number">10</span> }) } }) |
page2.js
|
1 2 3 4 5 6 7 |
<span class="hljs-keyword">const</span> app = getApp() Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ <span class="hljs-built_in">console</span>.log(app.globalData.list) <span class="hljs-comment">// [{id:10}]</span> } }) |
storage
storage并不是作为通信的主要方式。storage 主要是为了缓存数据,并且最多只能存储10M的数据,我们应该合理使用storage
|
1 2 3 4 |
wx.setStorageSync(<span class="hljs-string">'timestamp'</span>, <span class="hljs-built_in">Date</span>.now()) wx.getStorageSync(<span class="hljs-string">'timestamp'</span>) wx.removeStorageSync(<span class="hljs-string">'timestamp'</span>) |
eventBus
通过发布订阅模式注册事件和触发事件进行通信
简单实现
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EventBus</span></span>{ <span class="hljs-function"><span class="hljs-title">constructor</span>()</span>{ <span class="hljs-built_in">this</span>.task = {} } <span class="hljs-function"><span class="hljs-title">on</span>(<span class="hljs-params">name, cb</span>)</span>{ <span class="hljs-function"><span class="hljs-title">if</span>(<span class="hljs-params">!<span class="hljs-built_in">this</span>.task[name]</span>)</span>{ <span class="hljs-built_in">this</span>.task[name] = [] } <span class="hljs-keyword">typeof</span> cb === <span class="hljs-string">'function'</span> && <span class="hljs-built_in">this</span>.task[name].push(cb) } <span class="hljs-function"><span class="hljs-title">emit</span>(<span class="hljs-params">name, ...arg</span>)</span>{ <span class="hljs-keyword">let</span> taskQueen = <span class="hljs-built_in">this</span>.task[name] <span class="hljs-function"><span class="hljs-title">if</span>(<span class="hljs-params">taskQueen && taskQueen.length > <span class="hljs-number">0</span></span>)</span>{ taskQueen.forEach(<span class="hljs-function"><span class="hljs-params">cb</span>=></span>{ cb(...arg) }) } } <span class="hljs-function"><span class="hljs-title">off</span>(<span class="hljs-params">name, cb</span>)</span>{ <span class="hljs-keyword">let</span> taskQueen = <span class="hljs-built_in">this</span>.task[name] <span class="hljs-function"><span class="hljs-title">if</span>(<span class="hljs-params">taskQueen && taskQueen.length > <span class="hljs-number">0</span></span>)</span>{ <span class="hljs-keyword">let</span> index = taskQueen.indexOf(cb) index != -<span class="hljs-number">1</span> && taskQueen.splice(index, <span class="hljs-number">1</span>) } } <span class="hljs-function"><span class="hljs-title">once</span>(<span class="hljs-params">name, cb</span>)</span>{ <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callback</span>(<span class="hljs-params">...arg</span>)</span>{ <span class="hljs-built_in">this</span>.off(name, cb) cb(...arg) } <span class="hljs-keyword">typeof</span> cb === <span class="hljs-string">'function'</span> && <span class="hljs-built_in">this</span>.on(name, callback) } } <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> EventBus |
使用
app.js
|
1 2 3 4 |
<span class="hljs-keyword">import</span> EventBus <span class="hljs-keyword">from</span> <span class="hljs-string">'/util/EventBus'</span> wx.$bus = <span class="hljs-keyword">new</span> EventBus() |
page1.js
|
1 2 3 4 5 6 7 8 9 |
Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ wx.$bus.on(<span class="hljs-string">'add'</span>, <span class="hljs-built_in">this</span>.addHandler) }, <span class="hljs-function"><span class="hljs-title">addHandler</span>(<span class="hljs-params">a, b</span>)</span>{ <span class="hljs-built_in">console</span>.log(a+b) } }) |
page2.js
|
1 2 3 4 5 6 |
Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ wx.$bus.emit(<span class="hljs-string">'add'</span>, <span class="hljs-number">10</span>, <span class="hljs-number">20</span>) }, }) |
页面通信
getCurrentPages
getCurrentPages() 获取当前页面栈,数组中第一个元素为首页,最后一个元素为当前页面
元素为一个对象,里面存放着页面的信息,包括route(页面路径)、options(onLoad拿到的参数)、method、data等
|
1 2 3 4 5 6 7 8 9 10 |
Page({ <span class="hljs-function"><span class="hljs-title">onLoad</span>()</span>{ <span class="hljs-keyword">let</span> pages = getCurrentPages() <span class="hljs-keyword">let</span> lastPage = pages[pages.length-<span class="hljs-number">2</span>] lastPage.setData({ <span class="hljs-attr">list</span>: [] }) } }) |
写在最后
如果你还有其他的通信方式,欢迎交流~