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