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>
刷新浏览器,切换路由时,可以看到路由切换时,页面都有动态效果