路由

# vue2 仅支持 vue-router 3版本,不支持 4版本
pnpm i vue-router@3.5.3

基本使用

main.js
router/index.js
App.vue
components/About.vue
components/Home.vue

import 'bootstrap/dist/css/bootstrap.min.css'
import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../components/About.vue'
import Home from '../components/Home.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>React Router Demo</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
export default {
  name: "App",
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <h3>我是Home的内容</h3>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

标准化

  • 目录树
├── App.vue
├── components          -- 存普通控件
│   └── Banner.vue
├── main.js
├── pages               -- 存页面控件
│   ├── About.vue
│   └── Home.vue
└── router
    └── index.js
  • 代码

main.js
router/index.js
App.vue
pages/About.vue
pages/Home.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'
import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <h3>我是Home的内容</h3>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

嵌套路由

  • 目录树
├── App.vue
├── components
│   └── Banner.vue
├── main.js
├── pages
│   ├── About.vue
│   └── Home
│       ├── index.vue
│       ├── Message.vue
│       └── News.vue
└── router
    └── index.js
  • 代码

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/Message.vue
/pages/Home/News.vue
components/Banner.vue

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
    <li><a href="/message1">message001</a>&nbsp;&nbsp;</li>
    <li><a href="/message2">message002</a>&nbsp;&nbsp;</li>
    <li><a href="/message/3">message003</a>&nbsp;&nbsp;</li>
  </ul>
</template>

<script>
export default {
  name: "News",
};
</script>

<style>
</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

query 传参

<!-- 第一种方式 -->
<!-- <router-link :to="`/home/message/detail?id=${o.id}&msg=${o.title}`"></router-link> -->

<!-- 第二种方式 对象方式 -->
<router-link :to="{
    path: '/home/message/detail',
    query: {
    id: o.id,
    msg: o.title
    }
}"></router-link>

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            path: 'detail',
                            component: Detail
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="(o) in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail?id=${o.id}&msg=${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link :to="{
          path: '/home/message/detail',
          query: {
            id: o.id,
            msg: o.title
          }
        }">{{o.title}}</router-link>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        {id: '001' title='下来的时间'},
        {id: '002' title='找了家旅馆'},
        {id: '003' title='起来看高清'}
      ]
    }
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{$route.query.id}}</h4>
      <h4>消息内容: {{$route.query.msg}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    }
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

命名路由

  • 当传参路径太长适合此种方式
{
    path: 'message',
    component: Message,
    children: [
        {
            name: 'detailRouter',
            path: 'detail',
            component: Detail
        }
    ]
}
  • router
<router-link :to="{
    name: 'detailRouter', // 简化方式,路径太长时使用
    query: {
    id: o.id,
    msg: o.title
    }
}">{{o.title}}</router-link>

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail',
                            component: Detail
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="(o) in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail?id=${o.id}&msg=${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link :to="{
          name: 'detailRouter', // 简化方式,路径太长时使用
          query: {
            id: o.id,
            msg: o.title
          }
        }">{{o.title}}</router-link>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        {id: '001' title='下来的时间'},
        {id: '002' title='找了家旅馆'},
        {id: '003' title='起来看高清'}
      ]
    }
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{$route.query.id}}</h4>
      <h4>消息内容: {{$route.query.msg}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    }
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

params 传参

<!-- 第一种方式 -->
<!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

<!-- 第二种方式 对象方式 -->
<router-link :to="{
    name: 'detailRouter', // 对象方式只能使用命名路由
    params: {
    id: o.id,
    title: o.title
    }
}">{{o.title}}</router-link>

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="(o) in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link :to="{
          name: 'detailRouter', // 对象方式只能使用命名路由
          params: {
            id: o.id,
            title: o.title
          }
        }">{{o.title}}</router-link>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        {id: '001' title='下来的时间'},
        {id: '002' title='找了家旅馆'},
        {id: '003' title='起来看高清'}
      ]
    }
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{$route.params.id}}</h4>
      <h4>消息内容: {{$route.params.title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    }
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

props 方式传参

  • router/index.js
<router-link
    :to="{
        name: 'detailRouter', // 对象方式只能使用命名路由
        params: {
            id: o.id,
            title: o.title,
        },
    }"
    >{{ o.title }}</router-link
>
  • Detail.vue
<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>
  • router/index.js
{
    path: 'message',
    component: Message,
    children: [
        {
            name: 'detailRouter',
            path: 'detail/:id/:title',
            component: Detail,
            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
            // props: {
            //     a: 'id',
            //     b: 'title'
            // }

            // 布尔写法 params 参数有效, 将 id title 传入 Detail
            props: true

            // 函数写法, 可以解决其他传参
            // props(route){
            //     return {
            //         id: route.query.id,
            //         title: route.query.title 
            //     }
            // }

        }
    ]
}

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }
                            
                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }
                            
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="(o) in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link :to="{
          name: 'detailRouter', // 对象方式只能使用命名路由
          params: {
            id: o.id,
            title: o.title
          }
        }">{{o.title}}</router-link>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        {id: '001' title='下来的时间'},
        {id: '002' title='找了家旅馆'},
        {id: '003' title='起来看高清'}
      ]
    }
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div class="page-header"><h2>React Router Demo</h2></div>
</template>

<script>
export default {
    name: 'Banner'
}
</script>

<style>

</style>

编程式路由导航

pushShow(o) {
    this.$router.push({
    name: "detailRouter", // 对象方式只能使用命名路由
    params: {
        id: o.id,
        title: o.title,
    },
    });
},
replaceShow(o) {
    this.$router.replace({
    name: "detailRouter", // 对象方式只能使用命名路由
    params: {
        id: o.id,
        title: o.title,
    },
    });
},
  • $router.push : 历史信息会增加记录,即增加当前路由为最后一条记录
  • $router.replace : 历史信息不会增加记录,替换历史记录中最后一条记录为当前路由
  • 不能跳转同一路由页面,否则报错

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }
                            
                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }
                            
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
    <div>
    <h2>Home组件内容</h2>
    <div>
    <ul class="nav nav-tabs">
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
        <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
    </ul>
    <router-view></router-view>
    </div>
</div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

<style>

</style>

<template>
  <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

缓存路由

<!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 如果多个改为 :include="['xx','xx']" -->
<keep-alive include="News">  
    <router-view></router-view>
</keep-alive>

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }
                            
                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }
                            
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 如果多个改为 :include="['xx','xx']" -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News'
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

路由钩子

// 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
activated(){  // News组件出现(激活)
        this.timer = setInterval(() => {
        this.opacity -= 0.01
        if (this.opacity <= 0) this.opacity = 1
    }, 16)
},
deactivated(){  // News组件消失(失活)
    clearInterval(this.timer)  // 这样不影响缓存也可停止timer
}

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }
                            
                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }
                            
                        }
                    ]
                }
            ]
        }
    ]
})

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

全局前置守卫

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
router.beforeEach((to, from, next)=>{

    if (to.path === '/home/news' || to.path === '/home/message'){
// 只有为xiaoxue时才放行 news 和 message
if (localStorage.getItem('school') === 'xiaoxue') next()
else{
    alert('学校名不正确,无权查看')
}
    }else{
        next()
    }  
})

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }
                            
                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }
                            
                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
router.beforeEach((to, from, next)=>{

    if (to.path === '/home/news' || to.path === '/home/message'){
// 只有为xiaoxue时才放行 news 和 message
if (localStorage.getItem('school') === 'xiaoxue') next()
else{
    alert('学校名不正确,无权查看')
}
    }else{
        next()
    }

    
})

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

路由元信息

  • router/index.js
meta: {
    isAuth: true
},

增加后可以在路由守卫中用来做判断

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    path: 'news',
                    component: News,
                    meta: {
                        isAuth: true
                    }
                },
                {
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true
                    },
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }

                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }

                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
router.beforeEach((to, from, next) => {

    if (to.meta.isAuth) { // meta 存储是否需要权限校验
        // 只有为xiaoxue时才放行 news 和 message
        if (localStorage.getItem('school') === 'xiaoxue') next()
        else {
            alert('学校名不正确,无权查看')
        }
    } else {
        next()
    }


})

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

全局后置守卫

// 全局后置路由守卫, 每次路由切之后被调用
router.afterEach((to, from) => {
    document.title = to.meta.title || '权限系统'
})

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About,
            meta: {
                title: '关于'
            }
        },
        {
            path: '/home',
            component: Home,
            meta: {
                title: '主页'
            },
            children: [
                {
                    path: 'news',
                    component: News,
                    meta: {
                        isAuth: true,
                        title: '新闻'
                    }
                },
                {
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true,
                        title: '消息'
                    },
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            meta: {
                                isAuth: true,
                                title: '详情'
                            },
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }

                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }

                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
router.beforeEach((to, from, next) => {
    if (to.meta.isAuth) { // meta 存储是否需要权限校验
        // 只有为xiaoxue时才放行 news 和 message
        if (localStorage.getItem('school') === 'xiaoxue') next()
        else {
            alert('学校名不正确,无权查看')
        }
    } else {
        next()
    }


})

// 全局后置路由守卫, 每次路由切之后被调用
router.afterEach((to, from) => {
    document.title = to.meta.title || '权限系统'
})

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

独享路由守卫

{
    path: 'news',
    component: News,
    meta: {
        isAuth: true,
        title: '新闻'
    },
    beforeEnter(to, from, next) {
        if (to.meta.isAuth) { // meta 存储是否需要权限校验
            // 只有为xiaoxue时才放行 news 和 message
            if (localStorage.getItem('school') === 'xiaoxue') next()
            else {
                alert('学校名不正确,无权查看')
            }
        } else {
            next()
        }
    }
},

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About,
            meta: {
                title: '关于'
            }
        },
        {
            path: '/home',
            component: Home,
            meta: {
                title: '主页'
            },
            children: [
                {
                    path: 'news',
                    component: News,
                    meta: {
                        isAuth: true,
                        title: '新闻'
                    },
                    beforeEnter(to, from, next) {
                        if (to.meta.isAuth) { // meta 存储是否需要权限校验
                            // 只有为xiaoxue时才放行 news 和 message
                            if (localStorage.getItem('school') === 'xiaoxue') next()
                            else {
                                alert('学校名不正确,无权查看')
                            }
                        } else {
                            next()
                        }
                    }
                },
                {
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true,
                        title: '消息'
                    },
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            meta: {
                                isAuth: true,
                                title: '详情'
                            },
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }

                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }

                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
// router.beforeEach((to, from, next) => {
//     if (to.meta.isAuth) { // meta 存储是否需要权限校验
//         // 只有为xiaoxue时才放行 news 和 message
//         if (localStorage.getItem('school') === 'xiaoxue') next()
//         else {
//             alert('学校名不正确,无权查看')
//         }
//     } else {
//         next()
//     }


// })

// 全局后置路由守卫, 每次路由切之后被调用
router.afterEach((to, from) => {
    document.title = to.meta.title || '权限系统'
})

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

组件内路由守卫

  • About.vue
// 通过路由规则,进入组件时调用
beforeRouteEnter (to, from, next) {
    // ...
    console.log('About-beforeRouteEnter');
            if (to.meta.isAuth) { // meta 存储是否需要权限校验
                        // 只有为xiaoxue时才放行 news 和 message
                        if (localStorage.getItem('school') === 'xiaoxue') next()
                        else {
                            alert('学校名不正确,无权查看')
                        }
                    } else {
                        next()
                    }
    next()
},

// 通过路由规则,离开组件时调用
beforeRouteLeave (to, from, next) {
    // ...
    console.log('About-beforeRouteLeave');
    next()

}

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About,
            meta: {
                isAuth: true,
                title: '关于'
            }
        },
        {
            path: '/home',
            component: Home,
            meta: {
                title: '主页'
            },
            children: [
                {
                    path: 'news',
                    component: News,
                    meta: {
                        isAuth: true,
                        title: '新闻'
                    },
                    // beforeEnter(to, from, next) {
                    //     if (to.meta.isAuth) { // meta 存储是否需要权限校验
                    //         // 只有为xiaoxue时才放行 news 和 message
                    //         if (localStorage.getItem('school') === 'xiaoxue') next()
                    //         else {
                    //             alert('学校名不正确,无权查看')
                    //         }
                    //     } else {
                    //         next()
                    //     }
                    // }
                },
                {
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true,
                        title: '消息'
                    },
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            meta: {
                                isAuth: true,
                                title: '详情'
                            },
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }

                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }

                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
// router.beforeEach((to, from, next) => {
//     if (to.meta.isAuth) { // meta 存储是否需要权限校验
//         // 只有为xiaoxue时才放行 news 和 message
//         if (localStorage.getItem('school') === 'xiaoxue') next()
//         else {
//             alert('学校名不正确,无权查看')
//         }
//     } else {
//         next()
//     }


// })

// 全局后置路由守卫, 每次路由切之后被调用
// router.afterEach((to, from) => {
//     document.title = to.meta.title || '权限系统'
// })

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About',

    // 通过路由规则,进入组件时调用
    beforeRouteEnter (to, from, next) {
        // ...
        console.log('About-beforeRouteEnter');
              if (to.meta.isAuth) { // meta 存储是否需要权限校验
                            // 只有为xiaoxue时才放行 news 和 message
                            if (localStorage.getItem('school') === 'xiaoxue') next()
                            else {
                                alert('学校名不正确,无权查看')
                            }
                        } else {
                            next()
                        }
        next()
    },

    // 通过路由规则,离开组件时调用
    beforeRouteLeave (to, from, next) {
        // ...
        console.log('About-beforeRouteLeave');
        next()

    }
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

路由模式

  • history: url 参数 不带 #
  • hash: url 参数 带 #
const router = new VueRouter({
    mode: 'history',  // 兼容性 hash 模式好些, 否则看后端是否有 history中间件 或用 nginx代理解决
    ...
})

main.js
router/index.js
App.vue
pages/About.vue
/pages/Home/index.vue
/pages/Home/News.vue
/pages/Home/Message/index.vue
/pages/Home/Message/Detail.vue
components/Banner.vue

import 'bootstrap/dist/css/bootstrap.min.css'

import Vue from "vue";
import App from './App.vue'
import VueRouter from "vue-router";

import router from './router'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

import VueRouter from "vue-router";

import About from '../pages/About.vue'
import Home from '../pages/Home'
import News from '../pages/Home/News.vue'
import Message from '../pages/Home/Message'
import Detail from '../pages/Home/Message/Detail.vue'

const router = new VueRouter({
    mode: 'history',  // 兼容性 hash 模式好些, 否则看后端是否有 history中间件 或用 nginx代理解决
    routes: [
        {
            path: '/about',
            component: About,
            meta: {
                isAuth: true,
                title: '关于'
            }
        },
        {
            path: '/home',
            component: Home,
            meta: {
                title: '主页'
            },
            children: [
                {
                    path: 'news',
                    component: News,
                    meta: {
                        isAuth: true,
                        title: '新闻'
                    },
                    // beforeEnter(to, from, next) {
                    //     if (to.meta.isAuth) { // meta 存储是否需要权限校验
                    //         // 只有为xiaoxue时才放行 news 和 message
                    //         if (localStorage.getItem('school') === 'xiaoxue') next()
                    //         else {
                    //             alert('学校名不正确,无权查看')
                    //         }
                    //     } else {
                    //         next()
                    //     }
                    // }
                },
                {
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true,
                        title: '消息'
                    },
                    children: [
                        {
                            name: 'detailRouter',
                            path: 'detail/:id/:title',
                            component: Detail,
                            meta: {
                                isAuth: true,
                                title: '详情'
                            },
                            // 对象写法,把 id title 命名为 a 和 b 传入 Detail 属性去, params参数有效
                            // props: {
                            //     a: 'id',
                            //     b: 'title'
                            // }

                            // 布尔写法 params 参数有效, 将 id title 传入 Detail
                            props: true

                            // 函数写法, 可以解决其他传参
                            // props(route){
                            //     return {
                            //         id: route.query.id,
                            //         title: route.query.title 
                            //     }
                            // }

                        }
                    ]
                }
            ]
        }
    ]
})

// 全局前置路由守卫 每次路由切换之前调用和初始化时被调用
// router.beforeEach((to, from, next) => {
//     if (to.meta.isAuth) { // meta 存储是否需要权限校验
//         // 只有为xiaoxue时才放行 news 和 message
//         if (localStorage.getItem('school') === 'xiaoxue') next()
//         else {
//             alert('学校名不正确,无权查看')
//         }
//     } else {
//         next()
//     }


// })

// 全局后置路由守卫, 每次路由切之后被调用
// router.afterEach((to, from) => {
//     document.title = to.meta.title || '权限系统'
// })

export default router

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <Banner />
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 开启replace 模式 下一记录会替代当前记录 -->
          <router-link replace class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link replace class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template> 

<script>
import Banner from './components/Banner.vue'
export default {
  name: "App",
  components: {Banner}
};
</script>

<template>
    <h3>我是About的内容</h3>
</template>

<script>
export default {
    name: 'About',

    // 通过路由规则,进入组件时调用
    beforeRouteEnter (to, from, next) {
        // ...
        console.log('About-beforeRouteEnter');
              if (to.meta.isAuth) { // meta 存储是否需要权限校验
                            // 只有为xiaoxue时才放行 news 和 message
                            if (localStorage.getItem('school') === 'xiaoxue') next()
                            else {
                                alert('学校名不正确,无权查看')
                            }
                        } else {
                            next()
                        }
        next()
    },

    // 通过路由规则,离开组件时调用
    beforeRouteLeave (to, from, next) {
        // ...
        console.log('About-beforeRouteLeave');
        next()

    }
}
</script>

<style>

</style>

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/news"
            >News</router-link
          >
        </li>
        <li>
          <router-link
            class="list-group-item"
            active-class="active"
            to="/home/message"
            >Message</router-link
          >
        </li>
      </ul>
      <!-- include确定要缓存哪个路由 如果不填则缓存所有,名称应为组件名 -->
      <keep-alive include="News">  
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  beforeDestroy(){
      console.log('News即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <ul>
      <li :style="{opacity}">欢迎学习</li>
        <li>news001 <input type="text" /></li>
        <li>news002 <input type="text" /></li>
        <li>news003 <input type="text" /></li>
    </ul>
</template>

<script>
export default {
    name: 'News',
    data() {
        return {
            opacity: 1
        }
    },
    // mounted() {
    //     this.timer = setInterval(() => {
    //         this.opacity -= 0.01
    //         if (this.opacity <= 0) this.opacity = 1
    //     }, 16)
    // },
    // beforeDestroy() { 
    //     clearInterval(this.timer)
    // }
    // 路由组件2个钩子函数, 解决被缓存不能销毁timer问题
    activated(){  // News组件出现(激活)
            this.timer = setInterval(() => {
            this.opacity -= 0.01
            if (this.opacity <= 0) this.opacity = 1
        }, 16)
    },
    deactivated(){  // News组件消失(失活)
        clearInterval(this.timer)  // 这样不影响缓存也可停止timer
    }
}
</script>

<style>

</style>

<template>
  <div>
    <ul>
      <li v-for="o in messageList" :key="o.id">
        <!-- 第一种方式 -->
        <!-- <router-link :to="`/home/message/detail/${o.id}/${o.title}`">{{o.title}}</router-link> -->

        <!-- 第二种方式 对象方式 -->
        <router-link
          :to="{
            name: 'detailRouter', // 对象方式只能使用命名路由
            params: {
              id: o.id,
              title: o.title,
            },
          }"
          >{{ o.title }}</router-link
        >
        <button @click="pushShow(o)">push查看</button>
        <button @click="replaceShow(o)">replace查看</button>
      </li>
    </ul>
    <hr />
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "News",
  data() {
    return {
      messageList: [
        { id: "001" title="下来的时间" },
        { id: "002" title="找了家旅馆" },
        { id: "003" title="起来看高清" },
      ],
    };
  },
  methods: {
    pushShow(o) {
      this.$router.push({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
    replaceShow(o) {
      this.$router.replace({
        name: "detailRouter", // 对象方式只能使用命名路由
        params: {
          id: o.id,
          title: o.title,
        },
      });
    },
  },
  beforeDestroy(){
      console.log('Message即将销毁');
  }
};
</script>

<style>
</style>

<template>
  <div>
      <h4>消息ID: {{id}}</h4>
      <h4>消息内容: {{title}} </h4>
  </div>
</template>

<script>
export default {
    name: 'Detail',
    mounted() {
        console.log('route', this.$route);
    },
    props: ['id', 'title']
}
</script>

<style>

</style>

<template>
  <div>
    <div class="page-header"><h2>React Router Demo</h2></div>
    <button @click="back">后退</button> &nbsp;
    <button @click="forward">前进</button> <br>
    <label>测试前进后退几步</label><input type="number" v-model.number="goNum">
    <button @click="test">GO</button>
  </div>
</template>

<script>
export default {
  name: "Banner",
  data() {
      return {
          goNum: 0
      }
  },
  methods: {
      back(){
          this.$router.back()
      },
      forward(){
          this.$router.forward()

      },
      test(){
          this.$router.go(this.goNum)
      }
  },
};
</script>

<style>
</style>

results matching ""

    No results matching ""