hash路由与history路由
- hash模式:hash模式就是浏览器地址中
#及其后边的部分,通过window.location.hash可以获取到路径上的hash值。当路径的hash值发生变化时,不会导致页面刷新,也不会发送请求,我们可以通过hashchange事件来监听hash值的变化,进而渲染新的组件内容。
- history模式:history模式没有
#相关的内容,它之所以可以实现前端路由是由于HTML5新增的pushState以及replaceState方法啊,支持对浏览器的路由进行修改操作,此时浏览器不会对服务端发送请求并且也会触发一个监听事件popState。
实现前端路由的条件如下:
- 更改页面路径,不会引起页面刷新,不会向服务器端发送请求
- 存在监听路径改变的事件,可以在路径改变之后动态渲染页面
怎么实现vue3中的路由管理:
下面以hash模式为例手动实现vue3的hash模式路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import {createRouter,createWebHashHistory} from 'vue-router'
import Login from '../pages/login.vue' import Home from '../pages/home.vue'
const routes = [ {path:'/login',component:Login}, {path:'/home',component:Home} ]
export default createRouter({ history:CreateWebHashHistory(), routes })
|
1 2 3 4 5 6 7 8
| import {createApp} from "vue"
import App from './App.vue' import router from './router/router'
const app = createApp(App) app.use(router).mount('#app')
|
在这里我们手动实现一下createRouter与createWebHashHistory方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import RouterLink from './router-link.vue' import RouterView from './router-view.vue'
function createWebHashHistory(){ return 'WebHashHistory' }
import ref from 'vue' function createRouter(params){ const history = params.history const routes = params.routes const router = { history, routes, hash:ref(window.location.hash.slice(1)) install(app){ app.component("router-link",RouterLink) app.component("router-view",RouterView) app.provide("ROUTER",router) } } if(history == 'WebHashHistory'){ window.addEvenntListener('hashchange',() => { router.hash.value = window.location.slice(1) }) } return router }
|
搞定了上面这些只能监听到hash值的变化,还不足以根据hash将组件渲染到页面上,所以需要新增两个文件router-link.vue与router-view.vue来实现跳转与渲染功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //router-link使用 <router-link to='/login'>login</router-link>
//实现:就是一个a标签传入一个to参数,子元素使用插槽插入 <template> <a :href="'#' + props.to"> <slot></slot> </a> </template> <script setup> import {defineProps} from "vue" let props = defineProps({ to:String }) </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| //router-view实现:根据hash值去匹配查询的对应的组件 <template> <component :is="currentComponent"></component> </template> <script> import {computed,reactive,ref} from "vue" //获取app组件的传值,使用inject const router = inject('ROUTER') let hash = router.hash let routes = router.routes //hash地址为响应式,根据地址计算出组件 let currentComponent = computed(() => { const targetComponent = routes.find((routes) => { return route.path === hash.value }) return targetComponent.component }) </script>
|