路由就是通过修改url地址来实现页面跳转
Vue Router 中文官网 https://router.vuejs.org/zh/
路由原理:
(1)传统开发方式 url改变后,立刻发生请求响应整个页面,有可能资源过多,传统开发会让页面出现白屏
(2) SPA Single Page Application 单页面应用
锚点值的改变后 不会立刻发送请求,而是在某个合适的时机,发起ajax请求,
局部改变页面的数据
主要是通过加载不同的组件是实现效果的
优点:页面不立刻跳转 用户体验好
最基本的路由使用方法
通过检测hash值的变化来实现
<a href="#/login">登录页面</a>
<a href="#/register">注册页面</a>
<div id="app">
</div>
<script type="text/javascript">
var oDiv = document.getElementById('app');
window.onhashchange = function() {
console.log(location.hash);
switch (location.hash) {
case '#/login':
oDiv.innerHTML = '<h2>我是登录页面</h2>'
break;
case '#/register':
oDiv.innerHTML = '<h2>我是注册页面</h2>'
break;
default:
// statements_def
break;
}
}
</script>
vue-router的使用
最开始要先初始化
npm init // 初始化package.json
下载vue-router
npm install vue-router --save
下载结束后会有一个vue-router文件夹如果要引入vue-router.js的话,它在/node_module/vue-router/dist/vue-router
<script type="text/javascript" src="../node_modules/vue-router/dist/vue-router.js"></script>
vue的是一个单页面网页,路由的切换网页不会跳转,只是不同组件间的来回切换
Vue.use(VueRouter); // 让vue使用该VueRouter创建使用vue-router前尽量要先写这,不然可以看出人自动把这个VueRouter对象暴露给了全局里的Vue,但没有给局部的Vue
// 看下图
VueRouter的基本语法
path name component redirect(重定向) alias(别名) children(子路由)
var router = new VueRouter({
routes:[ // 注意这是一个数组,里面嵌套的是对象,每一个对象代表一个路由
{
path:'/login', // 路由地址
name:'login', // 对这个路由进行命名
component:Login , // 对应的路由要加载的组件
redirect: { name: 'foo' }, // 会重定向到别的路由中
alias: '/b', // 为当前路由起一个别名访问那个都一样
children:[ //路由嵌套 一个页面可能有多个路由同时嵌套就相当于路由之间的父子关系
{
// 当 /login 匹配成功,
// UserProfile 会被渲染在 Login 的 <router-view> 中
path: 'profile',
component: UserProfile // 还可以嵌套
}
],
},
{
path:'/register', // 路由地址
component:Register // 对应的路由要加载的组件
},
],
linkActiveClass:'myActive' // 触发路由时额外增加的类名
})
new Vue({
....,
router:router, // 把这路由对象挂载到Vue实例中去 也可以写成 router, 不然不挂载怎么用
....
})
vue router为我们暴露出的两个全局组件
<router-link to="/login"></router-link> 作用就个HTML中的a标签的作用是一样的 可以使用bind绑定
<router-link :to="{name:login}"></router-link> 和上面那个效果相同 to会被解析成href
:to中绑定的对象只要让页面知道是具体的某个路由就行,绑定里只能写对象
也可以
:to='{name:login,params:{id:'8-8'}}' // login/8-8顺便传个值也是可以的
<router-view></router-view> // 会将当前路由下的子路由中的组件加载到这个里
<router-link to="/login" replace></router-link> 这样实现路由跳转不会留下历史记录
命名视图
将组件加载到指定router-view中
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar, // a是对应的router-vie 的name Bar是要在a中加载的组件名称
b: Baz
}
}
]
})
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
编程式路由
// 字符串 使用router.push来实现路由跳转会留下历史记录
router.push('home') // 官网上这个好理解
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
const userId = 123;
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user query可以
还有个replace 就是router.replace和上面的一样就是把push替换掉这样导航不会留下历史记录
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,
类似 window.history.go(n)。
列子:
// 2.让vue使用该VueRouter创建
Vue.use(VueRouter);
//声明组件
var Login = {
template:`<div>我是登录页面</div>`
};
var Register = {
template:`<div>我是注册页面</div>`
};
// 3.创建路由对象
var router = new VueRouter({
// 4.配置路由对象
routes:[
// 路由匹配的规则
{
path:'/login',
component:Login
},
{
path:'/register',
component:Register
}
]
});
// 抛出两个全局的组件 router-link router-view
var App = {
template:`
<div>
<!--router-link默认会被渲染成a标签,to默认会被渲染成href属性-->
<router-link to = '/login'>登录</router-link>
<router-link to = '/register'>注册</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
}
// Cannot read property 'matched' of undefined
// 5.将配置好的路由对象关联到vue实例化对象中
new Vue({
el:'#app',
router:router,
template:`<App />`,
components:{
App
}
});