Vue Router 是 Vue.JS 官方的路由管理器. 它和 Vue.JS 的核心深度集成, 让构建单页面 SPA(Single Page Application) 应用变得易如反掌.
什么是路由?
请看下面这个例子: 通过 Ajax 请求, 更新页面局部内容
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <a href="#/login">
- 登录页面
- </a>
- <a href="#/register">
- 注册页面
- </a>
- <div id="app">
- </div>
- <script type="text/javascript">
- var oDiv = document.getElementById('app');
- Windows.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>
- </body>
- </HTML>
那 Vue Router 能干什么?
它能使获取请求更新页面的过程更可配置, 也就是简化上面的代码, 提供更丰富的配置
看下面这个例子
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <div id="app">
- </div>
- <!-- 1. 引入 vue.js -->
- <script type="text/javascript" src="../js/vue.min.js">
- </script>
- <!-- 2. 引入核心的插件 vue-router -->
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js">
- </script>
- <script type="text/javascript">
- // 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
- }]
- });
- // 4. 使用两个全局的组件 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
- }
- });
- '
- </script>
- </body>
- </HTML>
如果 path 非常长的话, 可以给路由的匹配规则起个别名, 代码如下:
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <div id="app">
- </div>
- <!-- 1. 引入 vue.js -->
- <script type="text/javascript" src="../js/vue.min.js">
- </script>
- <!-- 2. 引入核心的插件 vue-router -->
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js">
- </script>
- <script type="text/javascript">
- // 2. 让 vue 使用该 VueRouter 创建 如果 vue 是一个局部作用域的对象 那么必须 Vue.use(VueRouter);
- // Vue.use(VueRouter);
- // 声明组件
- var Login = {
- template: ` < div > 我是登录页面 < /div>`
- };
- var Register = {
- template: `<div > 我是注册页面 </div > `
- };
- // 3. 创建路由对象
- var router = new VueRouter({
- // 4. 配置路由对象
- routes: [
- // 路由匹配的规则
- {
- path: '/login',
- name: 'login',
- component: Login
- },
- {
- path: '/register',
- name: 'register',
- component: Register
- }]
- });
- // 4. 抛出两个全局的组件 router-link router-view
- var App = {
- template: ` < div > <!--router - link默认会被渲染成a标签,
- to默认会被渲染成href属性--><router - link: to = "{name:'login'}" > 登录 < /router-link>
- <router-link :to = "{name:'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
- }
- });
- </script>
- </body>
- </HTML>
可以给路由绑定参数
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <div id="app">
- </div>
- <!-- 1. 先引入 vue.js -->
- <script type="text/javascript" src="../js/vue.min.js">
- </script>
- <!-- 2. 引入核心的插件 vue-router -->
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js">
- </script>
- <script type="text/javascript">
- // 地址栏 路由范式
- //(1)xxxxx.HTML#/user/1 params 动态路由参数
- //(2)ooooo.HTML#/user?userId = 1 query
- // Vue.use(VueRouter);
- // 声明组件 $router $route (路由信息对象)
- var UserParams = {
- template: ` < div > 我是用户1 < /div>`,
- created() {
- console.log(this.$router);
- console.log(this.$route);
- }
- };
- var UserQuery = {
- template: `<div > 我是用户 2</div > `,
- created() {
- console.log(this.$route);
- }
- };
- // 3. 创建路由对象
- var router = new VueRouter({
- // 4. 配置路由对象
- routes: [
- // 路由匹配的规则
- {
- // 动态路由参数 以冒号开头
- path: '/user/:id',
- name: 'userP',
- component: UserParams
- },
- {
- path: '/user',
- name: 'userQ',
- component: UserQuery
- }]
- });
- // 使用两个全局的组件 router-link router-view
- var App = {
- template: ` < div > <!--router - link默认会被渲染成a标签,
- to默认会被渲染成href属性--><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 > `
- }
- // Cannot read property 'matched' of undefined
- // 5. 将配置好的路由对象关联到 vue 实例化对象中
- new Vue({
- el: '#app',
- router: router,
- template: ` < App / >`,
- components: {
- App
- }
- });
- </script>
- </body>
- </HTML>
路由也可以嵌套使用
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app"></div>
- <!-- 1. 先引入 vue.js -->
- <script type="text/javascript" src="../js/vue.min.js"></script>
- <!-- 2. 引入核心的插件 vue-router -->
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
- <script type="text/javascript">
- // 地址栏 路由范式
- //(1)xxxxx.HTML#/user/1 params 动态路由参数
- //(2)ooooo.HTML#/user?userId = 1 query
- // Vue.use(VueRouter);
- // 声明组件
- var Song = {
- template: `<div > 我是歌曲组件 </div>`,
- created() {
- console.log(this.$router);
- console.log(this.$route);
- }
- };
- var Movie = {
- template: `<div > 电影组件 </div>`,
- created() {
- console.log(this.$route);
- }
- };
- // 3. 创建路由对象
- // /home/song
- // /home/movie
- var Home = {
- template: `
- <div>
首页内容
- <br />
- <router-link to = '/home/song'> 歌曲 </router-link>
- <router-link to = '/home/movie'> 电影 </router-link>
- <router-view></router-view>
- </div>
- `
- };
- var router = new VueRouter({
- // 4. 配置路由对象
- routes: [
- // 路由匹配的规则
- {
- // 动态路由参数 以冒号开头
- path: '/home',
- name: 'home',
- component: Home,
- children: [{
- path: 'song',
- component: Song
- },
- {
- path: 'movie',
- component: Movie
- },
- ]
- }
- ]
- });
- // 使用两个全局的组件 router-link router-view
- var App = {
- template: `
- <div>
- <!--router-link 默认会被渲染成 a 标签, to 默认会被渲染成 href 属性 -->
- <router-link :to = "{name:'home'}"> 首页 </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
- }
- });
- </script>
- </body>
- </HTML>
动态路由匹配 (地址栏中参数的变化和 watch 的使用)
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <div id="app">
- </div>
- <!-- 1. 先引入 vue.js -->
- <script type="text/javascript" src="../js/vue.min.js">
- </script>
- <!-- 2. 引入核心的插件 vue-router -->
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js">
- </script>
- <script type="text/javascript">
- // 地址栏 路由范式
- //(1)xxxxx.HTML#/user/1 params 动态路由参数
- //(2)ooooo.HTML#/user?userId = 1 query
- // Vue.use(VueRouter);
- var ComDesc = {
- data() {
- return {
- msg: ''
- }
- },
- template: ` < div > {
- {
- msg
- }
- } < /div>
- `,
- created() {
- this.msg = 'andorid';
- console.log(1);
- },
- watch: {
- '$route'(to, from) {
- / / 对路由变化作出响应...console.log(to);
- console.log(from);
- this.msg = to.params.id;
- }
- }
- }
- // 3. 创建路由对象
- // /timeline/andorid
- // /timeline/frontend
- var Timeline = {
- template: ` < div id = 'timeline' > <router - link: to = "{name:'comDesc',params:{id:'andorid'}}" > 安卓 < /router-link>
- <router-link :to ="{name:'comDesc',params:{id:'frontend'}}"> 前端 </router - link > <router - view > </router-view>
- </div > `
- };
- var Pins = {
- template: ` < div > 我是沸点 < /div>
- `
- }
- var router = new VueRouter({
- / / 4.配置路由对象routes: [
- // 路由匹配的规则
- {
- // 动态路由参数 以冒号开头
- path: '/timeline',
- name: 'timeline',
- component: Timeline,
- children: [{
- name: 'comDesc',
- path: '/timeline/:id',
- component: ComDesc
- }]
- },
- {
- path: '/pins',
- component: Pins
- }]
- });
- // 使用两个全局的组件 router-link router-view
- var App = {
- template: ` < div > <!--router - link默认会被渲染成a标签,
- to默认会被渲染成href属性--><router - link to = '/timeline' > 首页 < /router-link>
- <router-link to = '/pins '> 沸点 </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
- }
- });
- '
- </script>
- </body>
- </HTML>
meta 和全局路由的渲染前配置
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id="app">
- <!-- 声明式的导航 -->
- <router-link to='/home'> 首页 </router-link>
- <router-link to='/blog'> 我的博客 </router-link>
- <router-link to='/login'> 登录 </router-link>
- <a href="javascript:void(0);" @click='clear'> 退出 </a>
- <router-view></router-view>
- </div>
- <script type="text/javascript" src="../js/vue.min.js"></script>
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script>
- <script type="text/javascript">
- Vue.use(VueRouter);
- var Home = {
- template: `
- <div>
我是首页
- </div>
- `
- };
- var Blog = {
- template: `
- <div>
我是博客
- </div>
- `
- };
- var Login = {
- data() {
- return {
- name: '',
- pwd: ''
- }
- },
- template: `
- <div>
- <input type="text" v-model ='name'/>
- <input type="text" v-mode = 'pwd'/>
- <input type="button" value ='登录' @click = 'login'/>
- </div>
- `,
- methods: {
- login() {
- localStorage.setItem('user', {
- name: this.name,
- pwd: this.pwd
- });
- // 编程式导航
- this.$router.push({
- name: 'blog'
- });
- }
- }
- };
- var router = new VueRouter({
- routes: [{
- path: '/',
- redirect: '/home'
- },
- {
- path: '/home',
- component: Home
- },
- {
- name: 'blog',
- path: '/blog',
- component: Blog,
- // 给未来路由 做权限控制 全局路由守卫 来做参照条件
- meta: {
- // 表明用户访问该组件是需要登录, auth 是自定义的参数
- auth: true
- }
- },
- {
- path: '/login',
- component: Login
- }
- ]
- });
- router.beforeEach((to, from, next) => {
- console.log(to);
- console.log(from);
- if (to.meta.auth) { // 用户点击了博客链接 该用户未登录 需要登录判断 准备跳转登录页面
- if (localStorage.getItem('user')) {
- // alert(1);
- // 不为空 放行
- next();
- } else {
- // alert(2);
- // 用户需要登录
- next({
- path: '/login'
- });
- }
- } else {
- // 直接放行
- next(); // 如果不调用 next 就会卡住
- }
- });
- new Vue({
- el: '#app',
- router,
- methods: {
- clear() {
- localStorage.removeItem('user');
- this.$router.push('/login');
- }
- }
- });
- </script>
- </body>
- </HTML>
keep-alive 在路由中的使用
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- </title>
- </head>
- <body>
- <div id="app">
- </div>
- <script type="text/javascript" src="../js/vue.min.js">
- </script>
- <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js">
- </script>
- <script type="text/javascript">
- Vue.use(VueRouter);
- var Series = {
- template: ` < div > 付费栏目 < /div>
- `,
- created() {
- console.log('付费栏目组件 created');
- },
- mounted() {
- console.log('付费栏目组件 mounted');
- },
- destroyed() {
- console.log('付费栏目组件被销毁了')
- }
- };
- var Topics = {
- template: `
- <div>
- <h3 @click = 'clickHandler'> 我是专题广场 </h3 > </div>
- `,
- methods: {
- clickHandler(e) {
- e.target.style.color = 'red';
- }
- },
- created() {
- console.log('专题广场组件 created');
- },
- mounted() {
- console.log('专题广场组件 mounted');
- },
- destroyed() {
- console.log('专题广场组件被销毁了')
- }
- };
- var router = new VueRouter({
- routes: [{
- path: '/series ',
- component: Series
- },
- {
- path: ' / topics ',
- component: Topics
- },
- ]
- });
- var App = {
- template: `
- <div>
- <router-link to = ' / series '> 付费栏目 </router-link>
- <router-link to = ' / topics '> 专题广场 </router-link>
- <keep-alive>
- <router-view></router-view>
- </keep-alive>
- </div>
- `
- }
- new Vue({
- el: '#app ',
- template: `<App />`,
- components: {
- App
- },
- router
- });
- '
- </script>
- </body>
- </HTML>
来源: http://www.bubuko.com/infodetail-3086332.html