Vue 頁(yè)面狀態(tài)保持頁(yè)面間數(shù)據(jù)傳輸?shù)囊环N方法(推薦)
如果大家覺(jué)得有用,更多的模塊請(qǐng) 點(diǎn)擊查看
vue router給我們提供了兩種頁(yè)面間傳遞參數(shù)的方式:
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 帶查詢參數(shù),變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
下面介紹一下 vue-viewplus 一個(gè)簡(jiǎn)化Vue應(yīng)用開(kāi)發(fā)的工具庫(kù) 中的參數(shù)棧模塊params-stack.js:
該插件為Vue實(shí)例提供了一個(gè) $vp 屬性,模塊提供了一系列api,來(lái)做自己的頁(yè)面參數(shù)方式:
// 跳轉(zhuǎn)頁(yè)面,并傳遞參數(shù)
this.$vp.psPageNext('/Demo/PageStack/Page2', {
params: {
phoneNumb: '15111111111'
}
})
這一點(diǎn)和vue router給我們提供的傳遞方式類似,并且目前還不支持 query: { plan: 'private' } 傳遞url參數(shù),但是我們?yōu)槭裁催€要做這個(gè)模塊:
- 提供一個(gè) 棧 來(lái)管理?xiàng)?nèi)所有頁(yè)面的參數(shù),方便頁(yè)面在回退的時(shí)候,拿到對(duì)應(yīng)頁(yè)面的 緩存參數(shù) ;即一般我們使用vue router的時(shí)候每個(gè)頁(yè)面的參數(shù)(除了使用url參數(shù)),在做統(tǒng)一返回鍵處理的時(shí)候,都不太方便進(jìn)行頁(yè)面狀態(tài)恢復(fù),而如果我們提供了一個(gè)棧,在頁(yè)面入棧的時(shí)候,將當(dāng)前頁(yè)面的參數(shù)存儲(chǔ),在下一個(gè)頁(yè)面點(diǎn)擊返回按鈕回到當(dāng)前頁(yè)面的時(shí)候我們?cè)購(gòu)膮?shù)?;謴?fù)參數(shù),這樣就能實(shí)現(xiàn)客戶端開(kāi)發(fā)中具有的這一特性;
- 該參數(shù)棧也支持緩存->自動(dòng)恢復(fù),vuex state和session storage兩級(jí)存儲(chǔ)保證參數(shù)棧不會(huì)被頁(yè)面刷新而導(dǎo)致頁(yè)面參數(shù)丟失
- 也為了統(tǒng)一編程方式
并且,當(dāng)前模塊提供的參數(shù)傳遞方式,和vue router給我們提供了兩種頁(yè)面間傳遞參數(shù)的方式, 并不沖突 ,可以互補(bǔ)使用。
只不過(guò)目前插件的參數(shù)棧并沒(méi)有管理vue router幫我們傳遞的參數(shù);
vuex state 參數(shù)棧存儲(chǔ)示例:

session storage 參數(shù)棧二級(jí)存儲(chǔ)示例:

示例
模擬一個(gè)簡(jiǎn)單表單提交流程

圖 詳見(jiàn)源碼 example 項(xiàng)目中當(dāng)前模塊示例
表單錄入頁(yè)面(簡(jiǎn)稱:Page1)
<template>
<group title="模擬手機(jī)號(hào)充值 - 堆棧底-第一頁(yè)" label-width="5em" class="bottom-group">
<box gap="10px 10px">
<x-input title="手機(jī)號(hào)" v-model="dataParams.phoneNumb"></x-input>
</box>
<box gap="10px 10px">
<x-button plain @click.native="submit()">點(diǎn)擊充值</x-button>
<x-button plain @click.native="modify()">修改參數(shù)棧內(nèi)參數(shù)對(duì)象</x-button>
</box>
</group>
</template>
<script type="text/ecmascript-6">
import demoMixin from '../demo-mixin'
import { XInput } from 'vux'
// 1.參數(shù)棧模塊提供的一個(gè)**混入**組件,方便頁(yè)面組件簡(jiǎn)化參數(shù)棧的api操作和開(kāi)發(fā),詳見(jiàn)下面的`paramsStack mixin`說(shuō)明
import { paramsStack } from 'vue-viewplus'
export default {
// 2.使用`paramsStack mixin`
mixins: [paramsStack, demoMixin],
components: {
XInput
},
data() {
return {
// 3.【可選】`paramsStack mixin`中定義的`data`屬性,聲明當(dāng)前頁(yè)面組件是參數(shù)棧的棧底,當(dāng)當(dāng)前頁(yè)面被點(diǎn)擊返回彈出的時(shí)候,插件會(huì)檢測(cè)這個(gè)屬性,如果為true,就清空參數(shù)棧
// isStackBottom: true,
// 4.自定義需要傳遞到下一個(gè)頁(yè)面的參數(shù)
dataParams: {
phoneNumb: ''
}
}
},
methods: {
submit() {
this.$vp.psPageNext('/Demo/PageStack/Page2', {
params: this.dataParams
})
}
},
created() {
// 【可選】類似第三步
// this.isStackBottom = true
// 5.解析回傳參數(shù)
if (!_.isEmpty(this.backParams)) {
this.dataParams.phoneNumb = this.backParams.phoneNumb
this.$vp.toast(`通過(guò) backParams.phoneNumb 預(yù)填寫頁(yè)面`)
}
}
}
</script>
表單確認(rèn)頁(yè)面(簡(jiǎn)稱:Page2)
<template>
<group label-width="15em" class="bottom-group">
<form-preview header-label="請(qǐng)確認(rèn)訂單信息" :body-items="list" ></form-preview>
<x-input title="請(qǐng)輸出充值金額" v-model="dataParams.amount" style="margin-top: 10px"></x-input>
<box gap="10px 10px">
<flexbox>
<flexbox-item>
<x-button type="default" @click.native="replace()">確認(rèn)</x-button>
</flexbox-item>
<flexbox-item>
<x-button type="default" @click.native="bck()">返回(回傳參數(shù))</x-button>
</flexbox-item>
</flexbox>
</box>
</group>
</template>
<script type="text/ecmascript-6">
import demoMixin from '../demo-mixin'
import { paramsStack } from 'vue-viewplus'
import { XInput, FormPreview, Flexbox, FlexboxItem } from 'vux'
export default {
mixins: [paramsStack, demoMixin],
components: {
FormPreview,
Flexbox,
FlexboxItem,
XInput
},
data() {
return {
// 1. 回顯上一個(gè)頁(yè)面錄入的手機(jī)號(hào)
list: [
{
label: '手機(jī)號(hào)',
value: ''
}
],
// 2. 自定義需要傳遞到下一個(gè)頁(yè)面的參數(shù)
dataParams: {
phoneNumb: '',
amount: '50元'
}
}
},
methods: {
/**
* 4.提交表單方式1
* 如果需要下一個(gè)頁(yè)面點(diǎn)擊返回,任然要回顯當(dāng)前頁(yè)面,就調(diào)用該方法
* /
next() {
this.$vp.psPageNext('/Demo/PageStack/Page4', { params: this.dataParams })
},
/**
* 4.提交表單方式2
* 一般確認(rèn)頁(yè)面都無(wú)需被“保留”,故這里使用`this.$vp.psPageReplace`接口完成跳轉(zhuǎn),底層將會(huì)使用
* `router.replace({location})`完成跳轉(zhuǎn)
*/
replace() {
this.$vp.psPageReplace('/Demo/PageStack/Page4', {params: this.dataParams})
},
bck() {
this.$vp.psPageGoBack({
// 3.設(shè)置回傳參數(shù)
backParams: {
phoneNumb: '13222222222'
}
})
}
},
created() {
this.list[0].value = this.params.phoneNumb
this.dataParams.phoneNumb = this.params.phoneNumb
}
}
</script>
表單結(jié)果頁(yè)面(簡(jiǎn)稱:Page4)
<template>
<div>
<msg title="操作成功" :description="description" :buttons="buttons"></msg>
</div>
</template>
<script type="text/ecmascript-6">
import demoMixin from '../demo-mixin'
import { paramsStack } from 'vue-viewplus'
import { FormPreview, Msg } from 'vux'
export default {
mixins: [paramsStack, demoMixin],
components: {
FormPreview,
Msg
},
data() {
return {
description: '',
buttons: [{
type: 'primary',
text: '在做一筆',
onClick: ((that) => {
return () => {
// 返回棧頂頁(yè)面
that.$vp.psPageGoBack()
}
})(this)
}, {
type: 'default',
text: '完成',
onClick: ((that) => {
return () => {
// 返回指定頁(yè)面,并清空參數(shù)棧
// that.$vp.psPageGoBack({
// backPopPageNumbs: -2,
// clearParamsStack: true
// })
that.$vp.psPageNext('/Demo', {
clearParamsStack: true,
backState: true
})
}
})(this)
}]
}
},
created() {
this.description = `${this.params.phoneNumb} 成功充值 ${this.params.amount}`
}
}
</script>
paramsStack mixin
以上3個(gè)頁(yè)面都集成了 paramsStack mixin ,定義如下:
/**
* 參數(shù)棧mixin對(duì)象
* <p>
* 方便頁(yè)面組件繼承之后操作參數(shù)棧
* @type {Object}
*/
export const paramsStackMixin = {
data() {
return {
/**
* 聲明該頁(yè)面是棧底部
*/
isStackBottom: false
}
},
computed: {
...mapGetters([
/**
* 查看`vuex#vplus.paramsStack[top-length]`棧頂參數(shù)
*/
'params'
]),
/**
* 查看`vuex#vplus.backParams`回傳參數(shù)
*/
backParams() {
return this.$store.state[MODULE_NAME].backParams
},
/**
* 查看`vuex#vplus.backState`是否是出棧|是否是返回狀態(tài)
*/
backState() {
return this.$store.state[MODULE_NAME].backState
}
},
methods: {
...mapMutations([
/**
* 入棧
*/
'pushParams',
/**
* 修改棧頂參數(shù)
*/
'modifyParams',
/**
* 出棧
*/
'popParams',
/**
* 清空參數(shù)棧
*/
'clearParamsStack',
/**
* 設(shè)置是否是出棧|是否是返回狀態(tài)(點(diǎn)擊返回頁(yè)面)
*/
'setBackState'
])
},
// 導(dǎo)航離開(kāi)該組件的對(duì)應(yīng)路由時(shí)調(diào)用
beforeRouteLeave(to, from, next) {
if (this.backState && this.isStackBottom) {
this.clearParamsStack()
}
next()
}
}
配置
沒(méi)有個(gè)性化配置,可以查看全局通用配置
API接口
restoreParamsStack
/** * $vp.restoreParamsStack() * 恢復(fù)插件中`vuex#$vp.paramsStack` && vuex#$vp.backParams` && vuex#$vp.backState`參數(shù)棧所用狀態(tài) * <p> * 在當(dāng)前模塊重新安裝的時(shí)候,一般對(duì)應(yīng)就是插件初始化和頁(yè)面刷新的時(shí)候 */ restoreParamsStack()
psModifyBackState
/**
* $vp.psModifyBackState(bckState)
* <p>
* 設(shè)置`vuex#vplus.backState`返回狀態(tài)
* @param {Boolean} [backState=false]
*/
psModifyBackState(bckState)
psClearParamsStack
/** * $vp.psClearParamsStack() * <p> * 清空參數(shù)棧 */ psClearParamsStack()
psPageNext
/**
* $vp.(location[, {params = {}, clearParamsStack = false, backState = false} = {}])
* <p>
* 頁(yè)面導(dǎo)航
* @param location router location對(duì)象
* @param {Object} [params={}] 向下一個(gè)頁(yè)面需要傳遞的參數(shù)
* @param {Boolean} [clearParamsStack=false] 在進(jìn)行頁(yè)面導(dǎo)航的時(shí)候,是否清空參數(shù)棧,默認(rèn)為false
* @param {Boolean} [backState=false] 設(shè)置`vuex#vplus.backState`返回狀態(tài),默認(rèn)為false
*/
psPageNext(location, {params = {}, clearParamsStack = false, backState = false} = {})
psPageReplace
/**
* $vp.(location[, {params = {}, isPop = true} = {}])
* <p>
* 頁(yè)面導(dǎo)航(基于Router),移除上一個(gè)頁(yè)面
* <p>
* 將會(huì)出棧頂對(duì)象,并重新設(shè)置`params`為參數(shù)棧的棧頂參數(shù)
* 注:在調(diào)用該方法的頁(yè)面,必須是要調(diào)用`ParamsStack#psPageNext`導(dǎo)航的頁(yè)面,因?yàn)樾枰WC“彈?!辈僮鳠o(wú)誤,
* 又或者設(shè)置`isPop`為false
* @param location router location對(duì)象
* @param {Object} [params={}] 向下一個(gè)頁(yè)面需要傳遞的參數(shù)
* @param {Boolean} [isPop=false] 是否pop當(dāng)前頁(yè)面的參數(shù)后在進(jìn)行頁(yè)面跳轉(zhuǎn),默認(rèn)為true,防止當(dāng)前頁(yè)面
* 不是通過(guò)`ParamsStack#psPageNext`導(dǎo)航過(guò)來(lái)的,但是由需要使用當(dāng)前方法
*/
psPageReplace(location, {params = {}, isPop = true} = {})
psPageGoBack
/**
* $vp.psPageGoBack({backParams = {}, clearParamsStack = false, backPopPageNumbs = -1} = {})
* <p>
* 頁(yè)面回退
* @param {Object} backParams 設(shè)置回傳參數(shù)
* @param {Boolean} clearParamsStack 是否清空參數(shù)棧
* @param {Number} backPopPageNumbs 出棧頁(yè)面數(shù)
*/
psPageGoBack({backParams = {}, clearParamsStack = false, backPopPageNumbs = -1} = {})
相關(guān)文章
vue中的stylus及stylus-loader版本問(wèn)題
這篇文章主要介紹了vue中的stylus及stylus-loader版本問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
iview tabs 頂部導(dǎo)航欄和模塊切換欄的示例代碼
這篇文章主要介紹了iview tabs 頂部導(dǎo)航欄和模塊切換欄的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
使用vue框架 Ajax獲取數(shù)據(jù)列表并用BootStrap顯示出來(lái)
這篇文章主要介紹了使用vue框架 Ajax獲取數(shù)據(jù)列表并用BootStrap顯示出來(lái),需要的朋友可以參考下2017-04-04
vue3如何將html元素變成canvas(海報(bào)生成),進(jìn)行圖片保存/截圖
這篇文章主要介紹了vue3實(shí)現(xiàn)將html元素變成canvas(海報(bào)生成),進(jìn)行圖片保存/截圖,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Vue實(shí)現(xiàn)DateRange選擇器的禁選功能
在基于Vue.js構(gòu)建的應(yīng)用程序中,處理日期選擇器是一個(gè)常見(jiàn)的需求,尤其是在涉及到日期范圍的選擇時(shí),Vue提供了多種方式來(lái)實(shí)現(xiàn)日期選擇器的功能,并允許我們對(duì)這些組件進(jìn)行高度定制,本文將深入探討如何在Vue應(yīng)用中實(shí)現(xiàn)DateRange選擇器的禁選功能,需要的朋友可以參考下2024-10-10

