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