1. 90前端首页
  2. 前端框架

总结几个vue-router的使用技巧

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是:更新视图而不重新请求页面;vue-router在实现单页面前端路由。
github: https://github.com/Michael-lz...
掘金: https://juejin.im/post/5df849...

route和router

  • $route 是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由参数。
  • $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等

hash 模式 和 history 模式

  • hash 模式:在浏览器中符号“#”,#以及#后面的字符称之为 hash,用 window.location.hash 读取。特点:hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安全无用,hash 不会重加载页面。
  • history 模式:history 采用 HTML5 的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
  • hash 模式中( http://localhost:8080#home),即使不需要配置,静态服务器始终会去寻找index.html并返回给我们,然后vue-router会获取 #后面的字符作为参数,对前端页面进行变换。
  • history 模式中,我们所想要的情况就是:输入http://localhost:8080/home,但最终返回的也是index.html,然后vue-router会获取 home 作为参数,对前端页面进行变换。那么在nginx中,谁能做到这件事呢?答案就是try_files

nginx

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

Apache

<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.js

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 中网页标题只加载一次,动态改变是无效的。

1.安装依赖

npm install vue-wechat-title --save

2.在 main.js 使用

import VueWechatTitle from \'vue-wechat-title\'
Vue.use(VueWechatTitle)

3.配置路由 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)
    }
  }
})

4.在 App.vue 中修改 router-view

<router-view v-wechat-title=\"$route.meta.title\"></router-view>

scrollBehavior

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

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>

本文来自网络整理,转载请注明原出处:https://segmentfault.com/a/1190000021608276

展开阅读全文

发表评论

登录后才能评论