vue 系列 — vue-router 传参

前言

有个项目需求:从 A 页面携带参数跳转到 B 页面

在网上查了一下,总共有两种方式:params 方式 和 query 方式

其中涉及到 this.$routerthis.$route 两者,所以我们先要了解一下它们的区别,还要注意在编程中要注意区分开:

this.$routerthis.$route 的区别

在控制台打印两者可以很明显的看出两者的一些区别:

  • $routerVueRouter 实例,想要导航到不同 URL,则使用 $router.push 方法
  • $route当前 router 跳转对象,里面可以获取 name、path、query、params 等

法一:params 方式传参

A 页面传参:

this.$router.push({
    name: 'xxx',
    params: {
      id: id
    }
})
复制代码

B 页面接参:

this.$route.params.id
复制代码

法二:query 方式传参

A 页面传参:

this.$router.push({
    path: '/xxx',
    query: {
      id: id
    }
})
复制代码

B 页面接参:

this.$route.query.id
复制代码

params 和 query 方式的区别

写法上

  • params 方式

name: 'xxx'

因为 params 只能用 name 来引入路由,所以如果这里写成了 path,接收参数页面会是 undefined

  • query 方式

path: '/xxx'

地址栏

  • params 方式

image.png

  • query 方式

image.png

从这里可以看出:

  • query 相当于 get 请求,页面跳转的时候,可以在地址栏看到请求参数
  • params 相当于 post 请求,参数不会再地址栏中显示

刷新

  • params 方式

params方式.gif

  • query 方式

query方式.gif

从这里可以看出:

  • 使用 params 方式跳转的页面刷新后数据被清除了
  • 使用 query 方式跳转的页面刷新后数据还在(URL 也没变化)

导航完成后 和 导航完成前 获取数据

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航

导航完成后获取数据

使用这种方式时,vue.js 会马上导航渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。

假设我们有一个 Post 组件,需要基于 $route.params.id 获取文章数据:

<template>
  <div class="post">
    <div v-if="loading" class="loading">
      Loading...
    </div>

    <div v-if="error" class="error">
      {{ error }}
    </div>

    <div v-if="post" class="content">
      <h2>{{ post.title }}</h2>
      <p>{{ post.body }}</p>
    </div>
  </div>
</template>
复制代码
export default {
  data () {
    return {
      loading: false,
      post: null,
      error: null
    }
  },
  created () {
    // 组件创建完后获取数据,
    // 此时 data 已经被 observed 了
    this.fetchData()
  },
  watch: {
    // 如果路由有变化,会再次执行该方法
    '$route': 'fetchData'
  },
  methods: {
    fetchData () {
      this.error = this.post = null
      this.loading = true
      // replace getPost with your data fetching util / API wrapper
      getPost(this.$route.params.id, (err, post) => {
        this.loading = false
        if (err) {
          this.error = err.toString()
        } else {
          this.post = post
        }
      })
    }
  }
}
复制代码

导航完成前获取数据

通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法

export default {
  data () {
    return {
      post: null,
      error: null
    }
  },
  beforeRouteEnter (to, from, next) {
    getPost(to.params.id, (err, post) => {
      next(vm => vm.setData(err, post))
    })
  },
  // 路由改变前,组件就已经渲染完了
  // 逻辑稍稍不同
  beforeRouteUpdate (to, from, next) {
    this.post = null
    getPost(to.params.id, (err, post) => {
      this.setData(err, post)
      next()
    })
  },
  methods: {
    setData (err, post) {
      if (err) {
        this.error = err.toString()
      } else {
        this.post = post
      }
    }
  }
}
复制代码

参考文章

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享