Vue 路由組件傳參的 8 種方式

我們在開發單頁面應用時,有時需要進入某個路由後基於參數從服務器獲取數據,那麼我們首先要獲取路由傳遞過來的參數,從而完成服務器請求,所以,我們需要了解路由傳參的幾種方式,以下方式同 vue-router@4

編程式路由傳參

除了使用 <router-link> 創建 a 標籤來定義導航鏈接,我們還可以藉助 router 的實例方法,通過編寫代碼來實現。

1. 通過 params 傳遞

路由配置

路徑參數 用冒號 : 表示。

const routes = [
  // 動態段以冒號開始
  { path: 'details/:id', name: "details", component: Details },
]

router.push() 方法的參數可以是一個字符串路徑,或者一個描述地址的對象。

const Home = {
  template: '<div @click="toDetails">To Details</div>',
  metheds: {
    toDetails() {
      // 字符串路徑
      this.$router.push('/details/001')
      // 帶有路徑的對象
      this.$router.push({path: '/details/001'})
      // 命名路由,路由配置時,需要 name 字段
      this.$router.push({ name: 'details', params: { id: '001' } })
    }
  }
}

注意,如果提供了 pathparams 會被忽略:

// `params` 不能與 `path` 一起使用
router.push({ path: '/details', params: { id: '001' } }) // -> /details

組件獲取數據

當一個路由被匹配時,它的 params 的值將在每個組件中以 this.$route.params 的形式暴露出來。

const Details = {
  template: '<div>Details {{ $route.params.id }} </div>',
  created() {
    // 監聽路由變化
    this.$watch(
      () => this.$route.params,
      (toParams, previousParams) ={
        // 對路由變化做出響應...
      }
    )
  },
}

2. 通過 query 傳遞

這種情況下 query (查詢參數)傳遞的參數會顯示在 url 後面,如:/details/001?kind=car

路由配置

使用 query 時,以下三種方式都是可行的:

this.$router.push('/details/001?kind=car')
this.$router.push({ path: '/details/001', query: { kind: "car" }})
this.$router.push({ name: 'details', params: { id: '001' }, query: { kind: 'car' }})

組件獲取數據

組件通過 $route.query 獲取:

const Details = {
  template: '<div>Details {{ $route.query.kind }} </div>',
  created() {
    // 監聽路由變化
    this.$watch(
      () => this.$route.query,
      (toParams, previousParams) ={
        // 對路由變化做出響應...
      }
    )
  },
}

要對同一個組件中參數的變化做出響應的話,你可以簡單地 watch $route 對象上的任意屬性,在這個場景中,就是 $route.query 。

3. 通過 hash 傳遞

通過此方式,url 路徑中帶有 hash,例如:/details/001#car

路由配置

使用 hash 時,以下三種方式都是可行的(同 query):

this.$router.push('/details/001#car')
this.$router.push({ path: '/details/001', hash: '#car'})
this.$router.push({ name: 'details', params: { id: '001' }, hash: 'car'})

組件獲取數據

組件通過 $route.hash.slice(1) 獲取:

const Details = {
  template: '<div>Details {{ $route.hash.slice(1) }} </div>',
}

通過 props 進行傳遞

在組件中使用 $route 會與路由緊密耦合,這限制了組件的靈活性,因爲它只能用於特定的 URL。雖然這不一定是件壞事,但我們可以通過 props 配置來解除這種行爲。

以解耦的方式使用 props 進行參數傳遞,主要是在路由配置中進行操作。

1. 布爾模式

當 props 設置爲 true 時,route.params 將被設置爲組件的 props。

例如下面的代碼是通過 $route 的方式獲取動態字段 id

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}
const routes = [{ path: '/user/:id', component: User }]

將上面的代碼替換成 props 的形式,如下:

const User = {
  props: ['id'], // 組件中通過 props 獲取 id
  template: '<div>User {{ id }}</div>'
}
// 路由配置中,增加 props 字段,並將值 設置爲 true
const routes = [{ path: '/user/:id', component: User, props: true }]

注意:對於有命名視圖的路由,你必須爲每個命名視圖定義 props 配置:

const routes = [
  {
    path: '/user/:id',
    components: { default: User, sidebar: Sidebar },
    // 爲 User 提供 props
    props: { default: true, sidebar: false }
  }
]

2. 對象模式

當 props 是一個對象時,它將原樣設置爲組件 props。當 props 是靜態的時候很有用。

路由配置

const routes = [
  {
    path: '/hello',
    component: Hello,
    props: { name: 'World' }
  }
]

組件中獲取數據

const Hello = {
  props: {
    name: {
      type: String,
      default: 'Vue'
    }
  },
  template: '<div> Hello {{ name }}</div>'
}

<Hello /> 組件默認顯示 Hello Vue,但路由配置了 props 對象,當路由跳轉到 /hello 時,會顯示傳遞過來的 name, 頁面會顯示爲 Hello World。

3. 函數模式

可以創建一個返回 props 的函數。這允許你將參數轉換爲其他類型,將靜態值與基於路由的值相結合等等。

路由配置

使用函數模式時,返回 props 的函數接受的參數爲路由記錄 route

// 創建一個返回 props 的函數
const dynamicPropsFn = (route) ={
  return { name: route.query.say + "!" }
}
const routes = [
  {
    path: '/hello',
    component: Hello,
    props: dynamicPropsFn
  }
]

組件獲取數據

當 URL 爲 /hello?say=World 時, 將傳遞 {name: 'World!'} 作爲 props 傳給 Hello 組件。

const Hello = {
  props: {
    name: {
      type: String,
      default: 'Vue'
    }
  },
  template: '<div> Hello {{ name }}</div>'
}

此時頁面將渲染:

注意:請儘可能保持 props 函數爲無狀態的,因爲它只會在路由發生變化時起作用。如果你需要狀態來定義 props,請使用包裝組件,這樣 vue 纔可以對狀態變化做出反應。

其他方式

1. 通過 Vuex 進行傳遞

    1. store 存儲狀態;
    2. A 組件更改 store 中的狀態;
    3. B 組件從 store 中獲取。

2. 通過前端本地存儲等方式

    1. Local Storage;
    2. Session Storage;
    3. IndexedDB;
    4. Web SQL;
    5. Cookies。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/LazX7doIiVSpSneGdFEq1w