vueのhashジャンプの原理を詳しく説明します。
new vueRouterの時に私達は一つのmode属性を導入できます。彼は三つの値を受け取ります。hash/history/abstract
hashとhistoryの違い
historyのパスはもっと綺麗です。たとえば。http://yoursite.com/user/idhistoryは、ページを再読み込みすることなく、pusState()に基づいてURLジャンプを完了する。しかし、強制更新は問題があります。だから、historyモードはバックエンドの人が協力して使う必要があります。
hashの経路は22166;を持っています。たとえばhttp://yoursite.com#/user/id
ハイビスカス
get CurrenntLocationが実現しました。
installメソッドでは
hashとhistoryの違い
historyのパスはもっと綺麗です。たとえば。http://yoursite.com/user/idhistoryは、ページを再読み込みすることなく、pusState()に基づいてURLジャンプを完了する。しかし、強制更新は問題があります。だから、historyモードはバックエンドの人が協力して使う必要があります。
hashの経路は22166;を持っています。たとえばhttp://yoursite.com#/user/id
ハイビスカス
class VueRouter{
constructor(options){
this.matcher = createMatcher(options.routes || []);
// hash
this.history = new HashHistory(this);//this vue-router
}
}
ソースコードはここで基本的なクラスを作成しました。ここでソースコードと統一して、このベースクラスは3つのモード共通の方法と属性を実装しました。ここでHashHistoryとベースHistoryを作成します。
import History from './base'
// hash
export default class HashHistory extends History{
constructor(router){
super(router); // call
}
}
//
export default class History {
constructor(router){
this.router = router;
}
}
hashルートであれば、ウェブサイトを開けます。hashがなければ、デフォルトで嚓を追加するべきです。
import History from './base';
function ensureSlash(){
if(window.location.hash){
return
}
window.location.hash = '/'
}
export default class HashHistory extends History{
constructor(router){
super(router);
ensureSlash(); // hash
}
}
初期化されたロジック(上のrouter.init関数)をもう一度見てください。
init(app){
const history = this.history;
// , ,
//
const setupHashListener = ()=> {
history.setupListener(); //
}
history.transitionTo( //
history.getCurrentLocation(), //
// ,
setupHashListener
)
}
ここでは、それぞれtranition To、get CurrenntLocation、setupListenerを実現します。get CurrenntLocationが実現しました。
function getHash(){
return window.location.hash.slice(1);
}
export default class HashHistory extends History{
// ...
getCurrentLocation(){
return getHash();
}
}
setupListener実現
export default class HashHistory extends History{
// ...
setupListener(){
window.addEventListener('hashchange', ()=> {
// hash
this.transitionTo(getHash());
})
}
}
TransitionTo実現
export function createRoute(record, location) { // {path:'/',matched:[record,record]}
let res = [];
if (record) { //
while(record){
res.unshift(record); //
record = record.parent
}
}
return {
...location,
matched: res
}
}
export default class History {
constructor(router) {
this.router = router;
// , router-view
this.current = createRoute(null, {
path: '/'
})
}
//
transitionTo(location, onComplete) {
//
let route = this.router.match(location);
//
if(
location === route.path &&
route.matched.length === this.current.matched.length){
return
}
// _route
this.updateRoute(route)
onComplete && onComplete();
}
}
export default class VueRouter{
// ...
//
match(location){
return this.matcher.match(location);
}
}
macthメソッド
function match(location){ //
let record = pathMap[location]
if (record) { //
// :/about/a:{path:xx,component...},path:'/about/a'
return createRoute(record,{
path:location
})
}
//
return createRoute(null, {
path: location
})
}
経路の変化を発見するのは難しくないです。current属性を応答式に変えることができます。毎回currentが変化してビューを更新すればいいです。installメソッドでは
install(Vue) {
Vue.mixin({ // beforeCreate
beforeCreate() {
if (this.$options.router) {
// Vue
Vue.util.defineReactive(this,'_route',this._router.history.current);
}
}
});
// $route $router vue
Object.defineProperty(Vue.prototype,'$route',{ // $route
get(){
return this._routerRoot._route;//
}
});
Object.defineProperty(Vue.prototype,'$router',{ // router
get(){
return this._routerRoot._router;
}
})
}
ルートの切り替えは初期化のたびに更新を呼び出す必要があります。routeの方法は、installの時に_をrouteは双方向データバインディングをしていますが、入ったばかりではthisがありません。router.history.currentの購読方法を発表して購読と更新の操作を行います。initメソッドに傍受関数を追加します。
history.listen((route) => { // _route ,
app._route = route
});
export default class History {
constructor(router) {
// ...
this.cb = null;
}
listen(cb){
this.cb = cb; //
}
updateRoute(route){
this.current =route;
this.cb && this.cb(route); // current _route
}
}
以上はvueのhashジャンプの原理について詳しく説明しました。vueのhashジャンプの原理に関する資料は他の関連記事に注目してください。