Vue Router 是 Vue.js 官方的路由管理器,是Vue三大核心插件之一,重中之重可见一斑。
前端路由实现
传统开发方式
url改变后,立刻发生请求响应整个页面,有可能资源过多,让页面出现白屏。
SPA单页应用
锚点值发生改变,不会立刻发送请求,而是在某个合适的时机,发起Ajax请求局部刷新
原生Js实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <a href="/home">登录页面</a> <a href="/user">注册页面</a> <div id="app"></div> <script> window.onhashchange = function(){ console.log(location.hash); switch (location.hash) { case '#/home': oDiv.innerHTML = '<h2>我首页</h2>'; break; case '#/user': oDiv.innerHTML = '<h2>我是用户页</h2>'; break; default: break; } } </script>
|
VueRouter实现
使用路由
使用路由,就会创建router-link、router-view两个核心组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <div id="app"></div> <script src="node_modules/vue/dist/vue.min.js"></script> <script src="node_modules/vue-router/dist/vue-router.min.js"></script> <script> const App = { template: ` <div> <router-link to="/login">登录</router-link> <router-link to="/user">用户</router-link> <router-view></router-view> </div> ` } const Login = { template: '<div>我是登陆页</div>' } const User = { template: '<div>我是用户页</div>' } const router = new VueRouter({ routes: [{ path: '/login', component: Login }, { path: '/user', component: User }] }) new Vue({ el: '#app', data() { return {
} }, components: { App }, router, template: '<App />' }) </script>
|
设置路由别名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const App = { template: ` <div> <router-link :to="{name: 'login'}">登录</router-link> <router-link :to="{name: 'user'}">用户</router-link> <router-view></router-view> </div> ` } const router = new VueRouter({ routes: [{ path: '/login', name: 'login', component: Login }, { path: '/user', name: 'user', component: User }] })
|
路由参数的两种方式:params和query
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const App = { template: ` <div> <router-link :to="{name: 'userP', params: {id: 1}}">用户1</router-link> <router-link :to="{name: 'userQ', query: {userId: 2}}">用户2</router-link> <router-view></router-view> </div> ` } const userParams = { template: '<div>我是用户1</div>' } const userQuery = { template: '<div>我是用户2</div>' } const router = new VueRouter({ routes: [{ path: '/user/:id', name: 'userP' component: userParams }, { path: '/user', name: 'userQ' component: userQ }] })
|
路由对象访问
$route:当前路由信息对象;$router:全局路由实例对象,有go、push、replace等常用方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const userParams = { template: '<div>我是用户1</div>', created(){ console.log(this.$router) console.log(this.$route.params.id); } } const userQuery = { template: '<div>我是用户2</div>', created(){ console.log(this.$router) console.log(this.$route.query.userId); } }
|
路由嵌套
路由中设置chilren属性配置子路由,注意子路由的path路径不要出错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| const Song = { template: '<div>我是音乐</div>' } const Movie = { template: '<div>我是电影</div>' } const Login = { template: '<div>我是登录页</div>' } const User = { template: `<div> 我是用户页<br> <router-link to="/user/song">歌曲</router-link> <router-link to="/user/movie">电影</router-link> <router-view></router-view> </div>` } const router = new VueRouter({ routes: [{ path: '/login', name: 'login', component: Login }, { path: '/user', name: 'user', component: User, children: [{ path: 'song', component: Song }, { path: 'movie', component: Movie }] }] })
|
缓存渲染keep-alive
切换路由的时候,把内容缓存起来,防止重复渲染和用户操作丢失。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const Song = { template: '<div @click="clickHandler">我是音乐</div>', methods: { clickHandler(e){ e.target.style.color = 'red'; } } } const User = { template: `<div> 我是用户页<br> <router-link to="/user/song">歌曲</router-link> <router-link to="/user/movie">电影</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div>` }
|
导航守卫
vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。比如你需要验证到登录信息后才能进入用户页,否则你将可能跳转到一个登录页面。
router.beforeEach(to, from, next) 在每个路由切换前都去进行监听判断,路由中的meta字段设置需要通过验证的标记。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| const Login = { data() { return { name: localStorage.getItem('user') && localStorage.getItem('user').name || '', pwd: localStorage.getItem('user') && localStorage.getItem('user').pwd || '' } }, template: `<div> <input type="text" :value="name" v-model="name" /> <input type="password" :value="pwd" v-model="pwd" /> <button @click="loginHandler">登录</button> </div> `, methods: { loginHandler() { localStorage.setItem('user', { name: this.name, pwd: this.pwd })
this.$router.push({ name: 'user' })
} } } const User = { template: '<div>我是用户页</div>' } const router = new VueRouter({ routes: [{ path: '/login', name: 'login', component: Login }, { path: '/user', name: 'user', component: User, meta: { auth: true } }] })
router.beforeEach((to, from, next) => { console.log('to', to); console.log('from', from); if (to.meta.auth) { if (localStorage.getItem('user')) { next(); } else { next({ path: '/login' }) } } else { next(); } })
|
题外:Vue相关开源项目库汇总