Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
|
092aaff8b1 | |
|
f30eac2195 | |
|
a9ff9f0323 | |
|
d3a00a319f | |
|
37dcc51e05 | |
|
a1c1740166 | |
|
b7567a15fc | |
|
ba92054633 | |
|
a24ab67694 | |
|
9c9561cb1c |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wkitd",
|
||||
"version": "1.3.4",
|
||||
"version": "1.3.12",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
|
|
|
@ -92,7 +92,7 @@ export function createApp({
|
|||
}
|
||||
}
|
||||
}
|
||||
App.reg('app')
|
||||
App.reg('app', 'v')
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
import { Component, html, css, raw } from 'wkit'
|
||||
import { object2query } from '../utils.js'
|
||||
import { object2query, query2object } from '../utils.js'
|
||||
import { __ROUTER_VIEW__, ROUTE_CALLBACKS } from '../constants.js'
|
||||
import { watch } from '../store.js'
|
||||
|
||||
|
@ -21,13 +21,16 @@ class RouterView extends Component {
|
|||
|
||||
set current(v) {
|
||||
let old = this.#current
|
||||
let $refs = this.$refs
|
||||
this.#current = v
|
||||
|
||||
if (this.keepAlive) {
|
||||
if (old) {
|
||||
if (this.$refs[old]) {
|
||||
this.$refs[old].removed = true
|
||||
this.$refs[old].deactivated()
|
||||
this.$refs[old].remove()
|
||||
let $old = $refs[old]
|
||||
if ($old) {
|
||||
$old.removed = true
|
||||
$old.deactivated()
|
||||
$old.remove()
|
||||
} else {
|
||||
this.$requestUpdate()
|
||||
}
|
||||
|
@ -35,14 +38,15 @@ class RouterView extends Component {
|
|||
this.$requestUpdate()
|
||||
}
|
||||
if (v) {
|
||||
if (this.$refs[v]) {
|
||||
this.root.appendChild(this.$refs[v])
|
||||
this.$refs[v].$requestUpdate()
|
||||
let $new = $refs[v]
|
||||
if ($new) {
|
||||
this.root.appendChild($new)
|
||||
$new.$requestUpdate()
|
||||
if (this.transition) {
|
||||
this.$refs[v].$animate()
|
||||
$new.$animate()
|
||||
}
|
||||
this.$refs[v].removed = false
|
||||
this.$refs[v].activated()
|
||||
$new.removed = false
|
||||
$new.activated()
|
||||
} else {
|
||||
this.$requestUpdate()
|
||||
}
|
||||
|
@ -72,20 +76,21 @@ class RouterView extends Component {
|
|||
{ transform: 'translateX(0)', opacity: 1 }
|
||||
]
|
||||
}
|
||||
let name = this.current
|
||||
|
||||
if (this.current) {
|
||||
if (name) {
|
||||
if (this.transition) {
|
||||
return raw(
|
||||
`<${this.current} ref="${this.current}" ${
|
||||
`<${name} ref="${name}" ${
|
||||
this.keepAlive ? 'keep-alive' : ''
|
||||
} #animation="%s"></${this.current}>`,
|
||||
} #animation="%s"></${name}>`,
|
||||
[option]
|
||||
)
|
||||
}
|
||||
return raw(
|
||||
`<${this.current} ref="${this.current}" ${
|
||||
`<${name} ref="${name}" ${
|
||||
this.keepAlive ? 'keep-alive' : ''
|
||||
}></${this.current}>`
|
||||
}></${name}>`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +98,7 @@ class RouterView extends Component {
|
|||
|
||||
class RouterLink extends Component {
|
||||
static props = {
|
||||
to: Object,
|
||||
to: { type: null },
|
||||
disabled: false
|
||||
}
|
||||
|
||||
|
@ -107,6 +112,7 @@ class RouterLink extends Component {
|
|||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--router-link-gap, 0);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -120,11 +126,12 @@ class RouterLink extends Component {
|
|||
cursor: not-allowed;
|
||||
}
|
||||
`
|
||||
#to = { path: '' }
|
||||
#href = ''
|
||||
|
||||
#navigate() {
|
||||
let type = this.$router.type
|
||||
let { path } = this.to
|
||||
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
|
@ -132,26 +139,33 @@ class RouterLink extends Component {
|
|||
if (type === 'hash') {
|
||||
location.hash = this.#href
|
||||
} else {
|
||||
this.$router.push(this.to)
|
||||
this.$router.push(this.#to)
|
||||
}
|
||||
}
|
||||
|
||||
#parsePath() {
|
||||
let type = this.$router.type
|
||||
let { path = '', query = {} } = this.to
|
||||
let params =
|
||||
typeof query === 'string'
|
||||
? query.replaceAll('?', '')
|
||||
: object2query(query)
|
||||
let path, query, params
|
||||
if (typeof this.to === 'string') {
|
||||
let tmp = this.to.split('?')
|
||||
path = tmp[0]
|
||||
params = tmp[1] || ''
|
||||
query = query2object(params)
|
||||
} else {
|
||||
path = this.to.path || ''
|
||||
query = this.to.query || {}
|
||||
params =
|
||||
typeof query === 'string'
|
||||
? query.replaceAll('?', '')
|
||||
: object2query(query)
|
||||
}
|
||||
|
||||
path = '/' + path.replace(/^\/+/, '')
|
||||
this.to = { path, query }
|
||||
this.#to = { path, query }
|
||||
|
||||
if (params) {
|
||||
path += '?' + params
|
||||
}
|
||||
|
||||
return path
|
||||
this.#href = path
|
||||
}
|
||||
|
||||
activated() {
|
||||
|
@ -166,7 +180,7 @@ class RouterLink extends Component {
|
|||
if (this.removed) {
|
||||
return
|
||||
}
|
||||
this.classList.toggle('active', route.path === this.to.path)
|
||||
this.classList.toggle('active', route.path === this.#to.path)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -175,17 +189,12 @@ class RouterLink extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
this.#href = this.#parsePath()
|
||||
this.#parsePath()
|
||||
return html`<a title=${this.#href} @click=${this.#navigate}
|
||||
><slot></slot
|
||||
></a>`
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('router-view')) {
|
||||
customElements.define('router-view', RouterView)
|
||||
}
|
||||
|
||||
if (!customElements.get('router-link')) {
|
||||
customElements.define('router-link', RouterLink)
|
||||
}
|
||||
RouterView.reg('view', 'router')
|
||||
RouterLink.reg('link', 'router')
|
||||
|
|
|
@ -10,7 +10,7 @@ import { __ROUTER_VIEW__, ROUTE_CALLBACKS } from '../constants.js'
|
|||
|
||||
//hash前缀正则
|
||||
const PREFIX_REGEXP = /^(#!|#)[\/]+?/
|
||||
const RULE_REGEXP = /(\/[^/]*)(:[A-Za-z0-9_]+)(\?)?/g
|
||||
const RULE_REGEXP = /(\/[^/]*)(:[\$@~\\!A-Za-z0-9_=\-]+)(\?)?/g
|
||||
|
||||
const MODE_HASH = 'hash'
|
||||
const MODE_HISTORY = 'history'
|
||||
|
@ -23,6 +23,7 @@ class Router {
|
|||
|
||||
#ready = false
|
||||
#route = Object.create(null)
|
||||
#tmp = null
|
||||
|
||||
#beforeEach
|
||||
|
||||
|
@ -69,7 +70,7 @@ class Router {
|
|||
if (_prefix === '/') {
|
||||
_prefix = '/?'
|
||||
}
|
||||
return _prefix + '([A-Za-z0-9_]+)' + _require
|
||||
return _prefix + '([\\$\\!@~A-Za-z0-9_=\\-]+)' + _require
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -105,6 +106,10 @@ class Router {
|
|||
;[path, query] = path.split('?')
|
||||
}
|
||||
path = path.replace(PREFIX_REGEXP, '/')
|
||||
// 修正默认主页,以支持带路径访问的首页
|
||||
if (path === '/index.html') {
|
||||
path = '/'
|
||||
}
|
||||
|
||||
if (!$view || path === this.#route.path) {
|
||||
// query不同, 只更新query
|
||||
|
@ -128,12 +133,12 @@ class Router {
|
|||
params,
|
||||
query: query2object(query)
|
||||
}
|
||||
Object.defineProperty(next, 'raw', { value: route.path })
|
||||
if (this.#beforeEach) {
|
||||
return this.#beforeEach(this.route, next, () => {
|
||||
this.#exec(next)
|
||||
})
|
||||
}
|
||||
|
||||
return this.#exec(next)
|
||||
}
|
||||
}
|
||||
|
@ -142,13 +147,26 @@ class Router {
|
|||
$view.current = route.name
|
||||
this.#route = { path, name: route.name, params: {}, query: {} }
|
||||
this.#exec(this.#route)
|
||||
} else {
|
||||
if (this.#tmp) {
|
||||
this.#exec(this.#tmp)
|
||||
this.#tmp = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#exec(route) {
|
||||
let $view = window.wkitd.get(__ROUTER_VIEW__)
|
||||
let table = this.#tables.get(route.raw)
|
||||
$view.current = route.name
|
||||
this.#route = route
|
||||
|
||||
if (table && typeof table.component === 'function') {
|
||||
if (!customElements.get(route.name)) {
|
||||
table.component()
|
||||
delete table.component //避免多次请求
|
||||
}
|
||||
}
|
||||
this.#broadcast()
|
||||
}
|
||||
|
||||
|
@ -215,6 +233,9 @@ class Router {
|
|||
return
|
||||
}
|
||||
|
||||
// 缓存当前路由信息, 当没有匹配到正确的路由时, 回调此缓存
|
||||
this.#tmp = obj
|
||||
|
||||
if (this.type === MODE_HASH) {
|
||||
if (replace) {
|
||||
location.replace(path.replace(/^\//, '#/'))
|
||||
|
|
Loading…
Reference in New Issue