routerlink傳遞參數解釋,在 Vue3中,封裝一個 router-links ,支持內外鏈接都能跳轉
<router-link> 標簽是用于在Vue應用程序的不同頁面之間跳轉,但它不是跳轉到外部鏈接,相反,我們一般使用 <a> 標簽。
也許只(zhi)有我這么認為,但很多(duo)時候(hou),我無法跟上這種差(cha)異(yi)。其他時候(hou),鏈(lian)接(jie)可能是(shi)動態(tai)的,即(ji)來自數據庫或用戶提供的某個(ge)數據源(yuan)。在這種情況下,你根(gen)本不知道鏈(lian)接(jie)是(shi)外部的還是(shi)內部的,在每(mei)個(ge)可能使用鏈(lian)接(jie)的地方手動做一個(ge)v-if是多么痛苦。
如果只用一個(ge)組件來處理所有內部和外部的鏈接,那(nei)不是很(hen)好嗎?
幸運的是,擴(kuo)展(zhan)<router-link>組件非常簡單,只需將它包裝到我們自己的定制組件中。Ok,我們需要構建一個AppLink組件來處理鏈接,無論是外部的還是內部的。
AppLink組件
AppLink組件的 props 要包含 router-link 的所有 props。為什么?因為這樣我們組件的“接口”就可以模仿 Router Link 的接口,無需再記住另一個API。我們可以通過從Vue Router導入 RouterLink 并將其 props 解構到我們的組件中,如下所示:
// AppLink.vue<script>import {RouterLink} from 'vue-router'export default{ props:{ ...RouterLink.props }}</script>
在 template 中,創建 router-link 并將 props 傳遞給它,我們還需要傳入slot ,這個可以在 router-link 插入內容。
// AppLink.vue<template> <router-link v-bind="$props"><slot /></router-link></template>
到(dao)目(mu)前為止,我(wo)們已經處理了所有內(nei)部鏈(lian)接(jie),那外部鏈(lian)接(jie)呢(ni)?如前所述,外部鏈(lian)接(jie)使用a標簽,因此我們將其添加到template中。像 router link 一樣,并將傳入的 to 值賦值給 href。
// AppLink.vue<template> <a :href="to"><slot/></a> <router-link v-bind="$props"><slot/></router-link></template>
這樣內部和外部鏈接都有了對應的處理,需要注意的是(shi),以上內容僅適用于 Vue3,因為(wei)它包含多個根元素(su)。
現在,我們需(xu)要一個計算屬性(xing)來告訴(su)AppLink使用哪種鏈接,我們先取名為isExternal。
首先,我們檢查prop的值是否為字符串。這是必需的,因為to屬性可能是一個對象,例如有時傳遞到router-link(即::to="{name:'RouteNameHere'}")。然后,我們將查字符串是否以http字符串開頭。如果這兩個條件都成立,那么就判斷是一個外部鏈接。
// AppLink.vue<script>export default{ //... computed:{ isExternal(){ return typeof this.to === 'string' && this.to.startsWith('http') } }}</script>
有了 isExternal計算屬性之后,我們就可以使用 v-if 來進行操作,如下所示:
// AppLink.vue<template> <a v-if="isExternal" :href="to"><slot/></a> <router-link v-else v-bind="$props"><slot/></router-link></template>
大(da)功(gong)告成(cheng),我們可以這樣來使(shi)用(yong) AppLink 組件。
// Anywhere in your app<AppLink :to="[external-or-internal-link]">Click Me</AppLink>
更高的靈活性
在新窗口中打開
我(wo)們(men)可以多添加(jia)一些(xie)常用的功能(neng)。例如,我(wo)們(men)希望外部鏈接都(dou)在新窗口中打開,這樣很簡(jian)單就(jiu)能(neng)做(zuo)到了,只(zhi)要把 target="_blank" 添加到我們的 a 標簽中即可。
// AppLink.vue<template> <a ... target="_blank"><slot/></a> ...</template>
當(dang)然,有(you)些(xie)外部鏈接不需要在新窗口(kou)中(zhong)打開,我們可以通過指定 target 來告訴組件內部打開鏈接的方式,如下所示:
<AppLink :to="//vueschool.io" target="_self">Vue School</AppLink>
鏈接安全
當我們使用target="_blank"屬性鏈接到另一個站點上的頁面時,最終可能使我們的站點面臨性能和安全性問題:
鏈(lian)接(jie)到的頁面(mian)最終可以在與頁面(mian)相同(tong)的進(jin)程上運行。根據所鏈(lian)接(jie)頁面(mian)的最新情(qing)況,這(zhe)可能會使(shi)您自己的頁面(mian)變慢。
另一個頁面也可以(yi)通過window.opener屬性訪問原始頁面窗口,從而引起安全隱患。
解決此問(wen)題(ti)的方(fang)法(fa)是為所(suo)有(you)外部鏈接標簽添加rel="noopener"屬性,因為我們已經封裝成組件了,所以只需要在組件內部的 a 標簽添加即可。
// AppLink.vue<template> <a ... rel="noopener"><slot/></a> ...</template>
外部鏈接的獨特樣式
我見過一些網站(zhan)(zhan)在(zai)他(ta)們的(de)網站(zhan)(zhan)上(shang)設置的(de)外部鏈接樣式(shi)與(yu)在(zai)他(ta)們自己的(de)網站(zhan)(zhan)上(shang)指向站(zhan)(zhan)內(nei)的(de)鏈接有點(dian)不同。這可以幫助用戶更好(hao)地(di)理解(jie)他(ta)們要跳轉的(de)是外部鏈接。
這個樣式(shi)可以是任(ren)何東西,如,在(zai)第三方鏈接(jie)加個警告(gao)的圖標,告(gao)訴用戶跳轉的風險。在(zai)我們的組件中(zhong)實現這一點非常簡單,只需在(zai)模板中(zhong)的a標簽中添加一個external-link類,然后使用css對其進行不同的樣式化:
// AppLink.vue// (must have font awesome font included in project)<template> <a ... class="external-link"> <slot/> <i class="fas fa-external-link-alt"></i> </a> ...</template><style scoped>.external-link i { font-size: 0.8em; opacity: 0.7;}</style>
這(zhe)里就把(ba) AppLink 思路講(jiang)完了,當然,大家需(xu)要(yao)新的需(xu)求可以自(zi)行擴展。
~完,我(wo)是小(xiao)智,看(kan)海賊王去了,下(xia)期見!
作者:Written by Daniel Kelly 譯者:前(qian)端小(xiao)智 來源:vueschool
//vueschol.io/articles/vuejs-tutorials/extendig-vue-router-links-in-vue-3/