知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁(yè) » 新聞資訊 » 小程序相關(guān) >
小程序-頁(yè)面與頁(yè)面間如何進(jìn)行傳遞數(shù)據(jù)(通信)
發(fā)表時(shí)間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):47
在小程序中組件與組件之間的通信是通過(guò)在引用組件處,在自定義組件上添加自定義屬性實(shí)現(xiàn)的,子組件內(nèi)部通過(guò)properties
進(jìn)行接收
更多關(guān)于組件與組件之間的通信可參考小程序?qū)崿F(xiàn)自定義組件以及自定義組件間的通信這篇文章
那頁(yè)面與頁(yè)面之間又如何傳遞數(shù)據(jù)?
您將閱讀完本文后,將收獲到:
- 頁(yè)面間跳轉(zhuǎn)攜帶參數(shù)(通過(guò)
url
的方式)傳遞數(shù)據(jù) - 如何返回上一級(jí)頁(yè)面,并刷新頁(yè)面呢
- 使用全局
app
頁(yè)面定義的變量實(shí)現(xiàn)數(shù)據(jù)的傳遞 - 使用本地緩存數(shù)據(jù)
- 使用
eventChannel
向被打開(kāi)頁(yè)面?zhèn)魉蛿?shù)據(jù)(wx.navigateTo
高級(jí)用法)
頁(yè)面間通過(guò) url
方式傳遞數(shù)據(jù)
在小程序中當(dāng)中,在父頁(yè)面,通過(guò)url
方式傳遞參數(shù)到子頁(yè)面,是一種比較常見(jiàn)的做法
如下示例所示:應(yīng)用場(chǎng)景
- 點(diǎn)擊列表頁(yè)面,進(jìn)入詳情頁(yè)
- 動(dòng)態(tài)改變?cè)斍轫?yè)面的
navBar
中的title
父頁(yè)面實(shí)例代碼
<view>
<view class="list-wrap">
<block wx:for="{{listDatas}}" wx:key="index">
<view bindtap="onListTap" data-list="{{item}}">
<text>{{ item.list_text}}text>
view>
block>
view>
view>
css代碼
.list-wrap {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 15px 15px;
}
.list-wrap view {
width: 30%;
height: 300rpx;
border: 1px solid #ccc;
margin-bottom: 15px;
text-align: center;
line-height: 300rpx;
font-size: 28rpx;
}
js代碼
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
listDatas: [
{
listId: '1',
list_text: '建鋼構(gòu)混泥房',
link_phone: '137-0113-4148',
linker: '王經(jīng)理',
},
{
listId: '2',
list_text: '建辦公樓房',
link_phone: '137-0113-4148',
linker: '陳經(jīng)理',
},
{
listId: '3',
list_text: '建冰場(chǎng)鋼結(jié)構(gòu)',
link_phone: '137-0113-4148',
linker: '張經(jīng)理',
},
],
},
/**
* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
*/
onLoad: function(options) {},
onListTap(event) {
const {
listId,
list_text,
link_phone,
linker,
} = event.currentTarget.dataset.list;
// 1. 傳遞參數(shù)-通過(guò)url的方式傳遞當(dāng)前頁(yè)面數(shù)據(jù)到子頁(yè)面當(dāng)中去,在子頁(yè)面的onload的options中可以拿到
wx.navigateTo({
url: `/pages/listDetail/listDetail?id=${listId}&navtitle=${list_text}&phone=${link_phone}&link=${linker}`,
});
},
});
切換tab
選項(xiàng)就可以查看對(duì)應(yīng)的代碼,在上面示例中,從一個(gè)頁(yè)面跳轉(zhuǎn)到另一個(gè)頁(yè)面是使用wx.navigateTo()
這個(gè)方法,如果想要將該頁(yè)面的數(shù)據(jù)傳遞到子頁(yè)面中,可以通過(guò)url
拼接參數(shù)的方式進(jìn)行傳遞,多個(gè)參數(shù)之間使用&
符號(hào)相連
路徑后可以帶參數(shù),參數(shù)與路徑之間使用 ?
分隔,參數(shù)鍵與參數(shù)值用 =
相連,不同參數(shù)用 &
分隔;如path?key=value&key2=value2
上面示例代碼中使用了es6
的模板字符串,參數(shù)之間,也可以使用+
拼接,個(gè)人覺(jué)得使用+
真的很難受,不舒服,容易出錯(cuò)
如下是es6模板字符串方式拼接參數(shù)
wx.navigateTo({
url: `/pages/listDetail/listDetail?id=${listId}&navtitle=${list_text}&phone=${link_phone}&link=${linker}`,
});
如下是加號(hào)拼接方式
wx.navigateTo({
url: "/pages/listDetail/listDetail?id="+listId+"&navtitle="+list_text+"&phone="+link_phone+"&link="+link_phone+"&link="+linker,
})
}
兩者比較
通過(guò)es6
中的模板字符串,使用反引號(hào),結(jié)合模板字符串${變量}
的方式,要比使用+
加號(hào)拼接參數(shù)要好理解得多
在單個(gè)參數(shù)情況下,或許使用模板字符串與加號(hào)沒(méi)有影響,區(qū)別,但是當(dāng)多個(gè)參數(shù)時(shí),使用加號(hào)做拼接就會(huì)令人奔潰,很容易出錯(cuò)
甚至有可能在接收參數(shù)時(shí),出現(xiàn)丟失的情況,這或許就是不小心使用加號(hào)前后空格或解析參數(shù)時(shí),加號(hào)被轉(zhuǎn)義導(dǎo)致的,很容易出現(xiàn) bug
子頁(yè)面實(shí)例代碼
<view>
<view class="container">
<view>項(xiàng)目:<text>{{id}}-{{text}}text>view>
<view>聯(lián)系人: {{link}}view>
<view>聯(lián)系電話: {{phoneNumber}}view>
view>
view>
css代碼
.container {
padding: 20px 0 10px 30px;
}
.container view {
line-height: 30px;
}
js邏輯代碼
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
// 頁(yè)面中要渲染的數(shù)據(jù),數(shù)據(jù)初始化
id: null,
text: '',
phoneNumber: '',
linker: '',
},
/**
* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
*/
onLoad: function(options) {
console.log(options);
const { id, navtitle, phone, link } = options;
this._setNavTitle(navtitle);
this._getList(id, navtitle, phone, link);
},
// 設(shè)置navTitle
_setNavTitle(navtitle) {
wx.setNavigationBarTitle({
title: navtitle,
});
},
_getList(id, navtitle, phone, link) {
// 改變頁(yè)面中的數(shù)據(jù),setData
this.setData({
text: navtitle,
id,
phoneNumber: phone,
link,
});
},
});
當(dāng)父頁(yè)面通過(guò)url
的方式傳遞數(shù)據(jù)給子頁(yè)面時(shí),在子頁(yè)面中的生命周期onLoad
函數(shù)中的options
中可以拿到
想要更改什么數(shù)據(jù),直接重新setData
就可以了的
注意
url
的方式適合頁(yè)面間跳轉(zhuǎn)攜帶參數(shù),多個(gè)參數(shù)之間使用&
符號(hào)拼接- 此方法有一定的局限性,不適宜傳入復(fù)雜的數(shù)據(jù),例如:數(shù)組,對(duì)象
- 適合參數(shù)比較少的情況
url 中有多個(gè)參數(shù)時(shí)傳遞
在小程序中,向跳轉(zhuǎn)的目標(biāo)url
頁(yè)面?zhèn)鬟f的參數(shù)有時(shí)候遠(yuǎn)不止一個(gè),使用wx.navigator
進(jìn)行跳轉(zhuǎn),支持/pages/xxx/xxx?param1=${param1}?m2=${param2}?m3=${param3}
的方式,并不支持類似obj={key1:value1,key2: value2}
對(duì)象或者數(shù)組list: [arr1, arr2, arr3 ..]
若url
參數(shù)是數(shù)組情況
wx.navigateTo({
url: `/pages/listDetail/listDetail?list=${[
listId,
list_text,
link_phone,
linker,
]}`,
});
子頁(yè)面(跳轉(zhuǎn)目標(biāo)頁(yè))
onLoad: function (options) {
console.log(options);
const list = options.list.split(','); // 通過(guò)split分割成數(shù)組
console.log(list);
},
分析
當(dāng)被跳轉(zhuǎn)的 url 中的參數(shù)是數(shù)組時(shí),那么在跳轉(zhuǎn)的目標(biāo)頁(yè)面中的onLoad
生命周期函數(shù)的option
,將得到父頁(yè)面中的字符串參數(shù)
通過(guò)split
方法將字符串分割為數(shù)組,然后通過(guò)數(shù)組下標(biāo)的方式拿到對(duì)應(yīng)的參數(shù)
父頁(yè)面中
const name = 'itclanCoder';
const sex = 'boy';
wx.navigateTo({
url: `/pages/listDetail/listDetail?data=http://www.wxapp-union.com/${[name, sex]}`,
});
子頁(yè)面中
onLoad: function (options) {
console.log(options);
const data = http://www.wxapp-union.com/options.data.split(','); // 通過(guò)split分割成數(shù)組
console.log(data); // ["itclanCoder", "boy"]
},
若url
參數(shù)是對(duì)象情況
在url
參數(shù)是對(duì)象時(shí),并不會(huì)像數(shù)組一樣,在目標(biāo)頁(yè)面中onLoad
的options
對(duì)象中是一個(gè)字符串,而卻是一個(gè)對(duì)象
如下所示
{
obj: [object, object];
}
我們需要借助JSON.stringify()
對(duì)傳入的參數(shù)對(duì)象進(jìn)行序列化
父頁(yè)面(對(duì)象參數(shù)序列化)
wx.navigateTo({
url: `/pages/listDetail/listDetail?obj=${JSON.stringify({
id: listId,
text: list_text,
phone: link_phone,
link: linker,
})}`,
});
通常,我們把參數(shù)對(duì)象,定義成一個(gè)對(duì)象的,簡(jiǎn)化我們的代碼,用一個(gè)變量對(duì)象臨時(shí)存儲(chǔ)的
const params = {
// 參數(shù)放到外面,讓代碼更加清晰,可讀,可維護(hù)性更高
id: listId,
text: list_text,
phone: link_phone,
link: linker,
};
wx.navigateTo({
url: `/pages/listDetail/listDetail?obj=${JSON.stringify(params)}`,
});
那么在子頁(yè)面中,需要通過(guò)JSON.parse()
對(duì)父頁(yè)面中傳遞過(guò)來(lái)的參數(shù)進(jìn)行反序列化,否則拿到的將是字符串對(duì)象,是無(wú)法通過(guò)對(duì)象.的方式訪問(wèn)屬性
子頁(yè)面(對(duì)象參數(shù)反序列化)
onLoad: function (options) {
console.log(options);
const obj = JSON.parse(options.obj); // 將字符串對(duì)象轉(zhuǎn)化為真正的對(duì)象
console.log(obj); // {id: "1", text: "建鋼構(gòu)混泥房", phone: "137-0113-4148", link: "王經(jīng)理"}
},
分析
在父頁(yè)面中若跳轉(zhuǎn)目標(biāo)的 url 參數(shù)是對(duì)象的情況下,需要先將參數(shù)通過(guò)JSON.stringify()
序列化才可以
const params = {
// 參數(shù)放到外面,讓代碼更加清晰,可讀,可維護(hù)性更高
id: 22,
name: '川川',
sex: 'boy',
};
wx.navigateTo({
url: `/pages/listDetail/listDetail?obj=${JSON.stringify(params)}`,
});
那么在子頁(yè)面(目標(biāo)頁(yè)面中)的onLoad
的options
中
onLoad: function (options) {
console.log(options);
const obj = JSON.parse(options.obj); // 將字符串對(duì)象轉(zhuǎn)化為真正的對(duì)象
console.log(obj); // {id: 22, name: "川川",sex: "boy"}
},
可能會(huì)遇到的問(wèn)題
當(dāng)傳遞的對(duì)象數(shù)據(jù)中含有特殊字符串時(shí),在下個(gè)頁(yè)面使用JSON.parse()
還原為對(duì)象時(shí)會(huì)報(bào)錯(cuò)
也就是當(dāng)url傳參 參數(shù)值過(guò)長(zhǎng)
,在子頁(yè)面接收時(shí),會(huì)出現(xiàn)問(wèn)題,存在丟失情況
具體解決辦法
在上個(gè)頁(yè)面(被跳轉(zhuǎn)頁(yè)面)將對(duì)象轉(zhuǎn)化為字符串后(JSON.stringify()
),然后使用encodeURIComponent
進(jìn)行編碼,然后在下個(gè)頁(yè)面先用decodeURIComponent
進(jìn)行解碼,最終在還原為對(duì)象
父(上個(gè))頁(yè)面編碼
const params = {
// 參數(shù)放到外面,讓代碼更加清晰,可讀,可維護(hù)性更高
id: 22,
name: '川川',
sex: 'boy',
};
const param = encodeURIComponent(JSON.stringify(params)); // 通過(guò)encodeURIComponent編碼
wx.navigateTo({
url: `/pages/listDetail/listDetail?obj=${param}`,
});
子頁(yè)面解碼
onLoad: function (options) {
console.log(options);
const tempObj = decodeURIComponent(options.obj)
const obj = JSON.parse(tempObj); // 將字符串對(duì)象轉(zhuǎn)化為真正的對(duì)象
console.log(obj); // {id: 22, name: "川川",sex: "boy"}
},
注意
- 當(dāng)父頁(yè)面?zhèn)鬟f的
url
參數(shù)為對(duì)象時(shí),在子頁(yè)面是無(wú)法直接獲取的,在父頁(yè)面中,必須先使用JSON.stringify()
轉(zhuǎn)換為字符串
然后在下個(gè)頁(yè)面使用JSON.parse()
還原為對(duì)象,這樣在子頁(yè)面中便可以通過(guò)對(duì)象的方式拿到 - 當(dāng)父頁(yè)面?zhèn)鬟f的
url
對(duì)象數(shù)據(jù)中含有特殊字符串時(shí),在子頁(yè)面使用JSON.parse()
還原為對(duì)象時(shí)會(huì)報(bào)錯(cuò)。需要在上個(gè)(父)頁(yè)面將對(duì)象轉(zhuǎn)化為字符串后(JSON.stringify()
),在使用encodeURIComponent
進(jìn)行編碼,然后在下個(gè)(子)頁(yè)面先用decodeURIComponent
進(jìn)行解碼在還原(JSON.parse()
)為對(duì)象。
如何返回上一級(jí)頁(yè)面-并刷新頁(yè)面
在使用wx.navigateTo()
API 進(jìn)行跳轉(zhuǎn)時(shí),在子頁(yè)面中可以通過(guò)wx.navigateBack()
返回上一級(jí)頁(yè)面的
這個(gè)場(chǎng)景在日常開(kāi)發(fā)中,就有不少的
例如:寫(xiě)完微博,發(fā)完微博成功后,自動(dòng)要返回到首頁(yè),申請(qǐng)退款時(shí),跳轉(zhuǎn)到申清退款頁(yè)面等等的
const pages = getCurrentPages(); // 可以獲取當(dāng)前頁(yè)面棧,上一個(gè)頁(yè)面以及當(dāng)前頁(yè)面棧信息
console.log(pages); // 是一個(gè)數(shù)組,記錄了上一個(gè)頁(yè)面與當(dāng)前頁(yè)面信息
// 取到上一個(gè)頁(yè)面
const prevPage = pages[pages.length - 2]; // 獲取第0個(gè)頁(yè)面,也就是上個(gè)頁(yè)面
console.log(prevPage);
prevPage.onLoad(); // 可以調(diào)用上一頁(yè)面的方法
prevPage.setData({
name: 'itclanCoder',
});
這個(gè)方法非常厲害,而且很有用,當(dāng)你通過(guò)wx.navigateTo()
,一層一層跳轉(zhuǎn)到子頁(yè)面時(shí),使用getCurrentPages
方法就可以找到上級(jí),上上級(jí)的頁(yè)面棧信息
它是通過(guò)獲取到其他頁(yè)面的原型對(duì)象,然后通過(guò)小程序原型下的setData
方法,對(duì)當(dāng)前對(duì)象管理的數(shù)據(jù)data
進(jìn)行修改
這個(gè)方法getCurrentPage
方法可以操作頁(yè)面堆棧頁(yè)面的數(shù)據(jù)和方法,可以做到對(duì)子(后一)頁(yè)面對(duì)父(上一)頁(yè)面的數(shù)據(jù)管理
提示
getCurrentPages()
用于獲取當(dāng)前頁(yè)面棧,數(shù)組中第一個(gè)元素為首頁(yè),最后一個(gè)元素為當(dāng)前頁(yè)面
- 不要嘗試修改頁(yè)面棧,會(huì)導(dǎo)致路由以及頁(yè)面狀態(tài)錯(cuò)誤(不要依賴這個(gè)方法)
- 不要在
App.onLaunch
的時(shí)候調(diào)用getCurrentPages()
,此時(shí)page
還沒(méi)有生成
使用全局app
頁(yè)面定義的變量實(shí)現(xiàn)數(shù)據(jù)的傳遞
在小程序當(dāng)中,當(dāng)有多個(gè)頁(yè)面用到一些公共變量對(duì)象參數(shù)時(shí),例如:小程序的openId
,一些公用的狀態(tài),可以放到全局app
中
全局頁(yè)面 app.js
//app.js
App({
onLaunch: function() {
// 定義的全局變量,如token,某些狀態(tài)等,放在globalData下
this.globalData = http://www.wxapp-union.com/{
token: 'token',
url: 'http://coder.itclan.cn/',
userInfo: 'itclanCoder',
};
},
});
使用頁(yè)面
const app = getApp(); // 在另一頁(yè)面想要使用全局變量處,調(diào)用getApp()
Page({
// 頁(yè)面初始化的數(shù)據(jù)
data: {
token: '',
url: '',
userInfo: '',
},
// 生命周期函數(shù)
onLoad: function(options) {},
onGetGlobal() {
// 獲取全局變量
const { token, url, userInfo } = app.globalData;
console.log(token, url, userInfo);
this.setData({
token,
url,
userInfo,
});
},
});
wxml
<view>
<view class="globalData">
<view class="getGloablBtn btn" bindtap="onGetGlobal">獲取全局變量view>
<view class="changeGloablBtn btn" bindtap="onChangeGlobal"
>修改全局變量view
>
view>
<view>{{token}}view>
<view>{{url}}view>
<view>{{userInfo}}view>
view>
wxss
.globalData {
display: flex;
justify-content: start;
margin: 15px 0 0 0;
}
.getGloablBtn {
background: rgb(89, 196, 119);
margin-right: 15px;
}
.changeGloablBtn {
background: rgb(160, 10, 7);
}
.btn {
width: 120px;
height: 30px;
line-height: 30px;
color: #fff;
text-align: center;
}
分析
全局定義的變量,一些狀態(tài),可以掛載在全局頁(yè)面 app.js
的globalData
中,在使用全局變量頁(yè)面處
- 需要調(diào)用
getApp()
函數(shù) - 通過(guò)
getApp().globalData.a
可以拿到全局對(duì)象下定義的變量對(duì)象 - 若要修改全局變量對(duì)象直接賦值即可
getApp().globalData.a = "bb"
;
全局定義變量注意事項(xiàng)
App()
必須在app.js
中注冊(cè),且不能注冊(cè)多個(gè)- 不要在定義
App()
內(nèi)的函數(shù)調(diào)用getApp()
,使用this
就可以拿到App
下的實(shí)例 - 不要在
App.onLaunch
的時(shí)候調(diào)用getCurrentPages()
,此時(shí)page
還沒(méi)有生成 - 通過(guò)
getApp()
獲取到全局頁(yè)面的實(shí)例后,就不要私自調(diào)用生命周期函數(shù)了的
使用本地緩存
在微信小程序都可以有自己的本地緩存
wx.setStorageSync
:同步設(shè)置本地存儲(chǔ)某個(gè)指定的key
數(shù)據(jù)wx.setStorage
: 異步設(shè)置本地所有存儲(chǔ)某個(gè)key
數(shù)據(jù)wx.getStorage
: 異步獲取本地所有存儲(chǔ)數(shù)據(jù)wx.getStorageSync
:同步獲取本地存儲(chǔ)某個(gè)指定key
的數(shù)據(jù)wx.clearStorage
:一次性清除所有本地存儲(chǔ)(緩存)數(shù)據(jù),不需要參數(shù)wx.clearStorageSync
:一次性清除同步所有本地存儲(chǔ),不需要參數(shù)wx.removeStorage
:從本地緩存中異步移除指定key
,需要指定某個(gè)key
wx.removeStorageSync
:從本地存儲(chǔ)中同步移除指定的key
,需要指定某個(gè)key
上面的方法可以對(duì)本地緩存進(jìn)行讀寫(xiě)和清理的操作,讀與寫(xiě)都是一一對(duì)應(yīng)的
使用本地緩存,可以作為頁(yè)面間數(shù)據(jù)傳遞,但是仍然需要注意一些實(shí)用情況,如下所示
隔離策略
同一個(gè)微信用戶,同一個(gè)小程序 storage
上限為 10MB
,一般可以作為緩存臨時(shí)一些小的數(shù)據(jù),比如用戶登錄信息之類的
storage
以用戶維度隔離,同一臺(tái)設(shè)備上,A 用戶無(wú)法讀取到 B 用戶的數(shù)據(jù);不同小程序之間也無(wú)法互相讀寫(xiě)數(shù)據(jù)
存儲(chǔ)大小限制
除非用戶主動(dòng)刪除或因存儲(chǔ)空間原因被系統(tǒng)清理,否則數(shù)據(jù)都一直可用。單個(gè) key
允許存儲(chǔ)的最大數(shù)據(jù)長(zhǎng)度為 1MB,所有數(shù)據(jù)存儲(chǔ)上限為 10MB
插件隔離限制
- 同一小程序使用不同插件:不同插件之間,插件與小程序之間
storage
不互通。 - 不同小程序使用同一插件:同一插件
storage
不互通 storage
只是針對(duì)當(dāng)前用戶,不同用戶,使用不同的插件,他們之間storage
是無(wú)法實(shí)現(xiàn)數(shù)據(jù)共用的
:::
清理策略
本地緩存的清理時(shí)機(jī)跟代碼包一樣,只有在代碼包被清理的時(shí)候本地緩存才會(huì)被清理
注意事項(xiàng)
將數(shù)據(jù)存儲(chǔ)在本地緩存中指定的 key 中。會(huì)覆蓋掉原來(lái)該 key 對(duì)應(yīng)的內(nèi)容
也就是說(shuō),如果是相同的key
,后面的會(huì)覆蓋掉原來(lái)該 key
對(duì)應(yīng)的內(nèi)容
設(shè)置/獲取/刪除存儲(chǔ)
使用的是wx.setStorageSync()
,wx.getStorageSync
方法
如何設(shè)置本地存儲(chǔ)數(shù)據(jù)
wx.setStorage({
key: 'key',
data: 'value',
});
或如下簡(jiǎn)寫(xiě)方式
wx.setStorageSync('key', 'value');
如何獲取本地存儲(chǔ)數(shù)據(jù)
wx.getStorageSync({
key: 'key',
success(res) {
console.log(res.data);
},
});
或如下簡(jiǎn)寫(xiě)
var value = http://www.wxapp-union.com/wx.getStorageSync('key');
如何刪除本地存儲(chǔ)數(shù)據(jù)
清除小程序當(dāng)中的本地存儲(chǔ)分為一次性全部刪除所有存儲(chǔ),與刪除存儲(chǔ)中某指定的存儲(chǔ)key
wx.clearStorage(); // 一次性刪除小程序中的所有存儲(chǔ)數(shù)據(jù)
刪除存儲(chǔ)中某指定的存儲(chǔ)key
,一定要注意這兩者的區(qū)別,有的小伙伴只知道wx.clearStorage()
wx.removeStorageSync('key'); // 刪除小程序中指定的key的存儲(chǔ)
同樣等價(jià)于
wx.removeStorageSync({
key: 'key',
success(res) {
console.log(res);
},
});
注意:wx.removeStorageSync
方法,不同于wx.clearStorageSync()
方法,它同樣也是刪除小程序中所有同步存儲(chǔ)的數(shù)據(jù),
前者需要指定刪除存儲(chǔ)對(duì)應(yīng)的key
值,而后者不需要指定key
,它是一次性刪除所有同步存儲(chǔ)的代碼
wx.clearStorageSync(); // 一次性刪除小程序中所有同步存儲(chǔ)的數(shù)據(jù)
關(guān)于小程序中本地存儲(chǔ)的方法確實(shí)容易讓人暈,搞混淆,理解它們的區(qū)別,還是要在開(kāi)發(fā)者工具中,自行調(diào)試,才知道每個(gè)方法之間區(qū)別差異的
光看文字,不動(dòng)手寫(xiě)代碼測(cè)試,是無(wú)法理解他們之間的差異的,很容易搞混,在使用時(shí)容易亂套
提示
凡是帶sync
結(jié)尾的都是同步的,而凡是帶clear
開(kāi)頭的都是一次性清除同步/異步的存儲(chǔ),而帶·remove
開(kāi)頭的都是需要指定刪除某個(gè)存儲(chǔ)的key
解決相同 key 覆蓋問(wèn)題
在小程序中,當(dāng)出現(xiàn)同名key
,后者key
覆蓋前者是一個(gè)讓人頭疼的問(wèn)題
具體解決
可以將需要存儲(chǔ)數(shù)據(jù)存到一個(gè)數(shù)組當(dāng)中,當(dāng)需要使用時(shí),取最后一個(gè)即可
至于若有增刪操作,每次刪除完某一數(shù)據(jù)后,重新在設(shè)置一次本地存儲(chǔ)即可
let lists = wx.getStorageSync('lists'); // 先獲取lists本地存儲(chǔ)的數(shù)據(jù)
if (!lists) {
// 第一次判斷緩存中有沒(méi)有l(wèi)ists數(shù)據(jù)
lists = []; // 若沒(méi)有,則存儲(chǔ)設(shè)置一個(gè)空數(shù)組
}
lists.push(data); // 這里的data是要存儲(chǔ)到本地中的數(shù)據(jù)
wx.setStorageSync('lists', lists); // 設(shè)置本地存儲(chǔ)key:val
通過(guò)上面的操作,就解決了存儲(chǔ) key 值覆蓋的問(wèn)題,那么如何取最新的呢
const storageList = wx.getStorageSync('lists');
const listData = http://www.wxapp-union.com/storageList[storageList.length - 1]; // 獲取到最后一個(gè)
this.setData({
// 重新setData數(shù)據(jù)即可
lists: listData,
});
是使用同步存儲(chǔ)還是異步存儲(chǔ)
帶有Sync
,這個(gè)表示的同步的操作,與之相對(duì)的不帶后綴就是異步”。
同步與異步是指的消息通訊機(jī)制。就是信息傳來(lái)傳去的時(shí)候是同步還異步。重點(diǎn)強(qiáng)調(diào)的是通訊這個(gè)動(dòng)作。
很容易混淆,在計(jì)算機(jī)里,他們兩是對(duì)立,相反的,同步代碼是順序執(zhí)行,會(huì)形成阻塞,而異步代碼不會(huì)阻塞,它是等待主線程執(zhí)行完后,可以在回過(guò)頭來(lái)執(zhí)行
比如要請(qǐng)求用戶信息的時(shí)候,需要從緩存中獲取username
這個(gè)變量,那只有先獲取到這個(gè)變量才能進(jìn)行下一步。那就應(yīng)該使用同步,使用wx.getStorageSync
。這樣能確保一定能獲取到這個(gè)變量,所有在第一次獲取緩存中的數(shù)據(jù)時(shí)
我們往往先要判斷一下緩存中是否有我們想要的那一數(shù)據(jù)的,否則若沒(méi)有,在代碼中使用了,就會(huì)報(bào)錯(cuò)
打電話就是一個(gè)同步的例子,必須先打完上一個(gè),然后才能在打下一個(gè),而發(fā)短信就是一個(gè)異步的例子,你可以跟 A 同學(xué)發(fā),發(fā)完后不用等待,也可以更 B 同學(xué)發(fā)
在相同的時(shí)間內(nèi),使用同步只能干一件事情,必須得一件,一件的干完,而異步則在同一段時(shí)間內(nèi),可以同時(shí)干多件事情
JavaScript
是單線程的,但是瀏覽器是多線程的.它的異步是借助事件實(shí)現(xiàn)的.具體可自行查看多線程與單線程相關(guān)知識(shí)的
使用eventChannel
向被打開(kāi)頁(yè)面?zhèn)魉蛿?shù)據(jù)(wx.navigateTo
高級(jí)用法)
對(duì)于頁(yè)面與頁(yè)面之間的數(shù)據(jù)通信,一種方式是,可以通過(guò)url
攜帶參數(shù)的方式跳轉(zhuǎn)到指定的頁(yè)面,在跳轉(zhuǎn)的指定頁(yè)面中的onLoad
生命周期函數(shù)中的options
中可以拿到數(shù)據(jù)
但是這種傳遞數(shù)據(jù)的方式是有限的,不適合數(shù)據(jù)多的情況下
另一種方式是可以傳遞數(shù)據(jù)沒(méi)有限制,wx.navigateTo
提供了一種更加高級(jí)的用法,通過(guò)eventChannel
向被打開(kāi)頁(yè)面?zhèn)魉蛿?shù)據(jù)
父(當(dāng)前)頁(yè)面向子(目標(biāo))頁(yè)面?zhèn)鬟f數(shù)據(jù)
被打開(kāi)(上/父級(jí))頁(yè)面
Page({
data: {
parentPageData: {
name: '川川',
url: 'http://coder.itclan.cn',
vx: 'itclanCoder',
},
},
onEventChannel() {
const parentPageData = http://www.wxapp-union.com/this.data.parentPageData; // 當(dāng)前頁(yè)面的數(shù)據(jù)
wx.navigateTo({
url: `/pages/listDetail/listDetail`, // 打開(kāi)的目標(biāo)頁(yè)面
success: (res) => {
// 通過(guò)eventChannel向被打開(kāi)頁(yè)面?zhèn)魉蛿?shù)據(jù),目標(biāo)頁(yè)面是listDetail,這個(gè)data名字是你自己取的任意,在目標(biāo)頁(yè)面中有個(gè)參數(shù)接收就可以
res.eventChannel.emit('parentPageEmit', { data: parentPageData });
},
});
},
});
被打開(kāi)(上/父級(jí))頁(yè)面的wxml
,綁定事件
<view bindtap="onEventChannel">打開(kāi)跳轉(zhuǎn)到目標(biāo)頁(yè)面view>
打開(kāi)(目標(biāo))頁(yè)面
在目標(biāo)打開(kāi)頁(yè)面中通過(guò)getOpenerEventChange
方法,用on
進(jìn)行監(jiān)聽(tīng)被跳轉(zhuǎn)頁(yè)面的方法,就可以拿到被跳轉(zhuǎn)頁(yè)面中通過(guò)emit
方法傳遞過(guò)來(lái)的數(shù)據(jù),其中使用on
監(jiān)聽(tīng)的方法名與被跳轉(zhuǎn)頁(yè)面的名字保持一致就可以,這樣實(shí)現(xiàn)了兩個(gè)不同頁(yè)面之間的數(shù)據(jù)通信傳遞
Page({
data: {
acceptParentData: {},
},
onLoad: function(options) {
// 通過(guò)getOpenerEventChannel對(duì)象,對(duì)`parentPageEmit`進(jìn)行監(jiān)聽(tīng)
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('parentPageEmit', (data) => {
console.log(data);
this.setData({
acceptParentData: data,
});
});
},
});
說(shuō)明
將某整個(gè)父頁(yè)面的數(shù)據(jù)傳遞給跳轉(zhuǎn)到的子頁(yè)面,是一個(gè)比較常見(jiàn)的需求操作
比如在商品詳情頁(yè)面中,跳到到下單頁(yè)面,需要將詳情頁(yè)面的一些數(shù)據(jù)
傳遞給跳轉(zhuǎn)的子頁(yè)面,那么這個(gè)時(shí)候,用url
的方式傳遞數(shù)據(jù)就不時(shí)很合適,選用eventChannel
的方式就比價(jià)適合
在wx.navigateTo
的成功success
回調(diào)中,通過(guò)emit
進(jìn)行觸發(fā),emit
接收兩個(gè)參數(shù),第一個(gè)是監(jiān)聽(tīng)事件的名稱,第二個(gè)參數(shù)是需要向目標(biāo)頁(yè)面?zhèn)鬟f的數(shù)據(jù)
res.eventChannel.emit(`監(jiān)聽(tīng)的事件名稱parentPageEmit`, { data: '數(shù)據(jù)' });
在跳轉(zhuǎn)的目標(biāo)頁(yè)面中,通過(guò)調(diào)用getOpenerEventChannel
方法,然后進(jìn)行on
的綁定
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('監(jiān)聽(tīng)的事件名稱parentPageEmit', (data) => {
console.log(data);
this.setData({
acceptParentData: data,
});
});
當(dāng)前頁(yè)面-->
目標(biāo)頁(yè)面是利用wx.navigateTo
中的 success
回調(diào)中使用 emit
觸發(fā),目標(biāo)跳轉(zhuǎn)頁(yè)面用 on
監(jiān)聽(tīng)
實(shí)現(xiàn)將當(dāng)前頁(yè)面的數(shù)據(jù)傳遞給目標(biāo)頁(yè)面中
那當(dāng)前頁(yè)面又如何獲取目標(biāo)頁(yè)面的數(shù)據(jù)呢
父(當(dāng)前)頁(yè)面如何獲取跳轉(zhuǎn)(子/目標(biāo))頁(yè)面中的數(shù)據(jù)
知道了當(dāng)前頁(yè)面向目標(biāo)跳轉(zhuǎn)頁(yè)面?zhèn)鬟f數(shù)據(jù),那么反過(guò)來(lái),當(dāng)前頁(yè)面又如何接收跳轉(zhuǎn)頁(yè)面?zhèn)鬟f過(guò)來(lái)的數(shù)據(jù)?
當(dāng)前頁(yè)面
Page({
data: {
parentPageData: {
name: '川川',
url: 'http://coder.itclan.cn',
vx: 'itclanCoder',
},
subdetailData: {},
},
onEventChannel() {
const parentPageData = http://www.wxapp-union.com/this.data.parentPageData; // 當(dāng)前頁(yè)面的數(shù)據(jù)
wx.navigateTo({
url: `/pages/listDetail/listDetail`, // 打開(kāi)的目標(biāo)頁(yè)面
events: {
// 頁(yè)面間通信接口,用于監(jiān)聽(tīng)被打開(kāi)頁(yè)面發(fā)送到當(dāng)前頁(yè)面的數(shù)據(jù)
// 為指定事件添加一個(gè)監(jiān)聽(tīng)器,獲取被打開(kāi)頁(yè)面?zhèn)魉偷疆?dāng)前頁(yè)面的數(shù)據(jù)
subPageEmit: (data) => {
console.log(data);
this.setData({
subdetailData: data,
});
},
},
});
},
});
wxml
<view class="subdetail-box">
<block wx:for="{{subdetailData}}" wx:key="index">
<view>姓名:{{item.name}}view>
<view>站點(diǎn):{{item.url}}view>
<view>微信:{{item.vx}}view>
block>
view>
子頁(yè)面目標(biāo)頁(yè)面
Page({
data: {
subdetailData: {
name: '輕記賬小程序-我是子頁(yè)面?zhèn)鬟f過(guò)來(lái)的數(shù)據(jù)',
url: 'http://itclan.cn/',
vx: 'itclanCoder',
},
},
onLoad: function(options) {
this.returnSubPagePrev();
},
returnSubPagePrev() {
const subdetailData = http://www.wxapp-union.com/this.data.subdetailData;
const eventChannel = this.getOpenerEventChannel();
// 通過(guò)emit的方式進(jìn)行觸發(fā),將子頁(yè)面/目標(biāo)頁(yè)面中的數(shù)據(jù)傳遞給當(dāng)前頁(yè)面
eventChannel.emit('subPageEmit', { data: subdetailData });
},
});
說(shuō)明
在當(dāng)前頁(yè)面中獲取子頁(yè)面的數(shù)據(jù),是借助wx.navigateTo
中提供的event
這個(gè)參數(shù)接口,它可以用于監(jiān)聽(tīng)被打開(kāi)頁(yè)面發(fā)送到當(dāng)前頁(yè)面的數(shù)據(jù)
換言之,也就是當(dāng)前頁(yè)面可以獲取監(jiān)聽(tīng)到子頁(yè)面?zhèn)鬟f過(guò)來(lái)的數(shù)據(jù),在子頁(yè)面中通過(guò)emit
的方式進(jìn)行觸發(fā),同樣,emit
方法接收兩個(gè)參數(shù)
第一個(gè)是監(jiān)聽(tīng)的事件名稱,第二個(gè)參數(shù)對(duì)象是具體要傳遞的數(shù)據(jù)
結(jié)語(yǔ)
本文主要介紹 4 種在小程序當(dāng)中頁(yè)面與頁(yè)面之間的傳遞數(shù)據(jù)常見(jiàn)方法,其中如何返回上一級(jí)頁(yè)面,這些都是實(shí)際開(kāi)發(fā)中經(jīng)常會(huì)遇到的問(wèn)題
每一種方法都有與之對(duì)應(yīng)的應(yīng)用場(chǎng)景,url
方式比較適合跳轉(zhuǎn),攜帶少量的數(shù)據(jù),當(dāng)多個(gè)頁(yè)面需要共享同一個(gè)數(shù)據(jù)對(duì)象時(shí),可以使用全局globalData
對(duì)象,也可以使用本地緩存數(shù)據(jù)
以及最后一種使用 eventChannel
向被打開(kāi)頁(yè)面?zhèn)魉蛿?shù)據(jù)(wx.navigateTo
高級(jí)用法)
它適合一種傳遞復(fù)雜的數(shù)據(jù).
關(guān)于頁(yè)面之間數(shù)據(jù)傳遞就介紹這么多,如果您有問(wèn)題,歡迎補(bǔ)充,給我留言,一起學(xué)習(xí)成長(zhǎng)
相關(guān)案例查看更多
相關(guān)閱讀
- 網(wǎng)站建設(shè)專業(yè)品牌
- 百度小程序
- 云南做軟件
- 微信小程序
- 云南網(wǎng)站建設(shè)首選公司
- 前端
- 云南微信小程序開(kāi)發(fā)
- 報(bào)廢車管理系統(tǒng)
- 網(wǎng)站制作
- 大理網(wǎng)站建設(shè)公司
- 搜索引擎排名
- 江蘇小程序開(kāi)發(fā)
- 昆明做網(wǎng)站建設(shè)的公司排名
- 云南網(wǎng)絡(luò)營(yíng)銷
- 汽車拆解管理系統(tǒng)
- 分銷系統(tǒng)
- 網(wǎng)站建設(shè)快速優(yōu)化
- 云南網(wǎng)站建設(shè)百度官方
- 網(wǎng)站建設(shè)靠譜公司
- 軟件定制公司
- 云南網(wǎng)站建設(shè)費(fèi)用
- 霸屏推廣
- 云南網(wǎng)站建設(shè)百度
- 云南建設(shè)廳網(wǎng)站首頁(yè)
- 云南網(wǎng)站建設(shè)制作
- 小程序用戶登錄
- 云南網(wǎng)站建設(shè)首選
- 小程序開(kāi)發(fā)聯(lián)系方式
- 開(kāi)通微信小程序被騙
- web教程