1. 程式人生 > 實用技巧 >【Vue】Re17 Router 第四部分(引數傳遞,守衛函式)

【Vue】Re17 Router 第四部分(引數傳遞,守衛函式)

一、案例搭建

新建Profile元件

元件寫好內容後配置路由

  {
    path : '/profile',
    component : () => import('../components/Profile')
  }

二、引數配置

App.vue配置profile

我們可以使用物件對to的url進行封裝

path屬性就是url

query屬性就是我們的請求資料【給地址的請求引數】

<template>
  <div id="app">
    <router-link to="/home" tag="button" >去首頁</router-link
> <router-link to="/about" tag="button" >去關於</router-link> <router-link :to="/user/+username" tag="button" >使用者管理</router-link> <router-link :to="ppp" tag="button" >profile</router-link> <!-- <button @click="toHome">首頁</button>--> <!--
<button @click="toAbout">關於</button>--> <router-view></router-view> </div> </template> <script> export default { name: 'App', data() { return { username : 'aaa', ppp : { path : '/profile', query : { name :
'aaa', age : 22, gender : true
} } } } // methods : { // toHome () { // this.$router.push('/home'); // }, // toAbout () { // this.$router.push('/about'); // } // } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>

可以看到引數這樣傳遞過來了

如果要取出請求引數,則可以這樣:

寫在方法裡面獲取,記得先從this物件引用

<template>
  <div>
    <h3>Profile-Component</h3>
    <p>
      profile component content ... <br>
      name -> {{$route.query.name}} <br>
      age -> {{$route.query.age}} <br>
      gender -> {{$route.query.gender}}
    </p>
  </div>
</template>

<script>
export default {
  name: "Profile"
}
</script>

<style scoped>

</style>

路由的程式碼寫法:

<template>
  <div id="app">
    <router-link to="/home" tag="button" >去首頁</router-link>
    <router-link to="/about" tag="button" >去關於</router-link>
    <router-link :to="/user/+username" tag="button" >使用者管理</router-link>
<!--    <router-link :to="ppp" tag="button" >profile</router-link>-->
    <button @click="toProfile" >profile</button>
<!--    <button @click="toHome">首頁</button>-->
<!--    <button @click="toAbout">關於</button>-->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
  data()  {
    return {
      username : 'aaa',
      ppp : {
        path : '/profile',
        query : {
          name : 'aaa',
          age : 22,
          gender : true
        }
      }
    }
  },
  methods : {
    toHome () {
      this.$router.push('/home');
    },
    toAbout () {
      this.$router.push('/about');
    },
    toProfile() {
      this.$router.push(this.ppp);
    }
  }

}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

三、$route & $router的區別?

router是全域性路由控制器物件

route是當前活躍的路由物件,是routes屬性陣列中的一個元素,也可以是router物件內部的一個屬性物件

https://www.bilibili.com/video/BV15741177Eh?p=113

四、導航守衛方法

1、回顧Vue例項的生命週期

  created() {
    // todo ... Vue建立時呼叫此函式,
  },
  mounted() {
    // todo ... Vue例項開始掛載虛擬DOM時呼叫此函式
  },
  updated() {
    // todo ... ... 元件資料發生更新時呼叫
  },

點選不同的子元件,更換標籤文字的需求:

每一次訪問不同的元件都會呼叫created函式

所以可以:

created() {
  // todo ... Vue建立時呼叫此函式,
  document.title = '關於-About';
},

但是這樣N個元件就要寫N次了,都是路由跳轉的方式進行的

那麼只要在監聽路由跳轉,在那個時刻把title元件的某一個數據就行了

import Vue from 'vue';
import Router from 'vue-router';


Vue.use(Router);

/* 方式一 */
const Home = resolve => {
  require.ensure(
    ['../components/Home.vue'],
    () => resolve(require('../components/Home.vue'))
  )
}
/* 方式二 */
const About = resolve => {
  require(['../components/About.vue'],resolve);
}
/* 方式三 */
const User = () => import('../components/User.vue');

const News = () => import('../components/home/News');
const Messages = () => import('../components/home/Messages');

const routerList = [
  /* 重定向首頁路由配置 */
  {
    path : '', /* 預設值預設指向 '/' */
    redirect : '/home',
  },
  {
    path : '/home', /* 為什麼這裡是path不是url? 因為完整的url還包括 專案根url(協議頭 + 域名(或者IP地址) + 埠號 + 專案根名稱路徑(可選))  */
    name : 'home', /* 名字可以不加 */
    component : Home, /* 使用懶載入後component這裡高亮顯示 */
    children : [ /* 設定子路由 */
      {
        path : '', /* 這個預設預設/home */
        redirect : 'news',
      },
      {
        path : 'news', /* 等同於 /home + /news = /home/news 這裡不需要再加斜槓了 */
        component : News,
        meta : {
          title : '新聞列表 - News'
        }
      },
      {
        path : 'messages',
        component : Messages,
        meta : {
          title : '訊息列表 - Messages'
        }
      }
    ],
    meta : {
      title : '首頁 - Home'
    }
  },
  {
    path : '/about',
    name : 'about',
    component : About,
    meta : {
      title : '關於 - About'
    }
  },
  {
    path : '/user/:username', /* 動態路徑:冒號+字元 */
    name : 'user',
    component : User,
    meta : {
      title : '使用者 - User'
    }
  },
  {
    path : '/profile',
    component : () => import('../components/Profile'),
    meta : {
      title : '檔案 - Profile'
    }
  }
]
const router = new Router({
  routes : routerList,
  mode : 'history',
});

/* 在建立例項後呼叫 */
router.beforeEach((to, from, next) => {
  // 呼叫這個方法以為著重寫,一定要呼叫 next方法, 否則路由無法跳轉

  // from 來自於哪個路由物件
  // to 跳轉到哪個路由物件

  // 按照案例的需求,就可以這樣設定了 route就是一個個routes的元素物件
  // 可以設定一個meta屬性物件,放入title屬性和對應的值即可
  document.title = to.meta.title;

  // 但是子路由沒有命名的話會早曾undefined顯示,因為meta屬性為空
  // 解決方案 document.title = to.matched[0].meta.title;

  // 跳轉要放在最後,不然是跳完了再執行標籤的文字更換
  next();
});
export default router;

afterEach守衛方法:

router.afterEach((to, from) => {
  // 因為是跳轉之後呼叫,自然而然的不需要next函數了
  // TODO ... ...
});

上述的兩個都是全域性守衛方法,在路由配置中重寫並呼叫

五、區域性路由守衛

詳細資料:

https://router.vuejs.org/guide/advanced/navigation-guards.html

You can definebeforeEnterguards directly on a route's configuration object:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

In-Component Guards

Finally, you can directly define route navigation guards inside route components (the ones passed to the router configuration) with the following options:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // called before the route that renders this component is confirmed.
    // does NOT have access to `this` component instance,
    // because it has not been created yet when this guard is called!
  },
  beforeRouteUpdate (to, from, next) {
    // called when the route that renders this component has changed.
    // This component being reused (by using an explicit `key`) in the new route or not doesn't change anything.
    // For example, for a route with dynamic params `/foo/:id`, when we
    // navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
    // will be reused (unless you provided a `key` to `<router-view>`), and this hook will be called when that happens.
    // has access to `this` component instance.
  },
  beforeRouteLeave (to, from, next) {
    // called when the route that renders this component is about to
    // be navigated away from.
    // has access to `this` component instance.
  }
}