Vue 路由

来源:https://www.cnblogs.com/chy18883701161/archive/2020/04/02/12621141.html
-Advertisement-
Play Games

在單頁應用中常常要用到路由。 傳統的頁面跳轉是瀏覽器請求新的頁面,渲染整個新的頁面。 單頁應用是把要跳轉的頁面的以組件的形式集成在當前頁面中,跳轉時瀏覽器不用發起新請求,因為目標頁面是當前頁面的一部分,直接顯示目標頁面那一部分即可。 demo 在單頁應用中使用路由 1、下載路由插件 npm inst ...


 

在單頁應用中常常要用到路由。

傳統的頁面跳轉是瀏覽器請求新的頁面,渲染整個新的頁面。

單頁應用是把要跳轉的頁面的以組件的形式集成在當前頁面中,跳轉時瀏覽器不用發起新請求,因為目標頁面是當前頁面的一部分,直接顯示目標頁面那一部分即可。

 

 

demo  在單頁應用中使用路由

1、下載路由插件

npm install vue-router -S

install可以簡寫為i

我們要使用的是裡面的vue-router.js文件

 

 

2、寫一個test.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <!-- 引入vue.js -->
        <script src="js/vue.js"></script> 
        <!-- 引入路由插件。上線時均要換為xxx.min.js -->
        <script src="js/vue-router.js"></script>
    </head>
    <body>
        
    <div id="app"></div>
    
    <script>
        // 首頁組件
        var Index={
            template:`
                <div>
                    <p>this is the index page</p>
                    <p><a href="#/login">login</a></p>  <!-- 註意url寫法,#/開頭 -->
                    <p><a href="#/register">register</a></p>
                </div>
            `
        }
        
        // 登錄組件
        var Login={
            template:`
                <div>
                    <p>this is the login page</p>
                    <p><a href="#/index">index</a></p>
                    <p><a href="#/register">register</a></p>
                </div>
            `
        }
        
        // 註冊組件
        var Register={
            template:`
                <div>
                    <p>this is the register page</p>
                    <p><a href="#/index">index</a></p>
                    <p><a href="#/register">register</a></p>
                </div>
            `
        }
            
        // 安裝路由插件
        Vue.use(VueRouter);
        
        // 創建路由對象
        var router=new VueRouter({
            // 配置路由規則
            routes:[  //對象數組
                {path:'/index',name:'index',component:Index}, //path指定映射地址,註意沒有#,component指定對應的組件
                {path:'/login',name:'login',component:Login},
                {path:'/register',name:'register',component:Register},
            ]
        });
        
        new Vue({
            el:'#app',
            router,  //啟用路由。原本是router:router,可以簡寫
            template:`
                <div>
                    <!--路由頁面只是當前頁面的一部分,當前頁面可以寫一些其他內容,寫的內容是所有路由頁面-->
                    <p>this is common area</p>
                    <router-view></router-view>  <!--引入路由頁面。路由到哪個頁面,就用對應的組件替換這部分-->
                </div>
            `
        })
    </script>        
        
    </body>
</html>

 

 

3、運行

假設test.html的地址是:http://127.0.0.1:8848/vue/test.html#/      註意後面有個#

則index的地址是:http://127.0.0.1:8848/vue/test.html#/index

login的地址是:http://127.0.0.1:8848/vue/test.html#/login

register的地址是:http://127.0.0.1:8848/vue/test.html#/register

 

3個頁面,但實際上路由的3個頁面都在test.html中。

<router-view></router-view>是一個路由容器,用來容納路由頁面。

 

 

 

 

單頁應用的兩種路由模式

  • 哈希模式(利用hashchange 事件監聽 url的hash 的改變)
  • history模式(需要後臺配合把介面都打到我們打包後的.html文件上,比如上用test.html打包路由頁面,test.html相當於一個容器)

demo中使用的是哈希模式

 

 

 

哈希模式實現路由跳轉的原理

    // 監聽地址欄url的改變,haschange是預定義事件
    window.addEventListener("hashchange",function(e){  //haschange事件發生時,會封裝事件以參數的形式傳給處理函數
        console.log(e);  //這個對象的部分信息: {..., oldURL: "http://127.0.0.1:8848/vue/test.html#/index", newURL: "http://127.0.0.1:8848/vue/test.html#/register", type: "hashchange", …}
        console.log(location.hash); //地址欄的url已改變,獲取新的url的hash。帶有#/,比如#/index,#/login
        // console.log(location); //location是不帶#/的,比如index、login
        
        switch(location.hash){  //根據路由配置決定和哪些常量比較。這些常量就是路由配置中的path
            case '#/index':
                //...   //如果匹配就用對應的組件替換<router-view></router-view>部分
                break;
            case '#/login':
                break;
            case '#/register':
                break;
        }
    })

 

 

 

 

路由跳轉的3種方式

  • <a>鏈接
  • <router-link>標簽
  • $router對象
    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <p>
                    <a href="#/index">index</a>  <!-- 要帶# -->
                    <router-link to="/login">login</router-link>  <!-- 不帶# -->
                    <button @click="goRegister">register</button>
                </p>
                <router-view></router-view> 
            </div>
        `,
        methods:{
            goRegister(){
                this.$router.push({path:'/register'});  //不帶#
            }
        }
    })
    

 

<router-link>、$router都是路由插件里的東西,都用路由了,那url中指定有#號,它自己會加#號,所以我們寫路徑的時候不加#號。

<a>是html的標簽,不知道url中有沒有#號,所以需要我們自己加上。

 

 

$router的常用方法

  • push()  跳轉到指定的頁面,會往history中插入一條新紀錄
  • replace()   和push()的用法、作用相同,只是replace()不會往history中插入一條新紀錄
  • go(-1)   跳轉到history中的上一條記錄,相當於點擊瀏覽器的後退箭頭。
  • forward(1)  跳轉到history中的下一條記錄,相當於點擊瀏覽器的前進箭頭。

 

$router還有個兄弟$route,和$router不同,$route封裝了路由信息,只有屬性(可以理解為是只讀的),常用的屬性比如hash、path、query、params。

 

 

 

 

路由的傳參和取參

1、<a>鏈接方式

    // 首頁組件
    var Index={
        template:`
            <div>
                <p>this is the index page</p>
                <p>{{this.$route.query.username}}  {{this.$route.query.username}}</p>  <!-- 如果只在載入此組件時使用,直接取就行了 -->
                <p>{{username}} {{password}}</p>  <!-- 如果後續還要使用,需要保存到記憶體變數中 -->
            </div>
        `,
        data(){
            return{
                username:'',
                password:''
            }
        },
        created(){  //路由到此組件|頁面時,會新建此組件的實例,在created()中獲取傳來的數據
            this.username=this.$route.query.username;  //$route,沒有r,a鏈接只能用query來取
            this.password=this.$route.query.password;
        }
    }
        
    // 安裝路由插件
    Vue.use(VueRouter);
    
    // 創建路由對象
    var router=new VueRouter({
        // 配置路由規則
        routes:[ 
            {path:'/index',name:'index',component:Index}, 
        ]
    });
    
    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <a href="#/index?username=chy&password=abcd">index</a>  <!-- 傳遞參數 -->
                <router-view></router-view> 
            </div>
        `
    })

參數以查詢字元串的形式拼接在url中:http://127.0.0.1:8848/vue/test.html#/index?username=chy&password=abcd

 

 

 

2、<router-link>方式有2種

(1)query

   <!-- to前面有冒號,我這裡使用的是路由配置里的name。query -->
   <router-link :to="{name:'index',query:{username:'chy',password:'abcd'}}">index</router-link>  

查詢字元串的形式拼接參數,獲取時也是$route.query的方式,url中會帶有參數:http://127.0.0.1:8848/vue/test.html#/index?username=chy&password=abcd

 

 

(2)params

<!--params,post方式-->
<router-link :to="{name:'index',params:{username:'chy',password:'abcd'}}">index</router-link> 

要用$route.params來接收,用什麼傳遞就用什麼接收。

url中不顯示參數,更安全:http://127.0.0.1:8848/vue/test.html#/index

 

params方式的路由配置還可以這樣寫:

    // 創建路由對象
    var router=new VueRouter({
        // 配置路由規則
        routes:[ 
            {path:'/index/:username',name:'index',component:Index},
        ]
    });

:參數名  可以獲取對應的參數值,http://127.0.0.1:8848/vue/test.html#/index/chy,url是RESTful風格

 

 

 

3、$router對象方式

    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <button @click="goIndex">index</button>
                <router-view></router-view> 
            </div>
        `,
        methods:{
            goIndex(){
                this.$router.push({name:'index',query:{username:'chy',password:'abcd'}});
            }
        }
    })

 

 

說明

<router-link>、$router對象方式,都可以使用query或params來傳遞參數,都可以使用path或name來指定路由頁面,

如果路由配置的path是:  {path:'/index/:username',name:'index',component:Index}   這種隨參數的變化而變化的,那就使用name。

 

 

 

 

 

路由傳參參數不刷新的問題

現象

  <router-link :to="{name:'index',params:{username:'chy1',password:'abcd1'}}">index</router-link>  
  <router-link :to="{name:'index',params:{username:'chy2',password:'abcd2'}}">index</router-link>  

比如第一次路由到index頁面,攜帶的參數是{username:'chy1',password:'abcd1'},

後續再路由到此頁面時,比如要攜帶的參數是{username:'chy2',password:'abcd2'},新的參數傳過去了,但使用的參數是第一次路由到此頁面時攜帶的參數。

即傳到同一路由頁面的參數不會刷新,3種方式都存在這個問題。

 

 

原因

Vue路由會復用組件,我把變數賦值寫在created()中,這個鉤子函數只在組件創建時執行,就是說變數賦值只執行1次(第一次路由到此頁面時)。

後續再次路由到此頁面時,新的參數是傳過去了,但變數賦值不會再執行,新的參數也就沒有賦給變數。

如果只在傳過去的時候使用參數,後面不再使用參數,可以  {{this.$route.query|params.參數名}}  直接取。

如果要把參數賦給變數,方便後續使用,該怎麼做?

 

 

 

2種解決方案

1、使用  :key 唯一標識一次路由

    // 創建路由對象
    var router=new VueRouter({
        // 配置路由規則
        routes:[ 
            {path:'/index',name:'index',component:Index},
        ]
    });
        
    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <router-link :to="{name:'index',query:{username:'chy1',password:'abcd1'}}">index</router-link>  
                <router-link :to="{name:'index',query:{username:'chy2',password:'abcd2'}}">index</router-link>  
                <router-view :key="$route.fullPath"></router-view> 
            </div>
        `,

    })

query方式(<a>鏈接也是query方式),路由配置的寫為/index的形式

因為根據url的hash來判斷是否是同一個路由頁面,預設的:key是/index這種形式,會認為是同一個路由頁面;

現在設置:key="$route.fullPath"(註意P是大寫),以完整的url來判斷,query方式會在url中拼接參數,能區分不同的參數傳遞。

 

 

  // 創建路由對象
    var router=new VueRouter({
        // 配置路由規則
        routes:[ 
            {path:'/index/:username',name:'index',component:Index},
        ]
    });
        
    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <router-link :to="{name:'index',params:{username:'chy1',password:'abcd1'}}">index</router-link>  
                <router-link :to="{name:'index',params:{username:'chy2',password:'abcd2'}}">index</router-link>  
                <router-view :key="$route.fullPath"></router-view> 
            </div>
        `,

    })

params方式,因為使用post傳遞參數,url中不帶參數,url(的hash)都是一樣的,怎麼區別?

路由配置的 path:'/index/:username' 中帶上唯一的參數標識,比如username、uid等,這樣url就不同了

 

 

說明

(1)此種方式,:key能唯一標識一次參數傳遞即可,不一定要是$route.fullPath,比如可以是:

:key="$route.fullPath"   //完整的url
:key="$route.query|params.username|uid"  //能唯一標識一次參數傳遞的參數  
:key="new Date().getTime()"  //時間戳(這個是毫秒級的)。使用時間戳時,就算2次路由的參數完全相同,也會重新創建路由頁面的組件

 

(2)此種方式,只要:key的值不同,就會重新創建路由頁面的組件,性能影響大,不太推薦。

 

 

 

2、數據監聽

    // 首頁組件
    var Index={
        template:`
            <div>
                <p>this is the index page</p>
                <p>{{username}}  {{password}}</p>

            </div>
        `,
        data(){
            return{
                username:'',
                password:'',
            }
        },
        // created(){  //可以不要created()
        //     this.username=this.$route.params.username;
        //     this.password=this.$route.params.password;
        // },
        watch:{  //監聽$route.query|params,當然直接監聽$route也行
            '$route.params'(){ //因為有.號,所以要要引起來,不然識別不了
                this.username=this.$route.params.username;  //參數變化時就重新獲取參數
                this.password=this.$route.params.password;
            }
        },    
    }
            
        
    // 安裝路由插件
    Vue.use(VueRouter);
        
    // 創建路由對象
    var router=new VueRouter({
        // 配置路由規則
        routes:[ 
            {path:'/index/:username',name:'index',component:Index},  //query方式寫成/inedx,params方式寫成/index/:username
        ]
    });
        
    new Vue({
        el:'#app',
        router,
        template:`
            <div>
                <router-link :to="{name:'index',params:{username:'chy1',password:'abcd1'}}">index</router-link>  
                <router-link :to="{name:'index',params:{username:'chy2',password:'abcd2'}}">index</router-link>  
                <router-view></router-view>  <!--不需要使用:key-->
            </div>
        `,
    })

這種方式,路由到同一個頁面時,會復用組件,不重新創建組件,開銷小,推薦。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 導讀 現代大部分的登錄系統都支持郵箱、手機號碼登錄兩種方式,那麼如何在郵箱或者手機號碼這個字元串上建立索引才能保證性能最佳呢? 今天這篇文章就來探討一下在Mysql中如何給一個字元串加索引才能達到性能最佳。 本文首發於作者的微信公眾號【碼猿技術專欄】,原創不易,喜歡的朋友支持一下,謝謝!!! 陳某將 ...
  • 2020/4/2 Mongodb使用的是類似與json字元串的形式存儲數據 [ { key:value }, { key:value }, ] Mongodb使用了不存在的對象,即創建該對象 use db 使用db資料庫 show dbs 查看當前伺服器中寫在磁碟上的資料庫 show tables ...
  • [20200401]優化的困惑5.txt--//春節前對一個生產系統做優化,完成後使用ash_wait_chains.sql檢查,發現control file parallel write有點多。--//當時並沒有在意,總感覺哪裡不對,感覺這套系統磁碟IO有問題,現在有空分析看看。1.環境:> @ ...
  • 動畫運行的原理 任何程式的動畫原理都是一樣的,即:視覺暫留,視覺暫留又叫視覺暫停,人眼在觀察景物時,光信號傳入大腦神經,需經過一段短暫的時間,光的作用結束後,視覺形象並不立即消失,這種殘留的視覺稱“後像”,視覺的這一現象則被稱為“視覺暫留”。 電影就是依靠視覺暫留,在感官上電影是連續的。使動畫有流暢 ...
  • 轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。 原文出處:https://dzone.com/articles/cross-platform-mobile-development-2020-trends-and 多年來,跨平臺移動開發已經獲得了最流行軟體開 ...
  • 一、註釋​ 1.JavaScript中的註釋 (1)單行註釋 //我是單行註釋 (2)多行註釋 /*我是多行註釋*/ /** *我是多行註釋 */ (3)註釋文化 2.常見的 (1)彈窗 例如:window.alert(""); (2)控制台輸出 例如:console.log("優秀"); cons ...
  • 同源策略 瀏覽器中有兩個安全機制,一個瀏覽器沙盒(Sandbox),另一個就是同源策略(Same Origin Policy,簡稱SOP) ,下麵介紹同源策略。同源是指 、`同功能變數名稱 同埠`,必須三同,缺一不可。下麵列舉了一些例子,為方便讀者瞭解哪些是屬於同源,下麵列舉一些案例: 根據這個策略,a. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...