做網(wǎng)站文案網(wǎng)址注冊(cè)在哪里注冊(cè)
vue-router作為vue全家桶之一的重要插件,有必要去深究一下,今天我們就從0到1手寫一個(gè)簡(jiǎn)化版本。
開(kāi)始之前,我們使用路由插件時(shí)是先進(jìn)行下載路由
npm i vue-router
,然后在main.js
中使用app.use
導(dǎo)入router
插件。想要手寫vue-router
,必須先搞懂app.use()
干了一件什么事情。我們?nèi)ス俜轿臋n下面看看。
app.use()?
安裝一個(gè)插件。
-
類型
tsinterface App {use(plugin: Plugin, ...options: any[]): this }
-
詳細(xì)信息
第一個(gè)參數(shù)應(yīng)是插件本身,可選的第二個(gè)參數(shù)是要傳遞給插件的選項(xiàng)。
插件可以是一個(gè)帶?
install()
?方法的對(duì)象,亦或直接是一個(gè)將被用作?install()
?方法的函數(shù)。插件選項(xiàng) (app.use()
?的第二個(gè)參數(shù)) 將會(huì)傳遞給插件的?install()
?方法。若?
app.use()
?對(duì)同一個(gè)插件多次調(diào)用,該插件只會(huì)被安裝一次。
兩個(gè)組件router-view 和router-link
<template><a :href="'#' + props.to"><slot></slot></a>
</template><script setup>
const props = defineProps({to: {type: String,required: true,},
});
</script><style lang="css" scoped>
</style>
<!--* @LastEditTime: 2024-08-14 10:45:56* @Description: file content
-->
<template><component :is="component"></component>
</template><script setup>
import { useRouter } from "./index.js";
import { computed } from "vue";
const router = useRouter();
const mapRouter = new Map();
const reflectMapRouter = (router) => {router.routes.forEach((route) => {// 更具路徑進(jìn)行組件查詢,保證O(1)時(shí)間mapRouter.set(route.path, route.component);});
};
//方法執(zhí)行進(jìn)行組件注冊(cè)
reflectMapRouter(router);
//設(shè)置為計(jì)算屬性響應(yīng)式更新
const component = computed(() => {const nowRoute = mapRouter.get(router.current.value);//這里注意,需要進(jìn)行校驗(yàn),因?yàn)橛脩艨赡茌斎脲e(cuò)誤網(wǎng)址return nowRoute ? nowRoute : null;
});
</script>
<style lang="css" scoped>
</style>
/** @LastEditTime: 2024-08-14 10:47:43* @Description: file content*/
import { ref } from "vue";
// 對(duì)所有頁(yè)面暴露
const ROUTER_KEY = "__router__";export const useRouter = () => {//獲取暴露的Router對(duì)象return inject(ROUTER_KEY);
}
class Router {constructor(options) {//history對(duì)象就是createHashWebHistroy返回的history對(duì)象this.history = options.history;// 路由對(duì)象數(shù)組,path,component,name等配置this.routes = options.routes;//獲取當(dāng)前路由地址this.current = ref(this.history.url);// 這里的方法是監(jiān)聽(tīng)hashchange事件來(lái)更新current,切換路由//,可以先不看這一段等會(huì)會(huì)講this.history.bindEvent(() => {this.current.value = window.location.hash.slice(1);})}//插件的install方法install(app) {// 全局聲明 有一個(gè)router 全局使用的對(duì)象app.provide(ROUTER_KEY, this);//注冊(cè)全局組件app.component('router-link', RouterLink);app.component('router-view', RouterView);}
}
export const createRouter = (options) => {return new Router(options);
}
export const createWebHashHistory = () => {function bindEvent(fn) {window.addEventListener('hashchange', fn);}// history 對(duì)象return {url: window.location.hash.slice(1) || '/',bindEvent}
}