国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue-router 源碼之實現一個簡單的 vue-router

2019-11-19 13:34:45
字體:
來源:轉載
供稿:網友

前言

通過上篇,我們知道前端理由的兩種實現方法,Hash 路由與 History 路由,并且用它們分別實現了一個前端路由。

接下來我們就將 Vue 與 Hash 路由結合,實現一個非常簡單的 vue-router 吧。

開始實現

想象一下,如果自己實現了一個 vue-router,會怎么去使用呢?參考 vue-router 官方的使用方式,看看 html 的使用:

<div id="app"> <p>  <router-link to="#/">home</router-link>  <router-link to="#/book">book</router-link>  <router-link to="#/movie">movie</router-link> </p> <router-view></router-view></div>

這里會有 router-link 和 router-view 兩個組件需要我們來實現。再來看 js 的:

const Home = { template: '<div>home</div>' };const Book = { template: '<div>book</div>' };const Movie = { template: '<div>movie</div>' };const routes = [ { path: '/', component: Home }, { path: '/book', component: Book }, { path: '/movie', component: Movie }];const router = new VueRouter(Vue, { routes});new Vue({ el: '#app'});

這里會有我們自己定義的組件 Home、Book 和 Movie,并且有它們各自對應的路由。我們實現的 VueRouter 跟官方的有些區別,在 VueRouter 被 new 時是將 Vue 作為參數傳入,而不是注入掛載到根實例下。

接下來就是 VueRouter 的實現了。

VueRouter

要怎么來實現 VueRouter 呢,先提供一下實現的思路:

  1. 綁定 hashchange 事件,實現前端路由;
  2. 將傳入的路由和組件做一個路由映射,切換哪個路由即可找到對應的組件顯示;
  3. 需要 new 一個 Vue 實例還做響應式通信,當路由改變的時候,router-view 會響應更新;
  4. 注冊 router-link 和 router-view 組件。

先創建一個 VueRouter:

class VueRouter { constructor (Vue, options) {  this.$options = options; }}

綁定事件

給 VueRouter 添加一個綁定事件的方法,一旦路由發生改變,會觸發 onHashChange 方法。

constructor (Vue, options) { this.init();}// 綁定事件init () { window.addEventListener('load', this.onHashChange.bind(this), false); window.addEventListener('hashchange', this.onHashChange.bind(this), false);}

路由映射表

將傳入的 options 設置成一張路由映射表,以便于通過路由查找到對應的組件。

constructor (Vue, options) { this.$options = options; this.routeMap = {}; this.createRouteMap(this.$options);}// 路由映射表createRouteMap (options) { options.routes.forEach(item => {  this.routeMap[item.path] = item.component; });}

options 之中,路由與組件的關系:

const routes = [ { path: '/', component: Home }, { path: '/book', component: Book }, { path: '/movie', component: Movie }];

生成的路由映射表:

this.routeMap = { '/': Home, '/book': Book, '/movie': Movie};

響應

我們需要 new 一個新的 Vue 實例,將當前路由 current 儲存在其 data 之中,當修改了 current 時,router-view 就會自己去更新視圖。

constructor (Vue, options) { this.app = new Vue({  data: {   current: '#/'  } });}// 獲取當前 hash 串getHash () { return window.location.hash.slice(1) || '/';}// 設置當前路徑onHashChange () { this.app.current = this.getHash();}

只要在 router-view 里使用到了 this.app.current,一旦更新它,便會更新。

注冊組件

router-link 實際上就是一個 <a> 標簽,點擊它便能觸發 hashchangerouter-view 會實現一個 render 方法,將當前路由對應的組件取出,進行渲染。

constructor (Vue, options) { this.initComponent(Vue);}// 注冊組件initComponent (Vue) { Vue.component('router-link', {  props: {   to: String  },  template: '<a :href="to" rel="external nofollow" rel="external nofollow" ><slot></slot></a>' }); const _this = this; Vue.component('router-view', {  render (h) {   var component = _this.routeMap[_this.app.current];   return h(component);  } });}

完整代碼

至此,一個簡單的 vue-router 就出來了,全部代碼是這樣的:

class VueRouter { constructor (Vue, options) {  this.$options = options;  this.routeMap = {};  this.app = new Vue({   data: {    current: '#/'   }  });  this.init();  this.createRouteMap(this.$options);  this.initComponent(Vue); } // 綁定事件 init () {  window.addEventListener('load', this.onHashChange.bind(this), false);  window.addEventListener('hashchange', this.onHashChange.bind(this), false); } // 路由映射表 createRouteMap (options) {  options.routes.forEach(item => {   this.routeMap[item.path] = item.component;  }); } // 注冊組件 initComponent (Vue) {  Vue.component('router-link', {   props: {    to: String   },   template: '<a :href="to" rel="external nofollow" rel="external nofollow" ><slot></slot></a>'  });  const _this = this;  Vue.component('router-view', {   render (h) {    var component = _this.routeMap[_this.app.current];    return h(component);   }  }); } // 獲取當前 hash 串 getHash () {  return window.location.hash.slice(1) || '/'; } // 設置當前路徑 onHashChange () {  this.app.current = this.getHash(); }}

最后

將 Vue 與 Hash 路由結合,監聽了 hashchange 事件,再通過 Vue 的 響應機制 和 組件,便有了上面實現好了一個 vue-router。

全部源碼參考這里

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹巴县| 云安县| 尚志市| 吉林市| 汉川市| 宾川县| 定结县| 梅河口市| 华安县| 秦安县| 新兴县| 巴塘县| 平泉县| 池州市| 鹤山市| 茶陵县| 枝江市| 江永县| 郧西县| 伊吾县| 子长县| 凤凰县| 古浪县| 广德县| 唐河县| 伊吾县| 宁河县| 全南县| 牟定县| 白沙| 苏尼特左旗| 雅江县| 沙田区| 拉孜县| 广昌县| 于田县| 左权县| 德兴市| 资源县| 汽车| 东辽县|