vueファミリーバケツ(vue-router簡版ソースコードの実現)
vue-router
Vue RouterはVueです.js官方のルーティングマネージャ.Vueとjsのコア深度統合により、単一ページアプリケーションの構築が容易になります.ネストされたルーティング/ビューグラフ モジュール化コンポーネントベースのルーティング構成 ルーティングパラメータ、クエリー、ワイルドカード はVueに基づく.js遷移システムのビュー遷移効果 細粒度のナビゲーション制御 自動アクティブCSS class付きリンク HTML 5履歴モードまたはhashモード、IE 9で を自動的に降格カスタムスクロールバー動作 インストール:vue add router
コアステップ:
手順一:vue-routerプラグイン、routerを適用する.js
ステップ2:ルーティングテーブルを宣言する(マッピングテーブルであり、pathとコンポーネントはマッピング関係である)
手順3:Routerインスタンス、routerを作成します.js(そしてエクスポート)
ステップ4:ルートコンポーネントにインスタンスを追加するmain.js
ステップ5:ルーティングビュー、Appを追加する.vue
ナビゲーションリンク
以上は多分vue-routerの基本的な使用で、以下は簡略版のソースコードの実現部分に入ります
vue-routerソース実装
需要分析 spaページはリフレッシュできません hash方式例えば#/home またはHistory api例:/about urlに従って対応するコンテンツを表示 router-view データ応答式:current変数はurlアドレスを持ち、変化するとrender を動的に再実行する.
タスク#タスク#プラグインを実装(VueRouterクラスとinstallスキーマの作成) VueRouterクラスの実装 処理ルーティングオプション urlの変化をモニタ 相応の変化 installメソッドを実装 $routerの登録 の2つのグローバルコンポーネント
kvue-routerを作成します.js
router-viewとrouter-linkの作成
krouter-linkを作成します.js
krouter-viewを作成します.js
urlの変化を監視応答式のcurrent属性を定義しhashchangeイベントを傍受する
対応するコンポーネントを動的に取得するkrouter-view.js
事前処理ルーティングテーブル事前処理ルーティングテーブル毎回ループを避ける
使用するjs
完全なコードを添付します
Vue RouterはVueです.js官方のルーティングマネージャ.Vueとjsのコア深度統合により、単一ページアプリケーションの構築が容易になります.
コアステップ:
手順一:vue-routerプラグイン、routerを適用する.js
import Router from 'vue-router'
Vue.use(Router)
ステップ2:ルーティングテーブルを宣言する(マッピングテーブルであり、pathとコンポーネントはマッピング関係である)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
手順3:Routerインスタンス、routerを作成します.js(そしてエクスポート)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
ステップ4:ルートコンポーネントにインスタンスを追加するmain.js
import router from './router'
new Vue({
router,
}).$mount("#app")
ステップ5:ルーティングビュー、Appを追加する.vue
<router-view></router-view>
ナビゲーションリンク
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
以上は多分vue-routerの基本的な使用で、以下は簡略版のソースコードの実現部分に入ります
vue-routerソース実装
需要分析
タスク#タスク#
kvue-routerを作成します.js
let Vue; // ,VueRouter
//
class VueRouter {
constructor(options) {
this.$options = options;
}
}
// : install , $router
VueRouter.install = function(_Vue) {
// ,VueRouter
Vue = _Vue;
// 1: $router
Vue.mixin({
beforeCreate() {
// router
if (this.$options.router) {
// vm.$router
Vue.prototype.$router = this.$options.router;
}
}
});
// 2: router-link router-view
Vue.component('router-link', Link)
Vue.component('router-view', View)
};
export default VueRouter;
? use ,Router , install , ( )
router-viewとrouter-linkの作成
krouter-linkを作成します.js
export default {
//
props: {
to: {
type: String,
require: true
}
},
render(h) {
//
// XXX
//
return h('a',{
attrs: {
href: '#' + this.to
}
}, this.$slots.default)
// jsx
// return {this.$slots.default}
}
}
krouter-viewを作成します.js
export default {
render(h) {
//
return h(null);
}
}
urlの変化を監視応答式のcurrent属性を定義しhashchangeイベントを傍受する
class VueRouter {
constructor(options) {
// current
Vue.util.defineReactive(this, 'current', '/')
// current
const initial = window.location.hash.slice(1) || '/'
Vue.util.defineReactive(this, 'current', initial)
// hashchange
window.addEventListener('hashchange', this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
}
onHashChange() {
this.current = window.location.hash.slice(1)
}
}
対応するコンポーネントを動的に取得するkrouter-view.js
export default {
render(h) {
//
let component = null;
this.$router.$options.routes.forEach(route => {
if (route.path === this.$router.current) {
component = route.component
}
});
return h(component);
}
}
事前処理ルーティングテーブル事前処理ルーティングテーブル毎回ループを避ける
class VueRouter {
constructor(options) {
// path route
this.routeMap = {
}
this.$options.routes.forEach(route => {
this.routeMap[route.path] = route
});
}
}
使用するjs
export default {
render(h) {
const {
routeMap, current} = this.$router
const component = routeMap[current] ? routeMap[current].component : null;
return h(component);
}
}
完全なコードを添付します
//
// 1.
// 2. , install
let _Vue = null
/**
* @class VueRouter
* @param options
*/
class VueRouter {
constructor(options) {
// options : router -
this.$options = options
// path route
this.routeMap = {
}
// url
this.$options.routes.forEach(route => {
this.routeMap[route.path] = route
})
// current
const initial = window.location.hash.slice(1) || '/'
// defineReactive
_Vue.util.defineReactive(this, 'current', initial)
// url
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
onHashChange () {
this.current = window.location.hash.slice(1)
console.log(this.current)
}
}
VueRouter.install = function(Vue) {
// Vue , VueRouter
_Vue= Vue
// 1. $router
// ,
Vue.mixin({
// this vue
beforeCreate() {
if(this.$options.router) {
Vue.prototype.$router = this.$options.router
}
}
})
// 2. router-link, router-view
Vue.component('router-link', {
//
props: {
to: {
type: String,
require: true
}
},
render(h) {
//
// XXX
//
return h('a',{
attrs: {
href: '#' + this.to
}
}, this.$slots.default)
// jsx
// return {this.$slots.default}
}
})
Vue.component('router-view', {
render(h) {
// url
const {
routeMap, current } = this.$router
const component = routeMap[current] ? routeMap[current].component : null
return h(component)
}
})
}
export default VueRouter