SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是:更新视图而不从新请求页面;vue-router在实现单页面前端路由。本文在github进行了收录。javascript
path,params,hash,query,fullPath,matched,name
等路由参数。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_files
。java
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)
})
复制代码
在 app 内嵌 h5 的混合应用中,iOS 系统下部分 APP 的 webview 中的标题不能经过 document.title = xxx 的方式修改,缘由是在 IOS webview 中网页标题只加载一次,动态改变是无效的。git
npm install vue-wechat-title --save
复制代码
import VueWechatTitle from 'vue-wechat-title'
Vue.use(VueWechatTitle)
复制代码
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)
}
}
})
复制代码
<router-view v-wechat-title="$route.meta.title"></router-view>
复制代码
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像从新加载页面那样。 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 是 Vue 提供的一个抽象组件,用来对组件进行缓存,从而节省性能,因为是一个抽象组件,因此在 v 页面渲染完毕后不会被渲染成一个 DOM 元素。
<keep-alive>
<router-view></router-view>
</keep-alive>
复制代码
当组件在 keep-alive 内被切换时组件的 activated、deactivated 这两个生命周期钩子函数会被执行
参数
<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>
复制代码