vue-06-路由

SPA 单页面应用开发(重点)

SPA 的优势:因为是把页面都合并到一起,所以路由切换时,实际上是在当前页面切换显示,所以不会因网络问题造成页面卡顿、白屏。

SPA 的不足:合并后的文件体积特别的大,所以第一次打开页面时,比较慢。(解决方法是用按需加载)

router 路由(重点)

vue-router 配置基于 vue 的单页面应用(SPA)

首先安装路由模块

    npm install vue-router -S
    或者
    yarn add vue-router

在 src 目录下,新建 router.js 文件,在里面写入如下代码:

    import Vue from 'vue' 
    import VueRouter from 'vue-router';
// 导入一些页面级别的组件(这些组件需要自己创建)
    import Index from './pages/Index.vue'
    import Goods from './pages/Goods.vue'
    import Buycar from './pages/Buycar.vue'
    import Mine from './pages/Mine.vue'
// 将vue-router注册到全局,这样每一个组件都可以使用router-link和router-view组件了
Vue.use(VueRouter);

// 定义路由规则(例如:当用户访问了/goods这个页面时,router-view标签渲染Goods组件)
  var routes = [
        { path: '/', component: Index },
        { path: '/goods', component: Goods },
        { path: '/buycar', component: Buycar },
        { path: '/mine', component: Mine },
    ]
// 创建路由实例
    var router = new VueRouter({ routes, mode:'history' });
// 导出路由对象
   export default router

在 src 目录下,找到 main.js 文件,在其中修改:

// 导入路由配置文件
    import router from './router.js'
    new Vue({
        router,     // 让每个vue组件中可以使用 $route 和 $router 对象
        render: h => h(App),
    }).$mount('#app')
  • router-link 组件:渲染后为a标签,点击这个标签后,浏览器地址栏会发生变化。
  • router-view 组件:浏览器地址栏每次发生变化时,会根据路由规则,把匹配到的组件显示到router-view标签上。

在 src/app.vue 文件中

    <router-view></router-view>

在 src/components/footer.vue 文件中

  <router-link to="/">首页</router-link>
    <router-link to="/goods">商品</router-link>
    <router-link to="/buycar">购物车</router-link>
    <router-link to="/mine">我的</router-link>

router-link组件识别路由后会自动添加style样式


    .router-link-exact-active{
        color: green !important;
    }

也可以自己定义样式

    <router-link to="/hi" active-class="xyz" exact-active-class="abc">hi</router-link>

通过tag属性,可以将a标签解析成其他标签。

   <router-link to="/hi" tag="li">hi</router-link>

路由模式:mode

  • history

  • hash(默认值。哈希、网址含#)

  • abstract(抽象、网址不变)

    var router = new VueRouter({ routes, mode:‘history’ });

用的较多的是history,每次页面切换的时候,浏览器地址栏看起来就像是传统的网站页面一样。

慎用 abstract,首次打开页面时 router-view 无法匹配 path=’/’,

所以可以在 app.vue 的 mounted 中执行 this.$router.push(’/’)

动态路由匹配

在浏览器中访问一个网址时,通常这个网址是有语义的,比如访问:

http://www.abc.com/news/102/

  • news 表示新闻
  • 102 表示新闻id

那么怎么配置这种路由呢?

路由规则页面

    const routes = [
        {
            path : '/news/:id',
            component: {
                // 可以直接创建组件,使用render渲染,不能使用template渲染。
                render(createElement){
                    return createElement('div', 'abc')
                },
                created(){
                    // 在js中接收浏览器地址栏中id对应的数据
                    console.log(this.$route.params)
                }
            }
        }
    ]

某组件的html页面,由这个页跳转到NewsComponent页面

    <router-link to="/news/102">点我跳转页面</router-link>

路由参数

路由中传递数据除了刚才的params外,还可以使用query数据。

路由规则页面


```javascript
    const routes = [
        {
            path : '/news',
            component : NewsComponent
        }
    ]


某组件的html页面,由这个页跳转到NewsComponent页面

```javascript
    <router-link to="/news?id=102">点我跳转页面</router-link>

NewsComponent组件的js部分

// 在js中接收浏览器地址栏中id对应的数据
this.$route.query.id

嵌套路由规则

移动端项目不建议使用嵌套的路由规则,如果必须要用到嵌套路由,通常也不会超过2层。

比如项目中,一级导航有首页和用户,用户页面又有二级导航登录、注册两个页面。

路由规则

    const routes = [
        {
            path: '/',
            component: IndexComponent
        },
        {
            path: '/user',
            component: UserComponent,
            children: [
                { path: '/user/register', component: RegisterComponent },
                { path: '/user/login', component: LoginComponent }
            ]
        }
    ]

children描述的是UserComponent组件内的路由规则,当根据路由规则匹配出对应的组件后,这个组件在UserComponent组件内,找到router-view渲染。

UserComponent组件

点击嵌套路由的链接时,只会在嵌套路由组件出口显示对应的组件。

    <router-link to="/user/register">注册</router-link>
    <router-link to="/user/login">登录</router-link>
    <router-view></router-view>

声明式导航、编程式导航

  • 声明式导航:html中的router-link标签实现页面跳转
  • 编程式导航:通过js代码实现页面跳转

向history中添加记录

    <router-link to="/">

    this.$router.push("/")
    this.$router.push({ path: '/html2', query:{a:1,b:2}})

不会向history中添加新纪录

    <router-link to="/" replace>

    this.$router.replace("/")

历史记录中前进及后退

    this.$router.go(1)

路由对象下有2个常用的属性,一个是route,一个是router:

  • route 这里存储的是属性,比如 route.query、$route.params
  • router 这里存储的是方法,比如 router.push()、router.replace()、router.go() 编程式导航方法都存到了这里

命名路由

给定义的路由规则起个名字,页面跳转时,使用该名字完成路由跳转。

路由规则

    const routes = [
        {
            name: 'abc',
            path: '/html1/:a/:b',
            component: a
        }
    ]

页面跳转

   <router-link :to="{name:'abc',params:{a:1,b:2}}">html1/1/2</router-link>
    <router-view></router-view>
    
    this.$router.push({ name: 'abc', params:{a:1,b:2}})

命名视图

一个页面中,有多个路由出口,每个router-view渲染哪个组件呢?

路由规则

    const routes = [
        { path: '/a', components: {one:a, two:b} },
        { path: '/b', components: {one:c} }
    ]

html部分

    <router-link to="/a">a</router-link>
    <router-link to="/b">b</router-link> 
    
    <router-view name="one"></router-view>
    <router-view name="two"></router-view>

访问a时,one渲染a组件,two渲染b组件。访问b时,one渲染c组件,two不渲染组件,节点移除。

重定向

当我们访问a时,自动跳转到了b。

   const routes = [
        { path: '/a', redirect: '/b' }
    ]

别名

当我们访问c时,url不变,但实际访问的是a。

    const routes = [
        { path: '/a', alias: '/c', component:a  }
    ]

守卫

路由中的守卫就是路由中的生命周期钩子函数。

全局守卫

只要发生页面跳转,无论是什么页面跳转,都会执行该钩子函数。

    const router = new VueRouter({routes, mode:"history"})
    
    router.beforeEach((to, from, next) => {
        // to 表示到哪里去
        // from 表示从哪里来
        console.log(to, from);
        // next 表示执行跳转
        next();
    })

路由守卫

在路由规则中,定义该钩子函数,表示渲染该组件之前执行守卫验证,如果有next则把组件渲染出来。

   const routes = [
        {
            path: '/foo',
            component: Foo,
            beforeEnter: (to, from, next) => {
                console.log(to, from);
                next();
            }
        }
    ]

组件守卫

在组件中定义该钩子函数

    {
        template: `...`,
        beforeRouteEnter (to, from, next) {
            // 不能获取组件实例 this 因为当守卫执行前,组件实例还没被创建
            // 组件被渲染之前
            console.log('beforeRouteEnter')
            next()
        }, 
        beforeRouteUpdate (to, from, next) {
            // 在当前路由改变,但是该组件被复用时调用
            // 修改路由数据前
            console.log('beforeRouteUpdate')
            next()
        }, 
        beforeRouteLeave (to, from, next) {
            // 导航离开该组件的对应路由时调用
            // 组件被移除前
            console.log('beforeRouteLeave')
            next()
        }
    }

懒加载

    { 
        path: '/buycar', 
        component: ()=>import('./pages/Buycar.vue') 
    },
    { 
        path: '/mine', 
        component: resolve=>require(['./pages/Mine.vue'], resolve)
    },

上面的两种写法都可以实现懒加载 import 属于 es6 的方法,而 require 属于 webpack 的方法。需要 build 后才能在 network 中看到效果。

发布了60 篇原创文章 · 获赞 19 · 访问量 5899

猜你喜欢

转载自blog.csdn.net/lff18277233091/article/details/104217909