總結幾個vue-router的使用技巧

SPA(single page application):單一頁面應用程序,只有一個完整的頁面;它在加載頁面時,不會加載整個頁面,而是隻更新某個指定的容器中內容。單頁面應用(SPA)的核心之一是:更新視圖而不從新請求頁面;vue-router在實現單頁面前端路由。本文在github進行了收錄。javascript

route和router

  • $route 是「路由信息對象」,包括path,params,hash,query,fullPath,matched,name等路由參數。
  • $router 是「路由實例」對象包括了路由的跳轉方法,鉤子函數等

hash 模式 和 history 模式

  • hash 模式:在瀏覽器中符號「#」,#以及#後面的字符稱之爲 hash,用 window.location.hash 讀取。特色:hash 雖然在 URL 中,但不被包括在 HTTP 請求中;用來指導瀏覽器動做,對服務端安全無用,hash 不會重加載頁面。html

  • history 模式:history 採用 HTML5 的新特性;且提供了兩個新方法: pushState(), replaceState()能夠對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變動。前端

  • hash 模式中( http://localhost:8080#home),即便不須要配置,靜態服務器始終會去尋找index.html並返回給咱們,而後vue-router會獲取 #後面的字符做爲參數,對前端頁面進行變換。vue

  • history 模式中,咱們所想要的狀況就是:輸入http://localhost:8080/home,但最終返回的也是index.html,而後vue-router會獲取 home 做爲參數,對前端頁面進行變換。那麼在nginx中,誰能作到這件事呢?答案就是try_filesjava

nginxnode

location / {
  root      /data/www/rf-blog-web;
  index      index.html;
  try_files    $uri $uri/ /index.html;
}
複製代碼

Apachewebpack

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
複製代碼

node.jsnginx

const http = require('http')
const fs = require('fs')
const httpPort = 80

http
  .createServer((req, res) => {
    fs.readFile('index.htm', 'utf-8', (err, content) => {
      if (err) {
        console.log('We cannot open "index.htm" file.')
      }
      res.writeHead(200, {
        'Content-Type': 'text/html; charset=utf-8'
      })
      res.end(content)
    })
  })
  .listen(httpPort, () => {
    console.log('Server listening on: http://localhost:%s', httpPort)
  })
複製代碼

切換路由動態改變 title

在 app 內嵌 h5 的混合應用中,iOS 系統下部分 APP 的 webview 中的標題不能經過 document.title = xxx 的方式修改,緣由是在 IOS webview 中網頁標題只加載一次,動態改變是無效的。git

  1. 安裝依賴
npm install vue-wechat-title --save
複製代碼
  1. 在 main.js 使用
import VueWechatTitle from 'vue-wechat-title'
Vue.use(VueWechatTitle)
複製代碼
  1. 配置路由 meta 對象配置 title,在路由守衛監聽
router.afterEach(route => {
  // 從路由的元信息中獲取 title 屬性
  if (route.meta.title) {
    document.title = route.meta.title
    // 若是是 iOS 設備,則使用以下 hack 的寫法實現頁面標題的更新
    if (navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
      const hackIframe = document.createElement('iframe')
      hackIframe.style.display = 'none'
      hackIframe.src = '/static/html/fixIosTitle.html?r=' + Math.random()
      document.body.appendChild(hackIframe)
      setTimeout(_ => {
        document.body.removeChild(hackIframe)
      }, 300)
    }
  }
})
複製代碼
  1. 在 App.vue 中修改 router-view
<router-view v-wechat-title="$route.meta.title"></router-view>
複製代碼

scrollBehavior

使用前端路由,當切換到新路由時,想要頁面滾到頂部,或者是保持原先的滾動位置,就像從新加載頁面那樣。 vue-router 能作到,並且更好,它讓你能夠自定義路由切換時頁面如何滾動。github

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 指望滾動到哪一個的位置
  }
})
複製代碼

scrollBehavior 方法接收 to 和 from 路由對象。第三個參數 savedPosition 當且僅當 popstate 導航 (經過瀏覽器的 前進/後退 按鈕觸發) 時纔可用。

與 keepAlive 結合,若是 keepAlive 的話,保存停留的位置:

scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      if (from.meta.keepAlive) {
        from.meta.savedPosition = document.body.scrollTop
      }
      return { x: 0, y: to.meta.savedPosition || 0 }
    }
  }
複製代碼

keep_alive

keep-alive 是 Vue 提供的一個抽象組件,用來對組件進行緩存,從而節省性能,因爲是一個抽象組件,因此在 v 頁面渲染完畢後不會被渲染成一個 DOM 元素。

<keep-alive>
  <router-view></router-view>
</keep-alive>
複製代碼

當組件在 keep-alive 內被切換時組件的 activated、deactivated 這兩個生命週期鉤子函數會被執行

參數

  • include: 字符串或正則表達式。只有匹配的組件會被緩存。
  • exclude: 字符串或正則表達式。任何匹配的組件都不會被緩存。
<keep-alive include="a,b">
  <router-view></router-view>
</keep-alive>
<keep-alive exclude="c">
  <router-view></router-view>
</keep-alive>
複製代碼

include 屬性表示只有 name 屬性爲 a,b 的組件會被緩存,(注意是組件的名字,不是路由的名字)其它組件不會被緩存。 exclude 屬性表示除了 name 屬性爲 c 的組件不會被緩存,其它組件都會被緩存。

使用$route.meta 的 keepAlive 屬性

須要在 router 中設置 router 的元信息 meta

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello,
      meta: {
        keepAlive: false // 不須要緩存
      }
    },
    {
      path: '/page1',
      name: 'Page1',
      component: Page1,
      meta: {
        keepAlive: true // 須要被緩存
      }
    }
  ]
})
複製代碼

在app.vue進行區別緩存和不用緩存的頁面

<div id="app">
  <router-view v-if="!$route.meta.keepAlive"></router-view>
  <keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
</div>
複製代碼

相關文章

相關文章
相關標籤/搜索