點燈坊

失くすものさえない今が強くなるチャンスよ

如何對其他 Page 傳遞多值 ?

Sam Xiao's Avatar 2020-08-13

傳統對其他 Page 傳遞資料時,會以 Query String 形式,除了會暴露資料遭 Hacker 嘗試破解外,也不適合傳遞太多資料,若能將這些資料整合成 Object 傳遞,且不必出現在 URL,那就非常完美。

Version

macOS Catalina 10.15.6
WebStorm 2020.2
Vue 2.6.11

Pass Object to Page

object000

Home 切到 About ,同時將 idname 傳遞到 About page,但可發現 url 並沒有帶任何資料,這是怎麼將 idname 傳遞過去呢 ?

Router

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
    props: true
  }
]

const router = new VueRouter({
  routes
})

export default router

13 行

{
  path: '/about',
  name: 'About',
  component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
  props: true
}

若要能以 Object 傳遞到其他 route,則該 route 要另外設定 props: true

Home

App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link :to="{ name: 'About', params: { user: { id, name }}}">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    id: 1,
    name: 'Sam'
  })
}
</script>

第 5 行

<router-link :to="{ name: 'About', params: { user: { id, name }}}">About</router-link>

當要直接在 HTML template 中傳遞 Object 到其他 page 時,要使用 Vue 的 <router-link>,不能使用 HTML 的 <a>,且將含有 nameparams property 的 Object 綁定到 to property。

  • name:要跳轉到的 route 名稱
  • params:要傳遞的 prop 為 user 與其 Object { id, name }

router.push()

App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <a href="#" @click="onClick">About</a>
    </div>
    <router-view/>
  </div>
</template>

<script>
let onClick = function() {
  let { id, name } = this
  this.$router.push({
    name: 'About',
    params: { user: { id, name }}
  })
}

export default {
  name: 'App',
  data: () => ({
    id: 1,
    name: 'Sam'
  }),
  methods: {
    onClick
  }
}
</script>

第 5 行

<a href="#" @click="onClick">About</a>

若想用 HTML 的 <a>,則必須配合其 click event。

12 行

let onClick = function() {
  let { id, name } = this
  this.$router.push({
    name: 'About',
    params: { user: { id, name } }
  })
}

若以 JavaScript 則必須使用 router.push() 將含有 nameparams property 的 Object 傳入。

若使用 path,將自動忽略 params,因此若要傳遞 Object,只能使用 named route

About

About.vue

<template>
  <div>{{ profile }}</div>
</template>

<script>
let mounted = function() {
  if (!this.user) return
  
  let { id, name } = this.user
  this.profile = `${id}: ${name}`
}

export default {
  name: 'About',
  props: ['user'],
  data: () => ({
    profile: ''
  }),
  mounted
}
</script>

15 行

props: ['user'],

接收方必須宣告 user prop。

第 6 行

let mounted = function() {
  if (!this.user) return
  
  let { id, name } = this.user
  this.profile = `${id}: ${name}`
}

mounted event 接收 user prop,使用 if 判斷 this.user 是否有傳遞 user prop,若有可直接將 user prop 解構。

Conclusion

  • 由於其他 page 也是 component,可將多值藏在 Object 內,透過 prop 方式達到傳遞多值的目標