1.vue路由实现原理

路由:代码中的一个对象,对项目中的页面/数据的请求做分发处理

路由作用:1,请求的分发,拦截,重定向 2,实现页面局部刷新

设置跳转链接a标签,设置它的href是hash值。a标签的访问地址如果是以#开头,则页面不会刷新,以#开头的路径地址叫做hash值,哈希值。以达到局部刷新的作用。然后hash值访问时会把hash值拼接到url路径后,并触发hashchange事件。

<body>
    <h1>
        <!-- a标签的访问地址如果是以#开头,则页面不会刷新,以#开头的路径地址叫做hash值,哈希值 -->
        <a href="#/main">主页</a>
        <a href="#/login">登录</a>
        <a href="#/user">个人</a>
    </h1>
    <h2 id="h2"></h2>
    <script>
        // 哈希值访问时会把hash值拼接到url路径后,并触发hashchange事件
        window.onhashchange = function() {
            console.log(location.hash);
            if (location.hash == "#/main") {
                h2.innerText = "这是主页的内容,此处省略600行"
            }
            if (location.hash == "#/login") {
                h2.innerText = "这是登录页的内容,此处省略100行"
            }
            if (location.hash == "#/user") {
                h2.innerText = "欢迎查看个人中心"
            }
        }
    </script>
</body>
  • hash值访问时会把hash值拼接到url路径后。比如我点击主页a标签跳转到该页面,它所对应的hash值时/main,在你点开的网页url地址后边会把这个/main拼接到没点击主页之前的url路径中。

2.vue-router插件实现路由

2.1 插件实现路由的步骤
  • 在vue之后导入vue-router路由插件(插件的导入顺序一定不能乱)

  • 在根组件模板中,添加路由跳转标签

  • 在全局作用域,创建一些组件,路由跳转页面对应的组件,并记录组件的返回值

  • 创建路由对象VueRouter,配置路由信息

    • 在路由对象中,routes数组中配置路由信息,一个对象对应一个路由信息
    • 在routes数组中path表示路由地址,在路由对象中省略#号
    • component表示组件,值不是组件名,是组件构造函数
  • 把路由对象加入vue根组件对象中

  • 在根组件模板合适的位置,添加路由出口:组件渲染的位置

<body>
    <!-- 第一步:在vue之后导入vue-router路由插件 -->
    <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <!-- 第二步:在根组件模板中,添加路由跳转标签 -->
        <h1>
            <a href="#/main">主页</a>
            <a href="#/login">登录</a>
            <a href="#/user">个人</a>
        </h1>
        <!-- 第六步:在根组件模板合适的位置,添加路由出口:组件渲染的位置 -->
        <router-view></router-view>
    </div>
    <script>
        // 第三步:在全布局作用域,创建一些组件,路由跳转页面对应的组件
        var MainCom = Vue.component("mainCom", {
            template: "<h2>这是主页</h2>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: "<h2>这是登录页</h2>"
        })
        var UserCom = Vue.component("userCom", {
            template: "<h2>这是个人页</h2>"
        })

        // 组件创建后返回值时组件的构造函数
        console.log(MainCom, LoginCom, new UserCom());


        // 第四步:创建路由对象,配置路由信息
        const router = new VueRouter({
            // 在routes数组中配置路由信息,一个对象对应一个路由信息
            routes: [
                // path表示路由地址,在路由对象中省略#号;component表示组件,值不是组件名,是组件构造函数
                {
                    path: "/main",
                    component: MainCom

                }, {
                    path: "/login",
                    component: LoginCom

                }, {
                    path: "/user",
                    component: UserCom

                }
            ]
        })
        new Vue({
            el: '#myApp',
            // 第五步:把路由对象加入vue根组件对象中
            router
        })
    </script>
</body>

3.vue路由跳转的两种方式

3.1 router-link标签跳转
  • vue路由封装了组件 router-link,用于替代a标签,这个标签的to属性设置跳转路径,不需要加#,渲染时会自动不上#
  • router-link标签选中时会自动添加这个router-link-exact-active class值,可以方便的实现标记,路由跳转时,class自动切换
  • router-link标签会渲染成a标签
    <style>
        .router-link-exact-active {
            color: red;
        }
    </style>
<body>
    <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>

        <router-view></router-view>
    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h2>这是主页</h2>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: "<h2>这是登录页</h2>"
        })
        var UserCom = Vue.component("userCom", {
            template: "<h2>这是个人页</h2>"
        })

        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }]
        })
        new Vue({
            el: '#myApp',
            data: {

            },
            methods: {

            },
            router
        })
    </script>
</body>
3.2 编导式导航跳转

编导式导航跳转:在js中使用router调用push函数实现路由跳转

<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <router-view></router-view>
    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h2>这是主页</h2>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: "<h2>这是登录页<button @click='change'>去主页</button></h2>",
            methods: {
                change() {
                    router.push("/main")
                }
            }
        })
        var UserCom = Vue.component("userCom", {
            template: "<h2>这是个人页</h2>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }]
        })
        new Vue({
            el: '#myApp',
            data: {

            },
            methods: {

            },
            router
        })
    </script>

4.vue路由重定向

在路由对象中的routes数组中的对象添加redirect字段,表示路由重定向,当首次打开页面时,默认的hash路径是/,此时路由重定向会把hash路径修改为/main,达到默认访问/main的目的

<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <router-view></router-view>
    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: "<h1>这是登录页<button @click='change'>去主页</button></h1>",
            methods: {
                change() {
                    router.push("/main")
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }]
        })
        new Vue({
            el: '#myApp',
            data: {

            },
            methods: {

            },
            router
        })
    </script>

5.vue路由监听

  • 路由监听需要在根组件中监听,不能在子组件(登录页等)中
  • 路由监听要监听$route字段,而不是router路由配置对象
  • 路由监听可以知道路由从哪一页跳转到了哪一页
    <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <router-view></router-view>
    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: "<h1>这是登录页<button @click='change'>去主页</button></h1>",
            methods: {
                change() {
                    router.push("/main")
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }]
        })
        new Vue({
            el: '#myApp',

            router,
            watch: {
                $route(newValue, oldValue) {
                    console.log(newValue.path, oldValue.path);
                }
            },
            mounted() {
                console.log(1, router)
                console.log(2, this.$router)
                console.log(3, this.$route)
            },
        })
    </script>

6. vue路由keepalive与动画

  • 路由跳转时,会销毁重建组件,所以组件数据状态会重置,如果不想组件重置,可在路由出口添加keep-alive
  • 如果路由切换时,还需要添加动画效果,那再加一层transition即可,然后通过css设置入场出场样式
  • transition需要写在keep-alive外层
        <transition>
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </transition>

7.vue路由传值

7.1 url拼接传值

步骤:

  • 在路由跳转前的组件内,给路由路径后添加?键值对拼接数据传值
  • 在路由跳转后的组件内,使用$route.query接收数据
<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <transition>
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </transition>


    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页,用户名:{{$route.query.name}}</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: `
            <h1>
              这是登录页,账号:<input v-model="msg">
              <router-link :to="'/main?name='+msg">登录去主页</router-link>
              </h1>`,
            data() {
                return {
                    msg: ""
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }]
        })
        new Vue({
            el: '#myApp',

            router,

            watch: {
                $route(newValue, oldValue) {
                    console.log(newValue, oldValue);
                }
            },
        })
    </script>
7.2 动态url/友好url传值

步骤:

  • 在路由配置对象中,添加动态路由配置
  • 在路由跳转前的组件内,给路由路径后添加/拼接数据传值
  • 在路由跳转后的组件内,使用$route.params接收数据

动态url或友好url就是url路径后的/:结构

  <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <transition>
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </transition>


    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页,用户名:{{$route.params.password}}</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: `
            <h1>
              这是登录页,账号:<input v-model="msg">
              <router-link :to="'/main/'+msg">登录去主页</router-link>
              </h1>`,
            data() {
                return {
                    msg: ""
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }, {
                path: "/main/:password",
                component: MainCom
            }]
        })
        new Vue({
            el: '#myApp',

            router
        })
    </script>

7.3 query对象传值

步骤:

  • 在路由跳转前的组件内,给to属性动态绑定一个对象,path设置路径,query设置字段
  • 在路由跳转后的组件内,使用$route.query接收数据
<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <transition>
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </transition>


    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页,用户名:{{$route.query.name}}</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: `
            <h1>
              这是登录页,账号:<input v-model="msg">
              <router-link :to="obj">登录去主页</router-link>
              </h1>`,
            data() {
                return {
                    msg: ""
                }
            },
            computed: {
                obj() {
                    return {
                        path: "/main",
                        query: {
                            name: this.msg
                        }
                    }
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }, {
                path: "/main/:password",
                component: MainCom
            }]
        })
        new Vue({
            el: '#myApp',

            router
        })
    </script>

7.4 命名路由传值

在路由配置信息中routes数组中的对象中添加name字段,name设置路由名,用于路由跳转和传值,设置了name属性的路由叫命名路由

步骤:

  • 在路由配置信息中,添加name字段设置为命名路由
  • 在路由跳转前的组件内,给to属性动态绑定一个对象,name设置路径,params设置字段
  • 在路由跳转后的组件内,使用$route.params接收数据
<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    <script src="./vue-router.js"></script>
    <div id='myApp'>
        <router-link to="/main">主页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/user">个人</router-link>
        <transition>
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </transition>


    </div>
    <script>
        var MainCom = Vue.component("mainCom", {
            template: "<h1>这是主页,用户名:{{$route.params.name}}</h1>"
        })
        var LoginCom = Vue.component("loginCom", {
            template: `
            <h1>
              这是登录页,账号:<input v-model="msg">
              <router-link :to="obj">登录去主页</router-link>
              </h1>`,
            data() {
                return {
                    msg: ""
                }
            },
            computed: {
                obj() {
                    return {
                        name: "yu",
                        params: {
                            name: this.msg
                        }
                    }
                }
            },
        })
        var UserCom = Vue.component("userCom", {
            template: "<h1>这是个人页</h1>"
        })
        const router = new VueRouter({
            routes: [{
                path: "/main",
                component: MainCom,
                name: "yu"
            }, {
                path: "/login",
                component: LoginCom
            }, {
                path: "/user",
                component: UserCom
            }, {
                path: "/",
                redirect: "/main"
            }, {
                path: "/main/:password",
                component: MainCom
            }]
        })
        new Vue({
            el: '#myApp',

            router
        })
    </script>

Logo

前往低代码交流专区

更多推荐