Vue 页面状态保持页面间数据传输的一种方法(推荐)

如果大家觉得有用,更多的模块请 点击查看

vue router给我们提供了两种页面间传递参数的方式:

// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

下面介绍一下 vue-viewplus 一个简化Vue应用开发的工具库 中的参数栈模块params-stack.js

该插件为Vue实例提供了一个 $vp 属性,模块提供了一系列api,来做自己的页面参数方式:

// 跳转页面,并传递参数
this.$vp.psPageNext('/Demo/PageStack/Page2', {
 params: {
  phoneNumb: '15111111111'
 }
})

这一点和vue router给我们提供的传递方式类似,并且目前还不支持 query: { plan: 'private' } 传递url参数,但是我们为什么还要做这个模块:

  • 提供一个 栈 来管理栈内所有页面的参数,方便页面在回退的时候,拿到对应页面的 缓存参数 ;即一般我们使用vue router的时候每个页面的参数(除了使用url参数),在做统一返回键处理的时候,都不太方便进行页面状态恢复,而如果我们提供了一个栈,在页面入栈的时候,将当前页面的参数存储,在下一个页面点击返回按钮回到当前页面的时候我们再从参数栈恢复参数,这样就能实现客户端开发中具有的这一特性;
  • 该参数栈也支持缓存->自动恢复,vuex state和session storage两级存储保证参数栈不会被页面刷新而导致页面参数丢失
  • 也为了统一编程方式

并且,当前模块提供的参数传递方式,和vue router给我们提供了两种页面间传递参数的方式, 并不冲突 ,可以互补使用。

只不过目前插件的参数栈并没有管理vue router帮我们传递的参数;

vuex state 参数栈存储示例:

session storage 参数栈二级存储示例:

示例

模拟一个简单表单提交流程

图 详见源码 example 项目中当前模块示例

表单录入页面(简称:Page1)

<template>
 <group title="模拟手机号充值 - 堆栈底-第一页" label-width="5em" class="bottom-group">
  <box gap="10px 10px">
   <x-input title="手机号" v-model="dataParams.phoneNumb"></x-input>
  </box>
  <box gap="10px 10px">
   <x-button plain @click.native="submit()">点击充值</x-button>
   <x-button plain @click.native="modify()">修改参数栈内参数对象</x-button>
  </box>
 </group>
</template>

<script type="text/ecmascript-6">
import demoMixin from '../demo-mixin'
import { XInput } from 'vux'
// 1.参数栈模块提供的一个**混入**组件,方便页面组件简化参数栈的api操作和开发,详见下面的`paramsStack mixin`说明
import { paramsStack } from 'vue-viewplus'

export default {
 // 2.使用`paramsStack mixin`
 mixins: [paramsStack, demoMixin],
 components: {
  XInput
 },
 data() {
  return {
   // 3.【可选】`paramsStack mixin`中定义的`data`属性,声明当前页面组件是参数栈的栈底,当当前页面被点击返回弹出的时候,插件会检测这个属性,如果为true,就清空参数栈
   // isStackBottom: true,
   // 4.自定义需要传递到下一个页面的参数
   dataParams: {
    phoneNumb: ''
   }
  }
 },
 methods: {
  submit() {
   this.$vp.psPageNext('/Demo/PageStack/Page2', {
    params: this.dataParams
   })
  }
 },
 created() {
  // 【可选】类似第三步
  // this.isStackBottom = true
  // 5.解析回传参数
  if (!_.isEmpty(this.backParams)) {
   this.dataParams.phoneNumb = this.backParams.phoneNumb
   this.$vp.toast(`通过 backParams.phoneNumb 预填写页面`)
  }
 }
}
</script>

表单确认页面(简称:Page2)
<template>
 <group label-width="15em" class="bottom-group">
  <form-preview header-label="请确认订单信息" :body-items="list" ></form-preview>
  <x-input title="请输出充值金额" v-model="dataParams.amount" style="margin-top: 10px"></x-input>
  <box gap="10px 10px">
   <flexbox>
    <flexbox-item>
     <x-button type="default" @click.native="replace()">确认</x-button>
    </flexbox-item>
    <flexbox-item>
     <x-button type="default" @click.native="bck()">返回(回传参数)</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. 回显上一个页面录入的手机号
   list: [
    {
     label: '手机号',
     value: ''
    }
   ],
   // 2. 自定义需要传递到下一个页面的参数
   dataParams: {
    phoneNumb: '',
    amount: '50元'
   }
  }
 },
 methods: {
  /**
   * 4.提交表单方式1
   * 如果需要下一个页面点击返回,任然要回显当前页面,就调用该方法
   * /
  next() {
   this.$vp.psPageNext('/Demo/PageStack/Page4', { params: this.dataParams })
  },
  /**
   * 4.提交表单方式2
   * 一般确认页面都无需被“保留”,故这里使用`this.$vp.psPageReplace`接口完成跳转,底层将会使用
   * `router.replace({location})`完成跳转
   */
  replace() {
   this.$vp.psPageReplace('/Demo/PageStack/Page4', {params: this.dataParams})
  },
  bck() {
   this.$vp.psPageGoBack({
    // 3.设置回传参数
    backParams: {
     phoneNumb: '13222222222'
    }
   })
  }
 },
 created() {
  this.list[0].value = this.params.phoneNumb
  this.dataParams.phoneNumb = this.params.phoneNumb
 }
}
</script>

表单结果页面(简称: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 () => {
       // 返回栈顶页面
       that.$vp.psPageGoBack()
      }
     })(this)
    }, {
     type: 'default',
     text: '完成',
     onClick: ((that) => {
      return () => {
       // 返回指定页面,并清空参数栈
       // 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个页面都集成了 paramsStack mixin ,定义如下:

/**
 * 参数栈mixin对象
 * <p>
 *  方便页面组件继承之后操作参数栈
 * @type {Object}
 */
export const paramsStackMixin = {
 data() {
  return {
   /**
    * 声明该页面是栈底部
    */
   isStackBottom: false
  }
 },
 computed: {
  ...mapGetters([
   /**
    * 查看`vuex#vplus.paramsStack[top-length]`栈顶参数
    */
   'params'
  ]),
  /**
   * 查看`vuex#vplus.backParams`回传参数
   */
  backParams() {
   return this.$store.state[MODULE_NAME].backParams
  },
  /**
   * 查看`vuex#vplus.backState`是否是出栈|是否是返回状态
   */
  backState() {
   return this.$store.state[MODULE_NAME].backState
  }
 },
 methods: {
  ...mapMutations([
   /**
    * 入栈
    */
   'pushParams',
   /**
    * 修改栈顶参数
    */
   'modifyParams',
   /**
    * 出栈
    */
   'popParams',
   /**
    * 清空参数栈
    */
   'clearParamsStack',
   /**
    * 设置是否是出栈|是否是返回状态(点击返回页面)
    */
   'setBackState'
  ])
 },
 // 导航离开该组件的对应路由时调用
 beforeRouteLeave(to, from, next) {
  if (this.backState && this.isStackBottom) {
   this.clearParamsStack()
  }
  next()
 }
}

配置

没有个性化配置,可以查看全局通用配置

API接口

restoreParamsStack

/**
  * $vp.restoreParamsStack()
  * 恢复插件中`vuex#$vp.paramsStack` && vuex#$vp.backParams` && vuex#$vp.backState`参数栈所用状态
  * <p>
  * 在当前模块重新安装的时候,一般对应就是插件初始化和页面刷新的时候
  */
 restoreParamsStack()

psModifyBackState

/**
  * $vp.psModifyBackState(bckState)
  * <p>
  * 设置`vuex#vplus.backState`返回状态
  * @param {Boolean} [backState=false]
  */
 psModifyBackState(bckState)

psClearParamsStack

/**
  * $vp.psClearParamsStack()
  * <p>
  * 清空参数栈
  */
 psClearParamsStack()

psPageNext

/**
  * $vp.(location[, {params = {}, clearParamsStack = false, backState = false} = {}])
  * <p>
  * 页面导航
  * @param location router location对象
  * @param {Object} [params={}] 向下一个页面需要传递的参数
  * @param {Boolean} [clearParamsStack=false] 在进行页面导航的时候,是否清空参数栈,默认为false
  * @param {Boolean} [backState=false] 设置`vuex#vplus.backState`返回状态,默认为false
  */
 psPageNext(location, {params = {}, clearParamsStack = false, backState = false} = {})

psPageReplace

/**
  * $vp.(location[, {params = {}, isPop = true} = {}])
  * <p>
  * 页面导航(基于Router),移除上一个页面
  * <p>
  *  将会出栈顶对象,并重新设置`params`为参数栈的栈顶参数
  *  注:在调用该方法的页面,必须是要调用`ParamsStack#psPageNext`导航的页面,因为需要保证“弹栈”操作无误,
  *  又或者设置`isPop`为false
  * @param location router location对象
  * @param {Object} [params={}] 向下一个页面需要传递的参数
  * @param {Boolean} [isPop=false] 是否pop当前页面的参数后在进行页面跳转,默认为true,防止当前页面
  * 不是通过`ParamsStack#psPageNext`导航过来的,但是由需要使用当前方法
  */
 psPageReplace(location, {params = {}, isPop = true} = {})

psPageGoBack

/**
  * $vp.psPageGoBack({backParams = {}, clearParamsStack = false, backPopPageNumbs = -1} = {})
  * <p>
  * 页面回退
  * @param {Object} backParams 设置回传参数
  * @param {Boolean} clearParamsStack 是否清空参数栈
  * @param {Number} backPopPageNumbs 出栈页面数
  */
 psPageGoBack({backParams = {}, clearParamsStack = false, backPopPageNumbs = -1} = {})
(0)

相关推荐

  • vue单页应用在页面刷新时保留状态数据的方法

    在Vue单页应用中,如果在某一个具体路由的具体页面下点击刷新,那么刷新后,页面的状态信息可能就会丢失掉.这时候应该怎么处理呢?如果你也有这个疑惑,这篇文章或许能够帮助到你 一.问题 现在产品上有个需求:单页应用走到某个具体的页面,然后点击刷新后,刷新的页面要与刷新前的页面要保持一致. 这时候就需要我们保存刷新之前页面的状态. 二.一种解决方案 在这个Vue单页应用中,王二是用Vuex作为状态管理的,一开始王二的思路是将Vuex里的数据同步更新到localStorage里. 即:一改变vuex里的

  • Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信

    最近在学习vue组件鸡组件之前通信问题,正好看到,以此来留作笔记. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Vue2-单一事件管理组件通信</title> <script src="vue.js"></script> <script type=

  • Vue 页面状态保持页面间数据传输的一种方法(推荐)

    如果大家觉得有用,更多的模块请 点击查看 vue router给我们提供了两种页面间传递参数的方式: 动态路由匹配 编程式的导航 // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }}) 下面介绍一下 vue-viewplus 一个简化Vu

  • 将html页面保存成图片,图片写入pdf的实现方法(推荐)

    需求是一个导出pdf的功能,多方奔走终于实现了,走了不少弯路,而且怀疑现在这个方法仍是弯的. 有个jsPDF 插件可以在前端直接生成pdf,很简便,但不支持IE. 前端: 首先引入  html2canvas.js html2canvas(document.body, { //截图对象 //此处可配置详细参数 onrendered: function(canvas) { //渲染完成回调canvas canvas.id = "mycanvas"; // 生成base64图片数据 var

  • jQuery页面加载初始化的3种方法(推荐)

    jQuery 页面加载初始化的方法有3种 ,页面在加载的时候都会执行脚本,应该没什么区别,主要看习惯吧,本人觉得第二种方法最好,比较简洁. 第一种: $(document).ready(function(){ alert("第一种方法."); }); 第二种: $(function(){ alert("第二种方法."); });  第三种: jQuery(function($) { alert("第三种方法."); }); ps; 不用jQuer

  • js实现页面跳转的五种方法推荐

    js实现页面跳转的五种方法推荐 第一种: 复制代码 代码如下: <script language="javascript" type="text/javascript"> window.location.href="xx.jsp?backurl="+window.location.href; </script> 第二种: 复制代码 代码如下: <script language="javascript&quo

  • springMVC使用jsp:include嵌入页面的两种方法(推荐)

    1.静态嵌入子页面 <%@ include file="header.jsp" %> 静态嵌入支持 jsp . html . xml 以及纯文本. 静态嵌入在编译时完成,相当于直接将子页面的文本插入到 include 标签所在的位置.子页面可直接使用父页面中的变量. 2.动态嵌入子页面 使用 jsp:include 时必须设置 flush 属性为 true . <jsp:include page="/main/header.jsp" flush=&

  • React组件间通信的三种方法(简单易用)

    目录 一.父子组件通信 二.跨级组件通信 1.逐层传值 2.跨级传值 三.兄弟(无嵌套)组件通信 四.路由传值 五.Redux React知识中一个主要内容便是组件之间的通信,以下列举几种常用的组件通信方式,结合实例,通俗易懂,建议收藏. 一.父子组件通信 原理:父组件通过props(与vue中的props区分开)向子组件通信,子组件通过回调事件与父组件通信. 首先,先创建一个父组件Parent.js跟子组件Children.js,二者的关系为直接父子关系. Parent.js父组件如下,给父组

  • vue项目退出登录清除store数据的三种方法

    目录 方法一:(不友好,页面会白屏,不推荐使用) 方法二 : (不会出现白屏,推荐使用) 方法三 : vuex清除token (不会出现白屏,推荐使用) 总结 方法一:(不友好,页面会白屏,不推荐使用) 在退出登录的loginOut 方法里面: window.location.reload() 方法二 : (不会出现白屏,推荐使用) 利用v-if控制router-view,在根组件APP.vue中实现一个刷新方法 <template> <router-view v-if="is

  • Vue父子模版传值及组件传值的三种方法

    这里是针对于vue1.0,如果要学2.0,建议大家去看官方文档 vue2.0 http://vuefe.cn/guide/ vue-router2.0https://router.vuejs.org/zh-cn/essentials/getting-started.html 第一种 <div id="example"> <my-component></my-component> </div> <script src="..

  • Vue 实时监听窗口变化 windowresize的两种方法

    下面给大家分享两种方法来介绍Vue 实时监听窗口变化 windowresize,具体内容如下所示: 方法一: First-step : 定义变量 data(){ return{ formLabelWidth : '123px' } }, Second-step:   根据生命周期 在mounted 中绑定 窗口变化 mounted(){ const that = this window.onresize = () => { return (() => { window.screenWidth

  • Vue 实现列表动态添加和删除的两种方法小结

    下面将介绍两种方式实现动态添加和删除列表 1.不使用组件 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - vue实现列表增加和删除</title> <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script&g

随机推荐