vue(5)—— vue的路由插件—vue-router 常用屬性方法

来源:https://www.cnblogs.com/yangva/archive/2019/03/22/10570774.html
-Advertisement-
Play Games

前端路由 看到這裡可能有朋友有疑惑了,前端也有路由嗎?這些難道不應該是在後端部分操作的嗎?確實是這樣,但是現在前後端分離後,加上現在的前端框架的實用性,為的就是均衡前後端的工作量,所以在前端也有了路由,減輕了伺服器對這方面的判斷,在前端做好路由分發之後,後端就只需要寫API介面了,更著重於數據... ...


前端路由

 

看到這裡可能有朋友有疑惑了,前端也有路由嗎?這些難道不應該是在後端部分操作的嗎?確實是這樣,但是現在前後端分離後,加上現在的前端框架的實用性,為的就是均衡前後端的工作量,所以在前端也有了路由,減輕了伺服器對這方面的判斷,在前端做好路由分發之後,後端就只需要寫API介面了,更著重於數據交互,邏輯上的代碼編寫了

 

單頁面應用

 

那麼,既然有前端路由,每個路由是不是都要單寫一個頁面呢?不需要的,現在都提倡單頁面應用

 

什麼是單頁面應用呢

 

單頁面應用,即 single page application ,簡稱SPA ,所有的路由其實都只在一個頁面上完成,這種就叫單頁面應用,我們不需要每個路由對應一個頁面去編寫

 

為什麼要用單頁面應用

 

1.傳統的根據路由切換頁面,都是立即切換,如果切換的網路資源很多的話,載入需要很久,用戶體驗很不好,並且寫的頁面越多,也越不好管理,可能還會有很多重覆的代碼出現,到後期更新迭代後,頁面越來越多,這樣會產生更多的資源

2.SPA可以完美解決以上的問題,並且數據切換時只是局部切換,且並不會立即切換,而是在某個合適的時間用ajax非同步請求後端的API介面,再載入出數據,這裡的【某個合適的時間】是指:因為用戶查看網頁的時候並不會永遠都在切換頁面吧?所以在某個剛好的時間切換就行了

 

單頁面應用的原理

 

原理就是運用了錨點,即html頁面上的id屬性,因為id用的符號【#】,根據前面的web前端基礎開發,相信你已經可以理解了,比如一個頁面右邊的固定按鈕,返回頂部,比如這裡淘寶的頁面,這個返回頂部的按鈕

 

用的就是【#】,這個就不多介紹了,因為學到vue這裡,前面說過的,你得有錢端的基礎知識才更容易學。在js里【#】其實是hash值,比如這個例子:

 

 

因為js自帶有location對象,在我點擊登錄時,因為用onhashchange監聽了hash改變,所以立馬可以得到新的hash值,然後按邏輯把數據渲染出來

 

代碼:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>

    <style>

    </style>
</head>

<body>
    <a href='#/login'>登錄</a>
    <a href="#/register">註冊</a>
    <div id="app">

    </div>
    <!-- <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> -->
    <script>
        var point = document.getElementById('app');

        window.onhashchange = function () {
            console.log(location);
            switch (location.hash) {
            case '#/login':
                point.innerHTML = '<h2>登錄</h2>'
                break;
            case '#/register':
                point.innerHTML = '<h2>註冊</h2>'
                break;
            default:
                break;
            }
        }
    </script>
</body>

</html>
原生js的路由控制

 

 

總之在單頁面應用里,用【#】的意思是當前頁面根本就沒有跳轉,還是當前的頁面,只是用了一些機制把數據換掉了而已,這個機制就是vue-router,vue-router其實就是用了這個onhash的原理,不過比js原生的多了很多特性和功能

 

 

註:

  • 錨點值即a標簽的跳轉,hash
  • onhashchange獲取url上錨點的改變
  • location.hash指當前的錨點
  • js里也有switch的用法

 

vue-router

 

vue-router插件位置:

 

 官方文檔傳送門:點我

 

vue-router簡介

這裡說下,為什麼要截圖官方的文檔,直接去官方文檔看不就好了嗎對吧,原因是:vue-router更新版本很快,所以文檔也會跟著更新,有些知識點可能有些不一樣。加上也就不用切換到另一個界面看了再回來看了,我截的圖也只是個人覺得需要註意的點

 

 

安裝vue-router

 

安裝之後當前目錄下多了個vue-router文件夾:

 

引入vue-router包

引入本地包 

 

你可以引入你下載的本地的,真正的使用vue-router是和vue配套一起使用的,所以vue也得引入

 

引入cdn包

 

查看控制台如果沒報錯表示引入成功

 

引入cdn包代碼: 

<script type="text/javascript" src='https://unpkg.com/vue-router/dist/vue-router.js'></script>

<!-- 或者引入指定的版本 -->
<script type="text/javascript" src='https://unpkg.com/[email protected]/dist/vue-router.js'></script>

 

使用vue-router 

 

 

 

 

使用步驟:

1.引入vue-router插件
2.讓根元素Vue載入自定義的VueRouter對象(此對象由vue-route插件提供,插件最後會返回一個VueRouter對象和router-linke和router-view組件),方面後面使用
3.創建、配置一個router對象,裡面設定好不同的錨點值對應的路由以及對應好第二步里自定義的VueRoter對象
4.將創建好的router對象掛載到vue實例對象上,直接如上寫即可,如果報錯什麼matched,一定是根元素Vue里沒有寫入router

5.利用vue-router插件提供的兩個全局的組件<router-link>和<router-view>設定好DOM佈局,通過<router-link>組件的to屬性設定好路由路徑,且組件最後會被渲染成a標簽,<router-view>給定一個路由組件的出口,用於讓VueRouter對象進行數據渲染
6.根據不同的路由,渲染整個頁面,最後展示出來

 

註意:

當使用vue-router時,掛載組件只需要再VueRouter對象里掛載就行了,不需要再在vue實例對象里用components屬性掛載了

VueRouter定義路由組件的屬性是routes,不是router,定義的url屬性用path

定義的url路由不用手動寫上【#】,vue-router會自動添加上

 

以上就是vue-router的簡單使用

 

命名路由

vue的路由也可以命名的,是不是感覺越來越像一門後端語言了,哈哈

 

 

註:

使用命名路由,在定義路由組件內部,最好用v-bind綁定,添加一個name屬性,值則為你定義的路由名字,必須是字典形式:{name:'名字'}

 

 

我這裡試了下,不用綁定直接使用也可以,以前的版本不行的,現在的貌似可以,具體還有待研究,我使用的版本:vue2.6.9,vue-router3.0.2

 

代碼

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>

    <style>

    </style>
</head>

<body>
    <div id="app">
    </div>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        Vue.use(VueRouter) // 目前是全局狀態,可有可不有
        var Vlogin = {  template: `<div>登錄</div>` }
        var Vregister = { template: `<div>註冊</div>` }
        const router = new VueRouter({
            routes: [{
                    path: '/login',
                    name:'login',
                    component: Vlogin  },
                {
                    path: '/register',
                    name:'register',
                    component: Vregister
                }]
        })
        var Vcom = {
            template: `<div>
                <router-link :to="{name:'login'}">登錄頁面</router-link>
                <router-link :to="{name:'register'}">註冊頁面</router-link>
                <router-view></router-view></div>`
        }
        let app = new Vue({
            el: '#app',
            components: {  Vcom  },
            router,
            template: `<Vcom />`
        })
    </script>
</body>

</html>
vue-router 命名路由

 

預設路由 

給預設的路由,因為很多時候打開頁面,總要展示一個預設的頁面吧,所以如下:給路由組件添加一個 '/',然後指向一個你覺得可以作為預設頁面的組件就行

 

補充一下,在vue-router3.0.1版本中,還有這種寫法:

 

但是由於我目前的是3.0.2,所有效果沒出來,並且我感覺沒多大用啊,反正都是渲染,直接用官方的就行了,搞些新寫法整那麼花里胡哨幹嘛對吧? 

 

路由重定向

這個跟上面的預設路由很類似,只是用的是redirect屬性:


我這裡訪問頁面會自動跳轉到登錄頁面,這種就是路由重定向

 

代碼:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>

    <style>

    </style>
</head>

<body>
    <div id="app">
    </div>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        Vue.use(VueRouter) // 目前是全局狀態,可有可不有
        var Vlogin = {
            template: `<div>登錄</div>`
        }
        var Vregister = {
            template: `<div>註冊</div>`
        }
        const router = new VueRouter({
            routes: [{
                    path:'/',
                    redirect:'/login'
                },
                {
                    path: '/login',
                    component: Vlogin
                },
                {
                    path: '/register',
                    component: Vregister
                }
            ]
        })
        var Vcom = {
            template: `<div>
                <router-link to="/login">登錄頁面</router-link>
                <router-link to="/register">註冊頁面</router-link>
                <router-view></router-view>
                </div>`
        }
        let app = new Vue({
            el: '#app',
            components: {
                Vcom
            },
            router,
            template: `<Vcom />`
        })
    </script>
</body>

</html>
路由重定向

 

 

帶參數的路由

 

 我們經常需要把某種模式匹配到的所有路由,全都映射到同個組件。例如,我們有一個 User 組件,對於所有 ID 各不相同的用戶,都要使用這個組件來渲染

帶參數是什麼意思,比如就目前我這個博客園後臺編輯頁面:

https://i.cnblogs.com/EditPosts.aspx?postid=10570774

其中,【?】後面的postid=10...就是帶的參數

 

除了這種,還有這種:

其中的p/105...就是參數,當然博客園的到底用的什麼做的url路由就不得而知了,也與本文無關了。

總之就是這種:xxx/user/userid/1,其中的userid/1就是參數

 

總結下就是,有以下兩種參數,表達的意思都是一樣的,是為了找page等於多少的數據

xxx.com/cont?page=2

xxx.com/cont/page/1

 

那麼在實際開發中,肯定會有指定某個參數的訪問,這種其實就是查詢嘛,查詢單個數據,也是非常常見且重要的,來個例子:

 (有些圖片看著字很小或者又顯示不全,你右鍵查看圖片源地址可以看大圖的,這個是博客園主題的關係,顯示不全)

 

註意:

 

  • 用【:】匹配的路由組件,path是這樣:/page/:pid,有【/】分割,在匹配時用的params,就可以匹配  /page/1,/page/2,/page/3等等的,瀏覽器url上顯示的是 /page/1
  • 另一種匹配,路由組件中的path沒做任何改動,直接在匹配時用的query,就可以匹配  /page?pid=1,/page?pid=2,/page?pid=3等等的,瀏覽器url顯示的是  /page?pid=1

 

 

相關具體步驟:

 

1.重新定義了兩個局部組件,其中一個用  /page:pid  ,為什麼這麼寫,這是官方文檔里明確說明瞭的:

 

2.再在router-link里多給了一個參數,params,在另外一個裡添加了query:

 

params和query都是固定的,不能隨意更改,不信你可以改了試試。

 

<router-link :to="{name:'pagep',params:{pid:1}}">第一頁</router-link>   匹配對應前面的  xxx.com/cont/page/1 <router-link :to="{name:'pageq',query:{pid:2}}">第二頁</router-link>     匹配對應前面的 xxx.com/cont?page=2

 

那有沒有想過,它這就給個參數(params/query),為什麼就可以匹配呢?匹配之後可以拿到那個參數嗎?

 

你可以用this.$router和this.$route查看下 ,為什麼是這兩個參數呢?因為讀源碼所得,當引入了vue-router之後,Vue實例化對象就多個兩個惡屬性,一個是$router,一個是$route

 

 

如下,給了一個已創建的生命周期函數,在生命周期里列印了this.$router,發現就是VueRouter對象,裡面有相關的屬性

 

 再列印this.$route看看,發現用【:】 可以匹配url的參數(比如這裡用的 :pid),並且給這個參數加了個鍵,然後匹配到的參數會進入params參數里去,作為一個字典存在:

 

 

為什麼要傳給params呢?你想想,像這樣的匹配,匹配到了之後,需要交給後端處理,那你怎麼拿到這個參數並傳遞給後端呢?沒有變數名字你怎麼傳?是不是需要一個形參啊?所以這裡就有個params屬性,它對應一個字典,字典key就是定義路由組件時path部分,冒號後面的欄位,值就是匹配到的值,比如這裡就是:{pid:'1'}。

並且它還有個參數query,但是此時如上圖,query還是一個空字典。

也就是說這兩個屬性 query和params都是路由組件自帶的屬性,它本來就有的,所以知道為什麼前面說在router-link綁定那裡不能隨意換成其他參數了吧

 

關於這裡,可能你理解起來有點吃力,如果你覺得比較吃力,得多看官方文檔,傳送門   多試幾個例子,我個人感覺它那官方文檔對於這裡都沒說的多清楚

 

由於我是做Python開發的,因為Python的django框架里就有個路由匹配的參數 path('/page:int<pid>',func),其中的pid就可以類比成這裡的pid,所以就很好理解,對這Python不熟悉的請忽略我說的Python這個部分

 

那麼有了用【:】匹配,再看另一個url為/page?pid=2是否能拿到值呢?是否會把參數作為鍵值交給自己自帶的屬性query呢:

 

確實如此:

 

那假如說我把兩個router-link傳進的參數不小心寫錯了,本來是params的寫成query,本來是query寫成了params,看是否可以拿到呢:

拿是可以拿到,但是參數都進錯了歸屬,這種操作太非主流了,可以是可以,但不建議這麼乾

 

代碼:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

    <style>

    </style>
</head>

<body>
        <body>
    <div id="app">

    </div>
    <script>
        Vue.use(VueRouter) // 目前是全局狀態,可有可不有
        var Vpagep = {
            template: `<div>第一頁內容</div>`,
            created() {
                console.log(this.$route)
            },
        }
        var Vpageq = {
            template: `<div>第二頁內容</div>`,
            created() {
                console.log(this.$route)
            },

        }
        const router = new VueRouter({
            routes: [{
                    path: '/page/:pid',
                    name: 'pagep',
                    component: Vpagep
                },
                {
                    path: '/page',
                    name: 'pageq',
                    component: Vpageq
                }
            ]
        })
        var Vcom = {
            template: `<div>
                <router-link :to="{name:'pagep',query:{pid:1}}">第一頁</router-link>
                <router-link :to="{name:'pageq',params:{pid:2}}">第二頁</router-link>
                <router-view></router-view></div>`
        }
        let app = new Vue({
            el: '#app',
            components: {
                Vcom
            },
            router,
            template: `<Vcom />`
        })
    </script>
</body>

</html>
帶參數的路由

 

 

編程式導航

 

編程式導航,聽著那麼高端大氣,到底什麼是編程式導航呢,官方文檔解釋:

 

也就是說,編程式導航就是直接使用router實例的push方法,並且其實前面我們用的router-link組件最終其實也是用的這個push方法,換言之我們也可以直接使用這個push方法,自定義,自己編寫導航,這就是編程式導航

 

官網使用案例:

// 字元串
router.push('home')

// 對象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 帶查詢參數,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

 

更多的就移步自己研究吧:點我

 

說了半天好像還是不夠深刻對吧?還是看例子:

 

 

看懂了吧?說白了就是,利用一個事件,在這個事件里把由router-link組件換成了$router.push(),傳進一個字典,字典和之前用的router-link傳入的一樣即可,這個字典就是name和params(或者是query) 

push這個意思就很明顯了,就是把這些參數推進去

 

代碼:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

    <style>

    </style>
</head>

<body>
        <body>
    <div id="app">

    </div>
    <script>
        Vue.use(VueRouter) // 目前是全局狀態,可有可不有
        var Vpagep = {
            template: `<div>第一頁內容</div>`,
            created() {
                console.log(this.$route)
            },
            
        }
        var Vpageq = {
            template: `<div>第二頁內容</div>`,
            created() {
                console.log(this.$route)
            },

        }
        const router = new VueRouter({
            routes: [{
                    path: '/page/:pid',
                    name: 'pagep',
                    component: Vpagep
                },
                {
                    path: '/page',
                    name: 'pageq',
                    component: Vpageq
                }
            ]
        })
        var Vcom = {
            template: `<div>
                <button @click="firstHander">第一頁</button>
                <button @click="secondHander">第二頁</button>
                <router-view></router-view>
                </div>`,
            methods:{
                firstHander(){
                    this.$router.push( {name:'pagep',params:{'pid':1}} )
                },
                secondHander(){
                    this.$router.push( {name:'pageq',query:{'pid':2}} )
                }
            }
        }
        let app = new Vue({
            el: '#app',
            components: {
                Vcom
            },
            router,
            template: `<Vcom />`
        })
    </script>
</body>

</html>
router-push

 

嵌套路由

  

因為路由組件之下,完全還有可能有細分的子路由組件之類的,這樣就可以把整個頁面切分成很多個模塊,每個模塊做著不同的分工,所以就需要有嵌套路由這個東西,

然後用法和路由組件是一樣的,就不用多說了,直接來個例子說明:

 

先看這個百度首頁,我圈出來的部分:

 

百度首頁和個人中心頁面當做路由的根組件,把我圈出來的部分作為子路由嵌套嵌套到個人中心路由組件里:

 

就是這麼簡單,反正路由組件該有的都得有就行了

代碼:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

    <style>

    </style>
</head>

<body>

    <body>
        <div id="app">
        </div>
        <script>
            Vue.use(VueRouter) // 目前是全局狀態,可有可不有 
            var Myfollow = {
                template: `<div>我的關註</div>`
            }
            var Navigate = {
                template: `<div>導航</div>`
            }
            var Story = {
                template: `<div>小說</div>`
            }
            var Commend = {
                tepmalte: `<div>推薦</div>`
            }
            var Person = {
                template: `<div>個人主頁<br>                    
                    <router-link to="/Person/follow">我的關註</router-link>
                    <router-link to="/Person/navigate">導航</router-link>
                    <router-link to="/Person/story">小說</router-link>
                    <router-link to="/Person/commend">推薦</router-link>
                    <router-view></router-view></div>`
            }
            var Home = {
                tempalte: `<div>百度首頁</div>`
            }
            const router = new VueRouter({
                routes: [{
                        path: '/Person',
                        component: Person,
                        children: [{
                                path: '/Person/follow',
                                component: Myfollow
                            },
                            {
                                path: '/Person/story',
                                component: Story
                            },
                            {
                                path: '/Person/commend',
                                component: Commend
                            },
                            {
                                path: '/Person/navigate',
                                component: Navigate
                            },
                        ]
                    },
                    {
                        path: '/home',
                        component: Home
                    }
                ]
            })
            var Root = {
                template: `<div>
                    <router-link to="/home">百度首頁</router-link>
                    <router-link to="/Person">個人主頁</router-link>
                    <router-view></router-view></div>`
            }
            const app = new Vue({
                el: '#app',
                router,
                components: {
                    Root,
                },
                template: `<Root />`,
            })
        </script>
    </body>

</html>
嵌套路由

 

子路由的path 

 

唯一要註意的是,寫子路由的path時,要嘛帶上完整的路由:

 

要嘛不要帶/,直接給一個路由的相對路徑,vue會自動拼寫成完整路由,其他沒做任何改變,一樣可以顯示:

 

 

動態路由

 

我畫出來的那個【'$route'】這個要註意,後面我們會用到

 

什麼是動態路由呢,我個人覺得官網講的太隨意了, 你看了估計都看不太懂啥意思

那麼動態路由到底是什麼呢?這麼說吧,因為Vue是單頁面應用,那麼就會有很多公用路由組件部分對吧,那麼這些公用組件部分會被多個組件使用,通常的方法就是把公用路由組件掛載成子組件,然後公用的部分顯示,不同的部分做單獨渲染或者說單獨的覆蓋數據就行。

這意思感覺有點像是模板一樣對吧?反正都是那一套模板,把數據放進去就行了,好的,不多說,直接上例子:

 

先看個網站,稀土掘金的,這個也是個開發者社區,然後我標記出來的,1就是根路由,2就是子路由,3就是公用部分(這個是要賬號登錄狀態才有的),不管我點2部分的路由的哪個標簽,3永遠都有的,而且沒有變,切換的永遠是3下麵的數據,並且3下麵的數據的css樣式也是公用部分:

 

好的,簡單的模仿一個:

 (為了在一個頁面顯示,所以排版看著有點怪)

 

看下控制台列印的結果:

 

大概什麼邏輯呢?就是相同部分都用同一個路由組件作為子組件,在父級路由的router-link里傳入對應的標簽參數,在公用路由組件里做下處理,把內容填充上就行,不再需要分別定義多個組件了。

 

這個在實際開發中,可以再公用路由組件里做判斷,如果是哪個子路由,數據就是什麼樣,做好不同的分類顯示就行了,這裡作為案例就沒做那麼詳細真實了

 

好的,至於這個  '$route'(to,form)  其中的'$route'到底是什麼暫且不 談了,詳細的看官網了

 

 

代碼:

 

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

    <style>

    </style>
</head>

<body>

    <body>
        <div id="app"></div>
        <script>
            Vue.use(VueRouter) // 目前是全局狀態,可有可不有                       
            var Pins = {
                template: ` <div>我是沸點</div>`
            }
            var common = { // 公用組件
                data() {
                    return {
                        msg: ''
                    }
                },
                template: `<div>公用部分:發表  - 寫文章 - 分享鏈接 
                    <div>{{msg}}</div></div>`,
                created() {
                    this.msg = '(css樣式結構,還沒有數據)'
                },
                watch: {
                    '$route'(to, form) {
                        console.log(form);
                        console.log(to);
                        this.msg = `${this.$route.params.category} 相關內容內容內容.........`
                    }
                }
            }
            var home = {
                template: `<div>
                    <router-link :to="{name:'common',params:{category:'commend'}}">推薦</router-link>
                    <router-link :to="{name:'common',params:{category:'follow'}}">關註</router-link>
                    <router-link :to="{name:'common',params:{category:'android'}}">安卓</router-link>
                    <router-view></router-view></div>`,
            }
            // 註意路由掛載組件的先後順序,先創建再在路由里掛載
            const router = new VueRouter({
                routes: [{
                        path: '/home',
                        component: home,
                        children: [{
                                path: '/',
                                component: common
                            },
                            {
                                path: '/home/:category',
                                name: 'common',
                                component: common
                            }
                        ]
                    },
                    {
                        path: '/pins',
                        name: 'pins',
                        component: Pins
                    }
                ]
            })
            var com = {
                template: `<div>
                    <router-link to="/home">首頁</router-link>
                    <router-link to="/pins">沸點</router-link>
                    <router-view></router-view></div>`
            }
            const app = new Vue({
                el: '#app',
                components: {
                    com
                },
                router,
                template: `<com/>`
            })
        </script>
    </body>

</html>
動態路由

 

keep-alive的用法

在路由組件中也可以用keep-alive,主要用途是對切換頁面時組件的緩存,防止銷毀創建增大開銷

這個在前面的局部組件也有用到的,不多說。用法就是在組件的出口前後加一個vue特殊的組件<keep-alive>包裹住即可

 

其他沒變只是在入口函數那裡加了keep-alive組件

 

 全局前置守衛驗證

 這個全局前置守衛在舊版的vue-router里名字叫全局守衛

在開發中,按照常識,都知道,不同用戶的許可權是不一樣的,然後能訪問的路由也是不一樣的,所以這就是許可權,而作為許可權驗證,得有一套機制吧,這套機制就是全局守衛

 

比如,某個網站,驗證用戶的登錄狀態,如果未登錄就提示登陸,否則就進不了需要登錄的網頁,必須登錄之後才可以查看網頁,這種場景就可以用全局前置守衛

 

相關的說明:

 

上面這個說的什麼意思呢,主要就是說,必須要調用next方法,不然的話會卡住 

 

路由元信息

首先呢,路由組件有一個元信息meta參數,這個參數就可以配置一些許可權驗證:

 

 

這裡給一個小demo,如下,這是優酷視頻網的某個部分,上面是免費視頻,下麵是需要會員才能看的視頻

 

 

好的,就做個這種簡單的出來:

 

點擊會員時,它會自動跳轉到登錄頁面

 

當我登錄之後,會員頁面顯示:

 

以上部分,在router-link傳入參數部分,可能有朋友會想,唉,你這為什麼要定義兩個公用組件,都那一套啊,免費電影和會員部分都用一套公用組件多省事啊,確實啊,這樣確實省事,其實最開始我就是這樣的,但是因為都用一個公用組件,在不同根組件切換到子組件時,會有錯亂,達不到我們的需要的效果,所以我定義了兩個公用組件。並且針對兩個組件,後期肯定還會有不同的配置的,所以這樣會更好維護一點

 

原理就是在定義路由時,給需要驗證的路由配置原信息,加了個meta參數,這個參數是router對象自帶的屬性,我們可以隨意定義鍵值進去:

 

利用這個鍵值用beforeEach全局守衛在路由跳轉時判斷這個參數,如果為true則需要做驗證,驗證通過則next()為空放行,驗證不通過則用next跳轉,這裡的next是個回調函數,有點編程式導航router.push的意思,此時這個beforeEach全局守衛其實也可以看出一個周期鉤子函數

 

 

 

對於驗證登錄狀態,用了js自帶的一個localStorage永久存儲對象作為存儲 :

 

需要清除的話,右鍵那個那個file://,點clear就行,詳細的就不多說了,自行查資料研究吧

 

 完整代碼

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>

    <style>
        .common{
            margin-top: 2%;
            width: 60%;
            height: 100px;
            background: purple;
            color: white;
            border: 1px solid rgb(144, 143, 143); 
            text-align: center;
            line-height: 50px;
        }
        .mcommon{
            margin-top: 2%;
            width: 60%;
            height: 100px;
            background-color: rgb(9, 78, 108);
            color:white;
            border: 1px solid rgb(172, 168, 168);
            text-align: center;
            line-height: 50px;
        }
    </style>
</head>

<body>

    <body>
        <div id="app"></div>
        <script>
            Vue.use(VueRouter) // 目前是全局狀態,可有可不有                       
            var login = {
                data() {
                    return {
                        name: '',
                        pwd: ''
                    }
                },
                template: `<div>                    
                        <input type='text' v-model="name">
                        <input type='password' v-model='pwd'>
                        <button @click="loginHander" >登錄</button>                    
                    </div>`,
                methods: {
                    loginHander() {
                        localStorage.setItem('user', {
                            'name': this.name,
                            'pwd': this.pwd
                        })
                        this.$router.push({
                            path: '/member'
                        })
                    }
                },
            }
            var common = { // 免費電影公用組件
                data() {
                    return {
                        msg: ''
                    }
                },
                template: `<div class="common">免費電影公用部分:XXXXX 
                    <div>{{msg}}</div></div>`,
                created() {
                    this.msg = '(css樣式結構,還沒有數據)'
                },
                watch: {
                    '$route'(to, form) {
                        console.log(form);
                        console.log(to);
                        this.msg = `${this.$route.params.category} 相關內容內容內容.........`
                    }
                }
            }
            var mcommon = { // 會員電影公用組件
                data() {
                    return {
                        msg: ''
                    }
                },
                template: `<div class="mcommon">會員電影公用部分:XXXXX 
                    <div>{{msg}}</div></div>`,
                created() {
                    this.msg = '(css樣式結構,還沒有數據)'
                },
                watch: {
                    '$route'(to, form) {
                        console.log(form);
                        console.log(to);
                        this.msg = `${this.$route.params.category} 相關內容內容內容.........`
                    }
                }
            }



            var movie = { // 免費視頻
                template: `<div>
                    <router-link :to="{name:'common',params:{category:'hollywood'}}">好萊塢</router-link>
                    <router-link :to="{name:'common',params:{category:'trailer'}}">預告片</router-link>
                    <router-link :to="{name:'common',params:{category:'online-movie'}}">網路電影</router-link>
                    <router-view></router-view></div>`,
            }
            var member = { // 會員視頻
                template: `<div>
                    <router-link :to="{name:'mcommon',params:{category:'lastest'}}">最新</router-link>
                    <router-link :to="{name:'mcommon',params:{category:'cinema'}}">院線大片</router-link>
                    <router-link :to="{name:'mcommon',params:{category:'exclusive'}}">獨播強擋</router-link>
                    <router-link :to="{name:'mcommon',params:{category:'popluar'}}">熱門紀實</router-link>
                    <router-link :to="{name:'mcommon',params:{category:'bbc'}}">BBC經典</router-link>
                    <router-link :to="{name:'mcommon',params:{category:'anime'}}">熱血動漫</router-link>
                    <router-view></router-view></div>`,
            };
            // 註意路由掛載組件的先後順序,先創建再在路由里掛載
            const router = new VueRouter({
                routes: [{
                        path: '/movie',
                        component: movie,
                        children: [{
                                path: '/',
                                component: common
                            },
                            {
                                path: '/movie/:category',
                                name: 'common',
                                component: common
                            }
                        ]
                    },
                    {
                        path: '/member',
                        component: member,
                        meta: {  // 帶有該參數,表示需要認證
                            auth: true
                        },
                        children: [
                            // 有認證之後不能再加預設路

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

-Advertisement-
Play Games
更多相關文章
  • 事件機制 React事件主要分為兩部分: 事件註冊與事件分發。下麵先從事件註冊說起。 事件註冊 假設我們的程式如下: 事件註冊主要發生在初始化Dom屬性的時候,調用 方法,對一些類型dom進行事件綁定。 js switch (tag) { case 'iframe': case 'object': ...
  • 一、自定義函數function 函數就是功能、方法的封裝。函數能夠幫我們封裝一段程式代碼,這一段代碼會具備某一項功能,函數在執行時,封裝的這一段代碼都會執行一次,實現某種功能。而且,函數可以多次調用。 1.1函數的定義和調用 語法: 定義:把需要實現的功能預先做好 執行:需要的時候執行這個功能,而且 ...
  • transform 變形屬性屬性:translate 平移,rotate 旋轉, scale 縮放,skew 傾斜 ◆ translate :指定對象的2D平移第一個參數對應X軸,第二參數對應Y軸;如果第二個參數未提供,則預設為0;translate(10px,10px)X軸 往左邊移動 對應第一個 ...
  • 頭部... 內容內容內容內容內容內容 底部。。。 .HolyGrail { display: flex; min-height: 100vh; flex-direction: column; } header, footer { height:80px; line-height: 80px; tex... ...
  • 原文地址:http://wushaobin.top/2019/03/15/webpackPlugin/ 什麼是Plugin? 在 "Webpack學習-工作原理(上)" 一文中我們就已經介紹了 的基本概念,同時知道了webpack其實很像一條生產線,要經過一系列處理流程後才能將源文件轉換成我們理想的 ...
  • 秒轉換成年月日時分秒 秒轉換成年月日時分秒 複製文本 複製文本 <script type="text/javascript"> function copy() { var url=document.getElementById("textID"); // 獲取要操作的DOM Url2.select( ...
  • import axios from 'axios' let CdnPath = {} CdnPath.install = function (Vue, options) { Vue.prototype.$_cdnDomain = function () { if (process.env.NODE_... ...
  • HTML基本結構: 選擇圖片 預覽圖: 立即提交 Java... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...