支持keepAlive和transition;
parent
0c42d793fa
commit
248e153995
|
@ -71,9 +71,15 @@ export function createApp({
|
|||
if ($router) {
|
||||
App.prototype.mounted = function (...args) {
|
||||
let $view = window.__wkitd__.get('ROUTER_VIEW')
|
||||
if ($view) {
|
||||
$view.sync($router.getViews())
|
||||
$router.init()
|
||||
mounted.call(this, ...args)
|
||||
} else {
|
||||
throw new Error(
|
||||
`<router-view /> not found, "Router" works Unexpected.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
App.reg('app')
|
||||
|
|
|
@ -18,16 +18,14 @@ const DEFAULT_OPTIONS = {
|
|||
const RULE_REGEXP =
|
||||
/(:id)|(\{id\})|(\{id:([A-z\d\,\[\]\{\}\-\+\*\?\!:\^\$]*)\})/g
|
||||
|
||||
const __ready__ = Symbol('ready')
|
||||
|
||||
class Router {
|
||||
[__ready__] = false
|
||||
|
||||
#tables = new Map()
|
||||
#views = new Set()
|
||||
|
||||
#options = Object.create(null)
|
||||
#targets = new Set()
|
||||
|
||||
#ready = false
|
||||
#options = Object.create(null)
|
||||
#route = Object.create(null)
|
||||
|
||||
constructor(options = {}) {
|
||||
|
@ -42,10 +40,10 @@ class Router {
|
|||
|
||||
#hashchange(ev) {
|
||||
if (ev?.type === 'load') {
|
||||
if (this[__ready__]) {
|
||||
if (this.#ready) {
|
||||
return
|
||||
}
|
||||
this[__ready__] = true
|
||||
this.#ready = true
|
||||
}
|
||||
|
||||
let path = location.hash
|
||||
|
@ -89,12 +87,6 @@ class Router {
|
|||
}
|
||||
|
||||
#add(route) {
|
||||
// 特殊值"!", 则自动作非匹配回调处理
|
||||
// if (route.path === '!') {
|
||||
// // this.noMatch = callback
|
||||
// this.#views.add(route.name)
|
||||
// return
|
||||
// }
|
||||
if (route.path !== '!' && route.path[0] !== '/') {
|
||||
console.error('路由规则必须以"/"开头')
|
||||
return
|
||||
|
@ -102,6 +94,7 @@ class Router {
|
|||
route.path = route.path.replace(/^[\/]+|[\/]+$|\s+/g, '')
|
||||
|
||||
this.#tables.set(route.path, this.#parseRule(route))
|
||||
this.#views.add(route.name)
|
||||
}
|
||||
|
||||
// 路由检测
|
||||
|
@ -112,7 +105,6 @@ class Router {
|
|||
if (!$view || (!allowReload && path === this.#route.path)) {
|
||||
return
|
||||
}
|
||||
// console.log('<><><><>')
|
||||
|
||||
for (let [k, route] of this.#tables) {
|
||||
let args = path.match(route.regexp)
|
||||
|
@ -123,16 +115,31 @@ class Router {
|
|||
this.#route.name = route.name
|
||||
this.#route.params = args
|
||||
this.#route.query = {}
|
||||
break
|
||||
this.#rsync()
|
||||
return
|
||||
}
|
||||
}
|
||||
// this.noMatch && this.noMatch(this.path)
|
||||
if (this.#tables.get('!')) {
|
||||
route = this.#tables.get('!')
|
||||
$view.current = route.name
|
||||
this.#route = { path, name: route.name, params: {}, query: {} }
|
||||
}
|
||||
}
|
||||
|
||||
#rsync() {
|
||||
for (let callback of this.#targets) {
|
||||
callback(this.route)
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.#hashchange()
|
||||
}
|
||||
|
||||
rsync(callback) {
|
||||
this.#targets.add(callback)
|
||||
}
|
||||
|
||||
getViews() {
|
||||
return Array.from(this.#views)
|
||||
}
|
||||
|
@ -166,7 +173,7 @@ class Router {
|
|||
// 因为先初始化,才开始监听路由规则
|
||||
// 所以会导致wondow load的时候, 规则还没生效, 而生效之后,load已经结束
|
||||
// 所以这里需要手动再触发一次load
|
||||
if (this[__ready__]) {
|
||||
if (this.#ready) {
|
||||
this.#hashchange()
|
||||
} else {
|
||||
fire(window, 'load')
|
||||
|
|
|
@ -14,7 +14,21 @@ export { createWebHashHistory, createWebHistory }
|
|||
class Router extends Component {
|
||||
static props = {
|
||||
keepAlive: false,
|
||||
current: 'str!'
|
||||
transition: false,
|
||||
current: {
|
||||
type: String,
|
||||
default: '',
|
||||
attribute: false,
|
||||
observer(v, old) {
|
||||
if (this.keepAlive && v) {
|
||||
if (old && this.$refs[old]) {
|
||||
this.$refs[old].deactivated()
|
||||
}
|
||||
this.$refs[v]?.$animate()
|
||||
this.$refs[v]?.activated()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#views = []
|
||||
|
@ -28,10 +42,36 @@ class Router extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
let option = {
|
||||
immediate: true,
|
||||
custom: [
|
||||
{ transform: 'translateX(-32px)', opacity: 0 },
|
||||
{ transform: 'translateX(0)', opacity: 1 }
|
||||
]
|
||||
}
|
||||
if (this.keepAlive) {
|
||||
return html``
|
||||
let template = this.#views.map(it => [
|
||||
this.transition
|
||||
? `<${it} ref="${it}" :__keep_alive__="%s" #animation="%s" style="%s"></${it}>`
|
||||
: `<${it} ref="${it}" :__keep_alive__="%s" style=%s></${it}>`,
|
||||
[
|
||||
this.current === it,
|
||||
{ ...option, immediate: this.current === it },
|
||||
this.current === it ? '' : 'display:none'
|
||||
]
|
||||
])
|
||||
|
||||
return raw(
|
||||
template.map(it => it[0]).join(''),
|
||||
template.map(it => it[1]).flat()
|
||||
)
|
||||
} else {
|
||||
if (this.current) {
|
||||
if (this.transition) {
|
||||
return raw(`<${this.current} #animation="%s"></${this.current}>`, [
|
||||
option
|
||||
])
|
||||
}
|
||||
return raw(`<${this.current}></${this.current}>`)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue