vue 路由基础

177 阅读2分钟

前言

路由就是通过不同的url地址展示不同的页面或者内容; vue 路由就是把所有内容的url地址统一管理中间站,然后根据不同的模块去跳转

1.router-link

  • 类似a标签,可以在不重新加载页面的情况下更改 URL
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-router@4"></script>

<div id="app">
  <h1>Hello world!</h1>
  <p>
    <!--使用 router-link 组件进行导航 -->
    <!--通过传递 `to` 来指定链接 -->
    <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>

  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

2.router-view

  • router-view 将显示与 url 对应的组件

// 1.定义路由组件
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }


// 2.定义多个路由
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3.创建路由实例和routes配置
const router = VueRouter.createRouter({
  // 4. 内部提供了 history 模式的实现。使用hash模式
  history: VueRouter.createWebHashHistory(),
  routes, // `routes: routes` 的缩写
})

// 5.创建挂载实例
const app = Vue.createApp({})
app.use(router); // 可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由
app.mount('#app')
// Home.vue
export default {
  computed: {
    username() {
      // 获取params的值
      return this.$route.params.username
    },
  },
  methods: {
    goTest() {
      if (isAuthenticated) {
        this.$router.push('/dashboard')
      } else {
        this.$router.push('/login')
      }
    },
  },
}

3.嵌套路由

  • 以/ 开头的嵌套路径将被视为根路径。允许利用组件嵌套,而不必使用嵌套的 URL
const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome },

        // ...其他子路由
      ]
    }
  ]
})

4.动态路由

  • 动态路由应用场景就是封装好的一个组件复用,然后匹配多个路径
  • 带参数的动态路由匹配
const User = {
  template: '<div>User</div>',
}

// 这些都会传递给 `createRouter`
const routes = [
  // 动态段以冒号开始
  { path: '/users/:id', component: User },
]

// 读取路由里:id 
const User = {
  template: '<div>User {{ $route.params.id }}</div>',
}


// 匹配模式   =〉匹配路径   =〉$route.params
/users/:username  =〉 /users/eduardo => { username: 'eduardo' }

/users/:username/posts/:postId =〉/users/eduardo/posts/123 =>{ username: 'eduardo', postId: '123' }

  • 响应路由参数的变化
const User = {
  template: '...',
  created() {
    this.$watch(
      () => this.$route.params,
      (toParams, previousParams) => {
        // 对路由变化做出响应...
      }
    )
  },
}

// 或者使用 beforeRouteUpdate 导航守卫,它也可以取消导航:
const User = {
  template: '...',
  async beforeRouteUpdate(to, from) {
    // 对路由变化做出响应...
    this.userData = await fetchUser(to.params.id)
  },
}

5.编程式导航

  • 可以通过 router访问路由实例。因此可以调用this.router 访问路由实例。因此可以调用 this.router.push。
// 声明式
<router-link :to="...">
// 编程式
router.push(...)


// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })
  • 如果路由提供了path,这个params则会被忽略
const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user

由于属性 to 与 router.push 接受的对象种类相同,所以两者的规则完全相同。

替换当前的位置

  • 它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。
// 声明式
<router-link :to="..." replace>
// 编程式
router.replace(...)
// 也可以直接在传递给 router.push 的 routeLocation 中增加一个属性 replace: true :


router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })

路由history模式 window.history.go(n)。

// 向前移动一条记录,与 router.forward() 相同
router.go(1)

// 返回一条记录,与router.back() 相同
router.go(-1)

// 前进 3 条记录
router.go(3)

// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)

6.命名路由

  • 命名路由的优点: 1.没有硬编码的 URL
  1. params 的自动编码/解码。
  2. 防止你在 url 中出现打字错误。
  3. 绕过路径排序(如显示一个)
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const Home = { template: '<div>This is Home</div>' }
const Foo = { template: '<div>This is Foo</div>' }
const Bar = { template: '<div>This is Bar {{ $route.params.id }}</div>' }

const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    { path: '/', name: 'home', component: Home },
    { path: '/foo', name: 'foo', component: Foo },
    { path: '/bar/:id', name: 'bar', component: Bar }
  ]
})

new Vue({
  router,
  template: `
    <div id="app">
      <h1>Named Routes</h1>
      <p>Current route name: {{ $route.name }}</p>
      <ul>
        <li><router-link :to="{ name: 'home' }">home</router-link></li>
        <li><router-link :to="{ name: 'foo' }">foo</router-link></li>
        <li><router-link :to="{ name: 'bar', params: { id: 123 }}">bar</router-link></li>
      </ul>
      <router-view class="view"></router-view>
    </div>
  `
}).$mount('#app')

1.命名视图

  • 一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
<router-view class="view left-sidebar" name="LeftSidebar"></router-view>
<router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>


const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      components: {
        default: Home,
        // LeftSidebar: LeftSidebar 的缩写
        LeftSidebar,
        // 它们与 `<router-view>` 上的 `name` 属性匹配
        RightSidebar,
      },
    },
  ],
})

2.嵌套命名视图

<!-- UserSettings.vue -->
<div>
  <h1>User Settings</h1>
  <NavBar />
  <router-view />
  <router-view name="helper" />
</div>

// 路由
{
  path: '/settings',
  // 你也可以在顶级路由就配置命名视图
  component: UserSettings,
  children: [{
    path: 'emails',
    component: UserEmailsSubscriptions
  }, {
    path: 'profile',
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}

7.路由组件传参

  • 布尔模式 当 props 设置为 true 时,route.params 将被设置为组件的 props。

  • 命名视图

// 对于有命名视图的路由,必须为每个命名视图定义 props 配置:
const routes = [
  {
    path: '/user/:id',
    components: { default: User, sidebar: Sidebar },
    props: { default: true, sidebar: false }
  }
]
  • 对象模式 当 props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
const routes = [
  {
    path: '/promotion/from-newsletter',
    component: Promotion,
    props: { newsletterPopup: false }
  }
]
  • 函数模式 可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
const routes = [
  {
    path: '/search',
    component: SearchUser,
    props: route => ({ query: route.query.q })
  }
]
// URL /search?q=vue 将传递 {query: 'vue'} 作为 props 传给 SearchUser 组件。

参考资料:

vue路由基础