日常開發中積累了不少可能對一些開發有幫助的簡單易用的組件,好記性不如爛筆頭,想對過去的一些零零亂亂的東西做一些總結,反省自己的同時也便于思考一些更優的方法,提升下開發思維??????。
代碼傳送門(??感覺有作用的的同學幫忙點下???)
效果截圖
完美實現了一個簡單的路由效果
router.gif
核心代碼
主要結構包括VueRouter類和install方法(install方法主要由Vue.use(...)來自動觸發該方法,是插件的必經之路。
)
let Vue = null; // 用來保存傳進來的Vue函數
class VueRouter {
constructor(options) {
this.$options = options;
this.routeMap = {};
this.app = new Vue({
data: {
current: '/'
}
})
}
init () {
this.listenURL()
// 創建路由映射
this.createRouteMap(this.$options)
// 初始化組件
this.initComponent()
}
listenURL () {
window.addEventListener('load', this.onHashChange.bind(this), false)
window.addEventListener('hashchange', this.onHashChange.bind(this), false)
}
createRouteMap (options) {
options.routes.forEach(element => {
this.routeMap[element.path] = element
});
}
initComponent () {
// 全局注冊組件router-link/router-view
Vue.component('router-link', {
props: {
to: String
},
render (h) {
console.log(this.$slots.default)
return h('a', {
attrs: {
href: '#' + this.to
}
}, [this.$slots.default])
}
})
Vue.component('router-view', {
render: h => {
var component = this.routeMap[this.app.current].component
return h(component)
},
})
}
onHashChange () {
this.app.current = window.location.hash.slice(1) || '/'
}
}
VueRouter.install = function (_Vue) {
Vue = _Vue
console.log('install')
Vue.mixin({
beforeCreate () {
console.log(this.$options.router)
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
export default VueRouter
代碼塊分析
constructor函數
:構造方法,創建路由對象的時候調用該方法,將配置項傳遞進來
constructor(options) {
this.$options = options; // 用來保存routes等配置項
this.routeMap = {}; // 用來保存路由關系映射
// 利用Vue的響應式,路由改變觸發其他條件(渲染組件)
this.app = new Vue({
data: {
current: '/'
}
})
}
install函數
:Vue.use(...)會觸發該方法,并把Vue傳入
VueRouter.install = function (_Vue) {
Vue = _Vue
// 全局混入,在生命周期中做一些擴展操作
Vue.mixin({
beforeCreate () {
if (this.$options.router) {
// 1.將創建Vue對象中傳入的router掛載在根組件上
Vue.prototype.$router = this.$options.router
// 2.觸發init方法
this.$options.router.init()
}
}
})
}
listenURL函數
:監聽地址的變化
listenURL () {
// 監聽初始化加載完成時候
window.addEventListener('load', this.onHashChange.bind(this), false)
// 監聽URL #后面的地址變化
window.addEventListener('hashchange', this.onHashChange.bind(this), false)
}
createRouteMap函數
:保存傳入的routes
createRouteMap (options) {
// 取出所有routes中的元素,以path為鍵作映射
options.routes.forEach(element => {
this.routeMap[element.path] = element
});
}
initComponent函數
:通過h函數
渲染router-link和router-view組件
initComponent () {
// 全局注冊組件router-link/router-view
Vue.component('router-link', {
props: {
to: String
},
render (h) {
return h('a', {
attrs: {
href: '#' + this.to
}
}, [this.$slots.default])
}
})
Vue.component('router-view', {
render: h => {
// 獲取對應的組件進行渲染
var component = this.routeMap[this.app.current].component
return h(component)
},
})
}
使用
在使用上和vue-router一模一樣,但是該代碼僅可用hash模式
關鍵點
處理自定義組件,一定要對vue中的傳值比較清晰了解,這里就不一一列舉。在這里主要使用的一些技術包括:
技術 | 概述 | 備注 |
---|---|---|
mixin | 全局混入 | 此處是混入到Vue的生命周期中 |
h函數 | 相當于createElement | 此處是創建兩個路由組件 |
hashchange | 監聽地址欄地址變化 | / |
install方法 | Vue.use(...)觸發 | 插件核心方法 |
后續會持續更新其他一些有用的組件提供參考...