高度なルーティングのVueの開発

1.ルーティングコンポーネントのパラメータ渡し

1ページ内に、パラメータを得るために必要なルーティングによると、ページ内のロジックを処理し、関連するパラメータは、$経路によって得ることができます

しかし、この方法は、ページに連結されたルーティングコンポーネントを分離するためには、ページコンポーネントは、大きい程度に多重化することができ、高すぎる、あなたは、パラメータ設定、ルーティンググループを渡すことができます

三つの形式を渡しルーティングコンポーネントのパラメータ

1.1最初:ブールモード

動的ルーティングのマッチングに配置適切な経路、動的ルーティングパラメータの

前の例では、動的ルーティングは、ルートパラメータを定義します

変更しsrc/router/router/jsたファイルを

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    }
]

変更しsrc/views/argu.vueたファイルの内容を:

<template>
    <div>
        {{ $route.params.name }}
    </div>
</template>

<script>
export default {

}
</script>

ブラウザのURLを開きます。http://localhost:8080/#/argu/orange以下のような効果があります

上記にargUページにすることができる$route对象動的ルーティングのパラメータを取得し、この時間は、動的ルーティングで定義されたブールモデルパラメータを使用して取得することができます

変更src/router/router/jsダイナミックルーティングパラメータを取得するブールモードを定義するファイルを

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true      // 定义布尔模式获取路由参数
    }
]

変更しsrc/views/argu.vueたファイルを

<template>
    <div>
        {{ name }}
    </div>
</template>

<script>
export default {
    props:{
        name:{
            type:String,            // 定义name的值的类型,String表示name的值必须为字符串,Number表示name的值为整数
            default:'renpingsheng'  // 定义默认值,可以省略
        }
    }
}
</script>

次のような効果があるルートのパラメータを変更

1.2秒:オブジェクトモード

例えば、ページのパラメータの受け渡しのルーティングについての伝統的な価値観の共通ルート、

変更しsrc/router/router.jsた経路についてのファイル転送値を

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
        props:{
            fruit:"banana"
        }
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    }
]

その後、修正src/views/About.vueファイルを

<template>
<div class="about">
    <h1>This is an about page</h1>
    <b>{{ fruit }}</b>
</div>
</template>
<script>
export default {
    props:{
        fruit:{
            type:String,
            default:'apple'     // 默认值,如果路由中没的传递任何值则在页面上显示默认值
        }
    }
}
</script>

原因/果物の値転送経路について、以下の表示ページとなるように

このときの値は、ルートの果物の小道具属性で渡されていない場合

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
        props:{
            // fruit:"banana"       // 把传递参数的这一行注释
        }
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    }
]

SRC /ビューは/同じファイル内容About.vue、デフォルト値はAbout.vueは次のように表示効果があり、ページ内に定義されたファイルの属性を小道具表示されます

第三1.3:ファンクションモード

コンポーネントに渡されたプロパティ値を設定するように、適切なロジックは、現在のルーティング受信特性に応じて決定することができます

変更しsrc/router/router/jsたファイルを、ルートホームを変更

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
        props: route => ({
            fruit: route.query.params
        })
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
        props:{
            // fruit:"banana"
        }
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    }
]

変更しsrc/views/Home.vueたファイルを

<template>
<div class="home">
    <b>{{ fruit }}</b>
    <br>
    <button @click="handleClick">返回上一页</button>
</div>
</template>

<script>

export default {
    name: 'home',
    props:{
        fruit:{
            type: String,
            default:'strawberry'
        }
    },
    methods:{
        handleClick () {
            this.$router.push({
            name:`argu`,
            params:{
                name:'banana'
            }
            })
        }
    }
}
</script>

URLは、ブラウザを開きます。http://localhost:8080/#/?params=orange次のように表示があります

URLのparamsは、次のようにページの表示があり、キーと値のペアを追加削除

URLは、キーと値のペアをparamsは含まれている場合は、ページのparamsのURLの値を表示します

URLはのparamsキーと値のペアで渡されていない場合は、ページ上の小道具で定義されたデフォルト値が表示されます

2.ガード

ナビゲーション警備員は、バックエンドミドルウェア機能の開発にほぼ相当、スキルの実際の開発に使用されます

発生する可能性があり、この段階でエンドナビゲーションに対応するルーティングロジックの一部をジャンプ

ユーザが直接ページを開くログインしている場合は、ページは、ログインが必要な開いたときたとえば、ユーザーがログインしているかどうかを判断します

ユーザーがログオンしていない場合は、ログインページにジャンプします

別の例は、ユーザが別のページにジャンプし、他の機能は、ナビゲーションガードによって実行することができたときに保存するようにユーザーに思い出させるために、ページの内容を編集しています

2.1グローバル・ガード

全局守卫就是在全局设置的守卫

変更しsrc/router/index.jsたファイルを、添加全局守卫

import Vue from 'vue'
import Router from 'vue-router'
import routes from './router'

Vue.use(Router)

const router = new Router({
    routes
})

const IS_LOGINED = true         // 模拟用户是否登录

router.beforeEach((to,from,next) => {
    if(to.name !== 'login'){
        if(IS_LOGINED) next()
        else next({name:'login'})
    }else{
        if(IS_LOGINED) next({name:'home'})
        else next()
    }
})
export default router

変更しsrc/router/router.jsたファイルを、添加login命名路由

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
        props: route => ({
            fruit: route.query.params
        })
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
        props:{
            // fruit:"banana"
        }
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    },{
        path:'/login',
        name:'login',
        component:() => import('@/views/login.vue')
    }
]

すると在src/views/目录下新建login.vue文件、以下のように、文書が読み込み

<template>
    <div>
        <b>this is login page</b>
    </div>
</template>

<script>
export default {
    
}
</script>

ブラウザにルーティングリストを入力し任意のURLに設定されている、対応するページを入力します

ときにsrc/router/index.js、ファイルIS_LOGINED的值设置为falseとき

import Vue from 'vue'
import Router from 'vue-router'
import routes from './router'

Vue.use(Router)

const router = new Router({
    routes
})

const IS_LOGINED = false

router.beforeEach((to,from,next) => {
    if (to.name !== 'login') {
        if (IS_LOGINED) next()
        else next({ name: 'login' })
    } else {
        if (IS_LOGINED) next({ name: 'home' })
        else next()
    }
})
export default router

ログインページに入りますお使いのブラウザで任意のURLを入力します。

それぞれの方法には、3つの警備員のパラメータを受け取ります。

to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
其中,next方法可以传入的参数:
    next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
    next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
    next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

すべてのルートに次の方法を実行するために最後を守るようにしてください、またはフックが解決されません

2.2ホームガード

后置守卫不能阻止页面的跳转

変更しsrc/router/index.jsたファイルを、设置后置守卫

import Vue from 'vue'
import Router from 'vue-router'
import routes from './router'

Vue.use(Router)

const router = new Router({
    routes
})

const IS_LOGINED = true

router.beforeEach((to,from,next) => {
    if (to.name !== 'login') {
        if (IS_LOGINED) next()
        else next({ name: 'login' })
    } else {
        if (IS_LOGINED) next({ name: 'home' })
        else next()
    }
})

router.afterEach((to, from) => {
    console.log(from)
    console.log(to)
})
export default router

まず、印刷結果におけるポストガードによると、およそのページにジャンプし、ブラウザのホームページを開きます

フロントガードbeforeResolve 2.3

警備員はまた、グローバルコールbeforeResolveガード、確認されているだけでなく、非同期のナビゲーションルートが後に解決される前に、すべてのコンポーネントを守るにおけるbeforeResolveの役割でした

ナビゲーションは、すべてのナビゲーションは、すべてのフックにわたって認識され、その後、ナビゲーションが確認されたことを意味します

2.4ルーティング排他ガード

路由独享守卫是在路由列表中配置的,例如在home路由中配置一个只在home路由中被调用的守卫

変更src/router/router.jsホームルーティングのためのファイルを添加路由独享守卫

import Home from '@/views/Home.vue'

export default [
    {
        path: '/',
        name: 'home',
        alias:'/home_page',
        component: Home,
        props: route => ({
            fruit: route.query.params
        }),
        beforeEnter:(to,from,next) => {
            if(from.name === 'about') alert("这是从about页来的")
            else alert("这不是从about页来的")
            next()
        }
    }, {
        path: '/about',
        name: 'about',
        component: () => import('@/views/About.vue'),
        props:{
            // fruit:"banana"
        }
    },{
        path:'/argu/:name',
        name:'argu',
        component:() => import('@/views/argu.vue'),
        props:true
    },{
        path:'/login',
        name:'login',
        component:() => import('@/views/login.vue')
    }
]

このとき、用浏览器打开home页,然后跳转到about页,再从about页跳转回到home页ダイアログをポップアップ

ポップアップボックスをキャンセルし、ブラウザにURLを入力しますhttp://localhost:8080/#/argu/orange、再入力にargUページからホームページには、ダイアログボックスをポップアップ表示されます

あなたが排他的なガードをルーティングbeforeEnter追加する場合は、ロジックを実行した後に、それ以外の場合はジャンプしませんが、次の()メソッドを呼び出してください

2.5コンポーネントガード

各コンポーネントは、3つのフックを持つことができます

その他のコメントガード、修正しsrc/views/Home.vueたファイルを、添加组件内守卫

<template>
<div class="home">
    <b>{{ fruit }}</b>
    <br>
    <button @click="handleClick">返回上一页</button>
</div>
</template>

<script>

export default {
    name: 'home',
    props:{
        fruit:{
            type: String,
            default:'strawberry'
        }
    },
    beforeRouteEnter(to,from,next){
        console.log(this)
        console.log(from.name)
        console.log(to.name)
        next()
    },
    methods:{
        handleClick () {
            this.$router.push({
            name:`argu`,
            params:{
                name:'banana'
            }
            })
        }
    }
}
</script>

ブラウザにのURLを開きますhttp://localhost:8080/#/し、その後についてのページにジャンプした後、バックホームページにジャンプ

在浏览器的调试页面可以看到

当直接打开Home页面时,from.name的值是null,to.name的值为home
而当从About页面跳转到Home页面时,from.name的值是about,to.name的值仍然是home

组件内守卫是在路由已经被触发,在进入对应页面调用,此时对应页面还没有渲染,所以在组件内守卫中调用this时,是获取不到当前组件的实例的,正如上面的例子里其值为undefined

跟路由独享守卫一样,如果添加了beforeRouteEnter守卫,在进行逻辑处理后,一定要调用 next()方法,否则不会进行跳转
如果想在组件内守卫中获取当前组件的实例,可以在next方法中获取

修改src/views/Home.vue文件,在组件内守卫的next方法中获取组件实例

<template>
<div class="home">
    <b>{{ fruit }}</b>
    <br>
    <button @click="handleClick">返回上一页</button>
</div>
</template>

<script>

export default {
    name: 'home',
    props:{
        fruit:{
            type: String,
            default:'strawberry'
        }
    },
    beforeRouteEnter(to,from,next){
        next( vm => {
            console.log(vm)
            console.log(vm.$root)
        })
    },
    methods:{
        handleClick () {
            this.$router.push({
            name:`argu`,
            params:{
                name:'banana'
            }
            })
        }
    }
}
</script>

刷新浏览器,打印结果如下

可以通过回调函数的方式来获取当前组件的实例,然后就可以获取某个属性的结果了

修改src/views/Home.vue文件,添加beforeRouteLeave守卫

<template>
<div class="home">
    <b>{{ fruit }}</b>
    <br>
    <button @click="handleClick">返回上一页</button>
</div>
</template>

<script>

export default {
    name: 'home',
    props:{
        fruit:{
            type: String,
            default:'strawberry'
        }
    },
    beforeRouteEnter(to,from,next){
        next( vm => {
            console.log(vm)
            console.log(vm.$root)
        })
    },
    beforeRouteLeave(to,from,next){
        const is_leave = confirm("您确定要离开本页面吗?")
        if(is_leave) next()
        else next(false)
    },
    methods:{
        handleClick () {
            this.$router.push({
            name:`argu`,
            params:{
                name:'banana'
            }
            })
        }
    }
}
</script>

刷新浏览器,显示效果如下

点击About标签后,显示效果如下

点击确定按钮,页面会跳转到About页面

如果点击取消按钮,则页面不会跳转,仍然会停留在Home页面

在这个守卫被调用时,页面已经渲染好了,所以可以在beforeRouteLeave组件里使用this来获取组件实例

比如我们一个网页发表一篇博客,当误操作点击跳转到其他页面时,此时就可以使用这个守卫来提示用户是否保存当前的编辑内容

2.6 beforeRouteUpdate守卫

修改src/views/argu.vue文件,添加beforeRouteUpdate守卫

<template>
    <div>
        {{ name }}
    </div>
</template>

<script>
export default {
    props:{
        name:{
            type:String,
        }
    },
    beforeRouteUpdate(to,from,next){
        console.log(to.name, from.name)
    }
}
</script>

使用浏览器打开URL:http://localhost:8080/#/argu/apple,此时在浏览器的调试页面不会打印任何数据

修改URL为:http://localhost:8080/#/argu/orange,页面显示效果如下

第一次进入argu页面时,没有打印任何内容,说明beforeRouteUpdate守卫没有被调用
当路由不改变,路由参数改变时,argu组件被复用,beforeRouteUpdate守卫才被调用

与beforeRouteLeave守卫一样,在beforeRouteUpdate守卫里,页面已经渲染好了,所以可以使用this来获取组件实例

3.一个完整的导航解析流程

导航被触发,不管是使用this.$router.push方式触发,还是在浏览器中直接输入URL的方式触发,
在失活的组件(即将离开的页面组件)里调用离开守卫 beforeRouteLeave
调用全局的前置守卫 beforeEach
在重用的组件里调用 beforeRouteUpdate 
调用路由独享守卫 beforeEnter
解析异步路由组件
在被激活的组件(即将进入的页面组件)里调用beforeRouteEnter
调用全局的解析守卫 beforeResolve
导航被确认
调用全局的后置守卫 afterEash
触发DOM更新
用创建好的实例调用 beforeRouterEnter守卫里传给next的回调函数

4.路由切换的动态效果

路由的切换其实就是一个路由注销,另一个路由加载

修改src/App.vue文件,

<template>
<div id="app">
    <div id="nav">
    <router-link v-bind:to="{ name:'home'}">Home</router-link> |
    <router-link :to="{ name:'about'}">About</router-link>
    </div>
    <transition-group name="router">
    <router-view key="defalut"/>
    <router-view key="view1" name="view1"/>
    <router-view key="view2" name="view2"/>
    </transition-group>
</div>
</template>

<style lang="less">
.router-enter{
    opacity: 0;
}
.router-enter-active{
    transition: opacity 2s ease;
}
.router-enter-to {
    opacity:1;
}
.router-leave{
    opacity:1;
}
.router-leave-active{
    transition:opacity 2s ease;
}
.router-leave-to {
    opacity:0;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}

#nav a {
font-weight: bold;
color: #2c3e50;
}

#nav a.router-link-exact-active {
color: #42b983;
}
</style>

刷新浏览器,切换路由时,可以看到路由切换时,页面都有动态效果

おすすめ

転載: www.cnblogs.com/renpingsheng/p/10926732.html