Vue-router(Vue路由总结)

Vue Router

Vue Router 是 Vue.js 官方的路由管理器。用 Vue.js + Vue Router 创建单页应用。

SPA的理解

  1. 单页Web应用(single page web application,SPA)

  2. 整个应用只有一个完整的页面,页面变化都是在这一个页面更新的

  3. 点击链接时, 不会刷新整个页面,只会做页面的局部更新,也会更新浏览历史(地址)

  4. 点击链接也不会向服务器发请求,数据都需要通过ajax发送请求, 并在前端异步展现

简述前端路由的原理

  • 点击链接不会刷新整个页面 --> 给 a 标签绑定点击事件,阻止其默认行为
  • 会更新浏览历史(地址) --> 调用 history.push(path),就可以更新了
  • 会局部更新 --> 内部会监听浏览历史的变化(history.listen(listener)),一旦发生变化就会遍历路由的所有配置,看当前路径(浏览地址)是否匹配上路由路径(path),匹配上就加载 component

使用

使用 Vue.js ,可以通过组合组件来组成应用程序,当把 Vue Router 添加进来,需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。

用路由的3步

  1. 定义路由组件

  2. 注册路由

  3. 使用路由

<router-link> 用来路由链接导航

<router-view> 用来显示当前路由组件

安装 路由插件

npm i vue-router

当安装插件之后, 就会全局注册两个组件:router-link,router-view,还会给原型上添加一些属性

1.定义路由组件

在src下创建一个文件router,在创建一个文件夹来定义路由

Vue.use(VueRouter);
// 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
    // 定义路由配置
    routes: [
        {
            path: "/home", // 路由路径
            component: Home, // 路由组件
            // 子路由
            children: [
                {
                    path: "/home/message", // 完整写法
                    component: Message,
                    children: [
                        {
                            name:"Detail",// 加上name属性,就叫做命名路由
                            path: "detail/:id",// 动态路由配置,能匹配多个路径
                          // path: "detail/:id?", // ? 表示params 参数是可选的
                            component: Detail,
                            props(route) {
                                return {
                                    ...route.params,
                                    ...route.query
                                }
                            }
                        }
                    ]
                },
                {
                    path: "news", // 简写
                    component: News
                }
            ]
        },
        {
            path: "/about",
            component: About
        },
        {
            // 当路径是/时,会切换到/home
            path: "/",
            redirect: "/home" //重定向
        }

    ]
})
export default router;

2.注册路由

new Vue({
    render: h => h(App),
    router, // 应用路由器
}).$mount('#app')

3.使用路由

<ul class="nav nav-pills nav-stacked">
          <!-- 
                router-link 路由连接导航 
                  - 切换地址

                - 当你点击选中 router-link 时,会添加两个类名:router-link-exact-active router-link-active
                - active-class 可以修改类名 router-link-active(active-class:默认是router-link-active)

                router-view 显示对应的路由组件
                  - 内部会根据当前的地址,遍历路由中的routes配置,找到相对应的路由组件进行显示
          -->
          <li>
            <router-link to="/about" active-class="active">About</router-link>
          </li>
          <li>
            <router-link to="/home">Home</router-link>
          </li>
        </ul>
		<!-- 显示对应的路由组件 -->
        <router-view></router-view>

路由传参的方式

 <!-- 
        路由传参的方式:
          1. params参数
            (1)路由配置:
              {
                path: '/xxx/:id', // :id 动态路由匹配,能匹配多个地址
                component: Xxx
              }

            跳转路由路径
              <router-link to="/xxx/1">xxx</router-link>

            子路由接受 :id 的参数
              this.$route.params.id 

            当 :id 的参数发生变化时,需要使用watch监视属性的变化,来更新数据 
              watch: {
                $route: {
                  handler(newVal) {
                    const id = +newVal.params.id;
                    this.message = this.messages.find((message) => message.id === id);
                  },
                  // 正常情况下,watch只有值发生变化的时候才会调用
                  // 一上来会调用一次
                  immediate: true,
                },
              },
			(2)路由配置
           		{
            	name: "Search",
            	// ? 表示params 参数是可选的
            	path: "/search/:searchText?",
            	component: Search,
         		}
         		this.$router.push({ name: '必须使用命名路由', params: {} })
        可选参数:需要 params 就加上 params 选项,不需要 params 就去掉

          2. query
            路由链接设置
              <router-link to="/xxx?name=jack&age=18">xxx</router-link>
            子组件获取
              this.$route.query 

          3. props
            将原先的params参数和query参数以props方式传递给组件
              子组件配置
                props(route) {
                  return {
                    ...route.params,
                    ...route.query,
                  };
                },    
              子组件声明接受
                props: ['id', 'name', 'age']
              子组件使用
                this.xxx 
         
         4. 命名路由
            - 路由取个名字
              {
                name: "Detail", // 命名路由
                path: "detail/:id",
                component: Detail,
              }
            - 路由路径
              <router-link
                :to="{
                  name: 'Detail', // 跳转哪个命名路由
                  params: {
                    id: message.id,
                  },
                  query: {
                    name: 'jack',
                    age: 18,
                  },
                }"
              >xxx</router-link>

           5. 给相同层级的路由组件一起传递公共参数
            传参
              <router-view key="value"></router-view>
            路由组件声明接受
              props: ['key']
            路由组件使用
              this.xxx   
           6. meta
 			 路由配置
   				 meta: { key: value }  // 当这个组件加载显示时,meta中的参数会传到$route中,组件中的meta只属于当前组件,(可以用在控制组件的显示隐藏)
  			使用 meta 参数
   				 this.$route.meta.xxx  
    -->
	<ul>
      <li v-for="message in messages" :key="message.id">
        <!-- <router-link :to="`/home/message/detail/${message.id}?name=suzy&age=25`">{{message.content}}</router-link> -->
        <router-link
          :to="{
            name: 'Detail', // 跳转哪个命名路由
            params:{
                id:message.id,
            },
            query:{
                name:'jack',
                age:18,
            }
            }"
        >{{ message.content }}</router-link>
      </li>
    </ul>
    <router-view suzy="iu"></router-view>


动态路由匹配

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

嵌套路由

需要在 VueRouter 的参数中使用 children 配置

Vue.use(VueRouter);
// 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
    // 定义路由配置
    routes: [
        {
            path: "/home", // 路由路径
            component: Home, // 路由组件
            // 子路由
            children: [
                {
                    path: "/home/message", // 完整写法
                    component: Message,
                    children: [
                        {
                            name:"Detail",// 加上name属性,就叫做命名路由
                            path: "detail/:id",
                            component: Detail,
                            props(route) {
                                return {
                                    ...route.params,
                                    ...route.query
                                }
                            }
                        }
                    ]
                },
            ]
        },
    ]
})

命名路由

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',// 加上name属性,就叫做命名路由
      component: User
    }
  ]
})

要链接到一个命名路由,可以给 router-linkto 属性传一个对象:

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

这跟代码调用 router.push() 是一回事:

router.push({ name: 'user', params: { userId: 123 }})

这两种方式都会把路由导航到 /user/123 路径。

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口,如果 router-view 没有设置名字,那么默认为 default

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

重定向

重定向也是通过 routes 配置来完成

const router = new VueRouter({
    // 定义路由配置
    routes: [
        {
            path: "/home", // 路由路径
            component: Home, // 路由组件
            // 子路由
    	}
        {
            // 当路径是/时,会切换到/home
            path: "/",
            redirect: "/home" //重定向
        }

    ]
})

编程式导航

  1. this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)

  2. this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)

  3. this.$router.back(): 请求(返回)上一个记录路由

4)this.$router.forward():请求(返回)下一个记录路由

  1. this.$router.go(-1): 请求(返回)上一个记录路由

  2. this.$router.go(1): 请求下一个记录路由

  /*
        $route 
          用来获取路由参数(params、query)和路由路径(path)
        $router
          用来编程式导航(push、replace、go、back、forward)

        两种路由跳转的方式:
          1. 路由链接导航
            router-link
          2. 编程式导航
            this.$router.push/replace()

            如果点击链接或者按钮只需要进行路由跳转,那么就用第一种方式
              例子:导航链接
            如果点击链接或者按钮需要做一些其他事,再进行路由跳转,那么就用第二种方式
              例子:登录按钮、修改按钮
      */

例如

 methods: {
    push(id) {
      // 编程式导航
      //console.log(this);
      this.$router.push(`/home/message/detail/${id}?name=suzy&age=25`);
    },
    replace(id) {
      this.$router.replace(`/home/message/detail/${id}?name=suzy&age=25`);
    }
  }
<button @click="push(message.id)">push</button>
<button @click="replace(message.id)">replace</button>
<button @click="$router.back()">goBack</button>
<button @click="$router.forward()">goFoward</button>

缓存路由组件

  1. 默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的

  2. 如果可以缓存路由组件对象, 可以提高用户体验

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

<keep-alive include="Home,About">
        <!-- exclude="Home" 缓存排除Home -->
        <!-- <keep-alive exclude="Home"> -->
       <router-view></router-view>
</keep-alive>

当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行。只有使用 <keep-alive> 才会有这两个钩子函数。如果需要使用<keep-alive>的组件,及时更新数据需要在两个钩子函数中操作

activated:被 keep-alive 缓存的组件激活时调用。

deactivated:被 keep-alive 缓存的组件停用时调用。

跳转路由链接的方式

  • 路由链接导航 router-link

  • 编程式导航 this.$router.push/replace/back/forward/go()

  • 用法区别:

    • 如果只需要跳转链接,用路由链接导航
    • 如果需要先做一些其他事(发送请求等),再跳转链接,用编程式导航
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值