vue-router v4.x

339 阅读1分钟

vue-router

安装

cdn

unpkg.com/vue-router@…

npm

npm install vue-router@4

项目中使用

import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      component: Dashboard
    },
    {
      path: '/todos',
      component: Todos
    }
  ]
})

createApp(App)
  .use(router)
  .mount("#app")

特性

动态路由

router.addRoute({
    path:'/about',
    name:'about',
    component:()=>import('../components/About.vue')
})
router.addRoute('about',{
    path:'/about/info',
    name:'info',
    component:{
        render(){
            return h('div', 'info page')
        }
    }
})

composition

获取路由器实例

import { useRouter } from 'vue-router';
const router = useRouter()

backTodash(){
    router.push('./')
}

监控route对象

import { useRoute } from "vue-router";
// route是响应式对象,可监控其变化
const route = useRoute();
watch(
  () => route.query,
  (query) => {
    console.log(query);
  }
);

守卫

import { onBeforeRouteLeave } from "vue-router";
onBeforeRouteLeave((to, from) => {
  const answer = window.confirm("你确定要离开当前页面吗?");
  if (!answer) {
    return false;
  }
});

RouterLink、useLink

import { RouterLink, useLink } from 'vue-router'

props: {
    ...RouterLink.props
},
setup (props) {
    // 获取RouterLink内部属性和方法
    const{ route, href, isActive, isExactActive, navigate } = useLink(props)
    console.log(route, href, isActive, isExactActive, navigate);
    return {
        route,
        isActive,
        navigate
    }
}

变化

实例创建方式

new Router() 变成 createRouter()

history选项替代了mode选项

  • history -- createWebHistory()
  • hash -- createWebHashHistory()
  • abstract -- createMemoryHistory()

base选项移至createWebHistory等方法中

通配符*被移除

isReady() 替代 onReady()

router.push()
// before
router.onReady(onSuccess,onError)
// now
router.isReady().then(onSuccess).catch(onError)

scrollBehavior 变化

- x,y -- left,top

<router-view><keep-alive> 和 <transition>

transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:

// before
<keep-alive>
    <router-view></router-view>
</keep-alive>

// now
<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>

<router-link> 一些属性移除

  • append
<router-link to="child-route" append>to relative child</router-link>
替换成
<router-link :to="append($route.path, 'child-route')">
  to relative child
</router-link>

// App 实例上定义一个全局的 `append` 函数:
app.config.globalProperties.append = (path, pathToAppend) =>
  path + (path.endsWith('/') ? '' : '/') + pathToAppend

  • event/tag
<router-link to="/about" tag="span" event="dblclick">About Us</router-link>
替换成
<router-link to="/about" custom v-slot="{ navigate }">
  <span @click="navigate" @keypress.enter="navigate" role="link">About Us</span>
</router-link>

忽略 mixins 中的导航守卫

删除 router.match 改为 router.resolve

删除 router.getMatchedComponents()

router.currentRoute.value.matched.flatMap(record =>
  Object.values(record.components)
)

包括首屏在内的 所有的导航现在都是异步的

这意味着,如果使用一个 transition,你可能需要等待路由 ready 好后再挂载程序:

app.use(router)
// 注意:在服务器端,需要手动跳转到初始地址。
router.isReady().then(() => app.mount('#app'))

如果在初始导航时有导航守卫,你可能不想阻止程序渲染,直到它们被解析,除非你正在进行服务器端渲染。否则,在这种情况下,不等待路由准备好挂载应用会产生与 Vue2 中相同的结果。

router的parent属性被移除

const parent = this.$route.matched[this.$route.matched.length - 2]

删除 pathToRegexpOptions

  • pathToRegexpOptions => strict
  • caseSensitive => sensitive
createRouter({
    strict:boolean,
    sensitive:boolean
})

history.state 的用法

// 将
history.pushState(myState, '', url)
// 替换成
await router.push(url)
history.replaceState({ ...history.state, ...myState }, '')

// 将
history.replaceState({}, '', url)
// 替换成
history.replaceState(history.state, '', url)

options 中的 routes 属性是必需的

createRouter({ routes: [] })

跳转不存在的命名路由报错

缺少必填参会抛出异常

带有空 path 的命名子路由不再添加斜线

const routes = [
  {
    path: '/dashboard',
    name: 'dashboard-parent',
    component: DashboardParent
    children: [
      { path: '', component: DashboardDefault },
    ],
  },
]

const routes = [
  {
    path: '/parent',
    component: Parent,
    children: [
      // 现在将重定向到 `/home` 而不是 `/parent/home`
      { path: '', redirect: 'home' },
      { path: 'home', component: Home },
    ],
  },
]

$route 属性编码行为

paramsquery和 hash

  • path 和 fullPath 不再解码
  • hash 被解码
  • pushresolve 和 replacestring 地址或 path 属性时必须编码
  • params斜线字符(/)会被解码
  • query中 + 不处理,stringifyQuery