- 路由的变化
- 路由的使用
- 路由的history
- createMemoryHistory
- createWebHashHistory
- createWebHistory
- 组件的变化
- 异步组件
- render函数
- 异步页面
- 内置Teleport组件
- 异步组件
路由的变化
- 安装
# 在Vue3要安装路由时使用npm i vue-router@nextyarn add vue-router@next
路由的使用
Vue2中使用路由的方法如下:
Vue3中使用路由的方法如下: ```javascript // src/router/index.js import {createRouter} from ‘vue-router’import VueRouter from 'vue-router'
// main.js import router from ‘./router’ createApp(App).use(router).mount(‘#app’)
<a name="cbi2T"></a>#### 路由的history在原来Vue2中,路由中原来模式的用法```javascriptconst router = new VueRouter({mode: 'history', // hashroutes: [...]})
而在Vue3的路由中则新增了三个函数
- createMemoryHistory
- createWebHashHistory
- createWebHistory
import { createRouter, createWebHistory } from 'vue-router'export default createRouter({history: createWebHistory(),routes: [...]})
组件的变化
在Vue3中使用异步组件的方法和Vue2有所不同。Vue3中新增了一个defineAsyncComponent方法来返回一个异步组件。
基本用法。将回调函数传入
defineAsyncComponent方法,并返回一个import语句。import { defineAsyncComponent} from 'vue'const Block = defineAsyncComponent(() => import('../components/Block.vue')) // Block就是一个异步的组件
这里回调函数返回的是一个Promise对象。
对于进阶用法。
defineAsyncComponent也可以接受一个对象(具体见官方文档)。defineAsyncComponent({loader: () => import(path),loadingComponent: Loading,errorComponent: MyError})
其中,loader是一个函数,返回一个通过import导入组件的对象。
loadingComponent是加载时要显示的组件。
errorComponent是当抛出错误时要显示的组件。
这里看另一种写法:
defineAsyncComponent({loader: () => import(path),loadingComponent: Loading,errorComponent: {render(h) {return h(Comp, 'error')}}})
在Vue2中,render函数会有h的形参。但是在Vue3中,则将h函数从参数中去除,而是通过import {h} from 'vue'导入并使用。所以上述代码会报错,正确的使用应该如下
import { defineAsyncComponent, h } from 'vue'defineAsyncComponent({loader: () => import(path),loadingComponent: Loading,errorComponent: {render() {return h(Comp, 'error')}}})
一个组件可以进行异步加载,那么页面是否也可以异步加载呢?这是可以的,页面其实也是组件。但是在router中,页面的组件是这样使用的。
import Home from '../views/Home.vue'import About from '../views/About.vue'const routes = [{path: '/',component: Home},{path: '/about',component: About},]
这样的页面组件还是同步的,在这段代码中,先将需要的组件import,然后将其放到router中。那么既然异步组件是通过defineAsyncComponent包装后变为异步组件,那么页面组件也同样使用同样的方法包装后成为异步的页面组件。
const Home = getAsyncPage('../views/Home.vue')const About = getAsyncPage('../views/About.vue')
这里getAsyncPage(path)是一个封装好的方法,接受一个path(组件路径)并返回一个包装好的异步组件。这样就将页面组件也转为了异步的页面组件。
/*** 生产异步页面* @param {String} path 组件路径*/export function getAsyncPage (path) {return defineAsyncComponent({loader: async () => {NPorgress.start()await delay(500)const comp = await import(path)NPorgress.done()return comp},loadingComponent: Loading, // 当Promise在pendding时显示的组件。})}
Teleport组件
在日常模态框的功能中,模态框组件一般都是和模态框相关的逻辑放在一起。但是这就造成了在HTML结构中,模态框相关的节点是放在相应的节点周围。
但是在模态框在HTML结构中,应该作为body的直接子元素。在Vue3中提供了一个内置组件Teleport,提供了一个to属性。to属性接受一个css选择器(如#app,body,.class)。
<Teleport to="body"><Modal></Modal></Teleport>
将Modal组件包裹在Teleport中,通过to指定body,就达到了尽管在vue组件中modal和相关逻辑在一起,但是在最终HTML结构中,modal放在了body的子结点上。
