删除多余文件;修复hash路由默认值;优化router-link样式
parent
8519bfd4ef
commit
285e64bbed
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "wkitd",
|
"name": "wkitd",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
|
|
@ -16,6 +16,7 @@ class App extends Component {}
|
||||||
|
|
||||||
export function createApp({
|
export function createApp({
|
||||||
data = {},
|
data = {},
|
||||||
|
styles = [],
|
||||||
methods = {},
|
methods = {},
|
||||||
mounted = noop,
|
mounted = noop,
|
||||||
render
|
render
|
||||||
|
@ -24,6 +25,7 @@ export function createApp({
|
||||||
|
|
||||||
return new (function () {
|
return new (function () {
|
||||||
App.props = data
|
App.props = data
|
||||||
|
App.styles = styles
|
||||||
Object.assign(App.prototype, methods, { mounted })
|
Object.assign(App.prototype, methods, { mounted })
|
||||||
|
|
||||||
this.use = function (plugin = noop, ...args) {
|
this.use = function (plugin = noop, ...args) {
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @authors yutent (yutent@doui.cc)
|
|
||||||
* @date 2017-04-14 21:04:50
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { bind, fire } from 'wkit'
|
|
||||||
import {
|
|
||||||
noop,
|
|
||||||
targetIsThisWindow,
|
|
||||||
query2object,
|
|
||||||
object2query
|
|
||||||
} from '../utils.js'
|
|
||||||
|
|
||||||
//hash前缀正则
|
|
||||||
const PREFIX_REGEXP = /^(#!|#)[\/]+?/
|
|
||||||
const RULE_REGEXP = /(\/[^/]*)(:[A-Za-z0-9_]+)(\?)?/g
|
|
||||||
|
|
||||||
class Router {
|
|
||||||
type = 'history'
|
|
||||||
|
|
||||||
#tables = new Map()
|
|
||||||
#views = new Set()
|
|
||||||
|
|
||||||
#targets = new Map()
|
|
||||||
|
|
||||||
#ready = false
|
|
||||||
#route = Object.create(null)
|
|
||||||
|
|
||||||
#beforeEach
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
// bind(window, 'popstate', this.#hashchange.bind(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 事件监听
|
|
||||||
__listen__() {
|
|
||||||
let { mode } = this.options
|
|
||||||
|
|
||||||
bind(window, 'load, popstate', ev => {
|
|
||||||
if (ev.type === 'load') {
|
|
||||||
if (this.ready) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.ready = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = mode === 'hash' ? location.hash : location.pathname
|
|
||||||
|
|
||||||
path = path.replace(PREFIX_REGEXP, '').trim()
|
|
||||||
path = path.replace(TRIM_REGEXP, '')
|
|
||||||
|
|
||||||
if (ev.type === 'load') {
|
|
||||||
this.go(path)
|
|
||||||
// hash模式要手动触发一下路由检测
|
|
||||||
if (mode === 'hash') {
|
|
||||||
this.__check__(path)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 因为pushState不会触发popstate事件,
|
|
||||||
// 所以这里只在hash模式或有ev.state的情况下才会主动触发路由检测
|
|
||||||
if (mode === 'hash' || ev.state) {
|
|
||||||
this.__check__(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
//劫持页面上所有点击事件,如果事件源来自链接或其内部,
|
|
||||||
//并且它不会跳出本页,并且以"#/"或"#!/"开头,那么触发go方法
|
|
||||||
bind(document, 'click', ev => {
|
|
||||||
let prevented =
|
|
||||||
'defaultPrevented' in ev
|
|
||||||
? ev.defaultPrevented
|
|
||||||
: ev.returnValue === false
|
|
||||||
|
|
||||||
if (prevented || ev.ctrlKey || ev.metaKey || ev.which === 2) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = ev.target
|
|
||||||
while (target.nodeName !== 'A') {
|
|
||||||
target = target.parentNode
|
|
||||||
if (!target || target.tagName === 'BODY') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mode === 'history') {
|
|
||||||
if (targetIsThisWindow(target.target)) {
|
|
||||||
let href =
|
|
||||||
target.getAttribute('href') || target.getAttribute('xlink:href')
|
|
||||||
|
|
||||||
if (
|
|
||||||
!href ||
|
|
||||||
/^(http[s]?:|ftp:)?\/\//.test(href) ||
|
|
||||||
/^javascript:/.test(href)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash地址,只管修正前缀即可, 会触发popstate事件,所以这里只处理非hash的情况
|
|
||||||
if (!PREFIX_REGEXP.test(href)) {
|
|
||||||
// 非hash地址,则需要阻止默认事件
|
|
||||||
// 并主动触发跳转, 同时强制清除hash
|
|
||||||
ev.preventDefault()
|
|
||||||
this.go(href, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
__parseRule__(rule, opts) {
|
|
||||||
let re = rule.replace(RULE_REGEXP, function (m, p1, p2, p3, p4) {
|
|
||||||
let w = '([\\w.-]'
|
|
||||||
if (p1 || p2) {
|
|
||||||
return w + '+)'
|
|
||||||
} else {
|
|
||||||
if (!/^\{[\d\,]+\}$/.test(p4)) {
|
|
||||||
w = '('
|
|
||||||
}
|
|
||||||
return w + p4 + ')'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
re = re
|
|
||||||
.replace(/(([^\\])([\/]+))/g, '$2\\/')
|
|
||||||
.replace(/(([^\\])([\.]+))/g, '$2\\.')
|
|
||||||
.replace(/(([^\\])([\-]+))/g, '$2\\-')
|
|
||||||
.replace(/(\(.*)(\\[\-]+)(.*\))/g, '$1-$3')
|
|
||||||
re = '^' + re + '$'
|
|
||||||
opts.regexp = new RegExp(re)
|
|
||||||
return opts
|
|
||||||
}
|
|
||||||
|
|
||||||
__add__(rule, callback) {
|
|
||||||
// 特殊值"!", 则自动作非匹配回调处理
|
|
||||||
if (rule === '!') {
|
|
||||||
this.noMatch = callback
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (rule.charAt(0) !== '/') {
|
|
||||||
console.error('路由规则必须以"/"开头')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rule = rule.replace(/^[\/]+|[\/]+$|\s+/g, '')
|
|
||||||
let opts = { rule, callback }
|
|
||||||
|
|
||||||
Anot.Array.ensure(this.table, this.__parseRule__(rule, opts))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 路由检测
|
|
||||||
__check__(path) {
|
|
||||||
let { allowReload } = this.options
|
|
||||||
if (!allowReload && path === this.last) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.last = this.path
|
|
||||||
this.path = path
|
|
||||||
this.pathArr = path.split('/')
|
|
||||||
LINKS.forEach(vm => {
|
|
||||||
if (vm.rule.test(this.path)) {
|
|
||||||
vm.active = true
|
|
||||||
} else {
|
|
||||||
vm.active = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
for (let i = 0, route; (route = this.table[i++]); ) {
|
|
||||||
let args = path.match(route.regexp)
|
|
||||||
if (args) {
|
|
||||||
args.shift()
|
|
||||||
return route.callback.apply(route, args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.noMatch && this.noMatch(this.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到路由
|
|
||||||
go2(path, forceCleanHash = false) {
|
|
||||||
path = path.trim().replace(TRIM_REGEXP, '')
|
|
||||||
let { mode } = this.options
|
|
||||||
|
|
||||||
if (mode === 'hash') {
|
|
||||||
// 页面刷新时, 不主动添加空hash, 避免执行2次noMatch回调
|
|
||||||
if (!path && path === location.hash) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
location.hash = '!/' + path
|
|
||||||
} else {
|
|
||||||
let hash = forceCleanHash ? '' : location.hash
|
|
||||||
let search = forceCleanHash ? '' : location.search
|
|
||||||
if (forceCleanHash) {
|
|
||||||
window.history.pushState({ path }, null, `/${path + search + hash}`)
|
|
||||||
} else {
|
|
||||||
window.history.replaceState({ path }, null, `/${path + search + hash}`)
|
|
||||||
}
|
|
||||||
// pushState不会触发popstate事件,所以要手动触发路由检测
|
|
||||||
this.__check__(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绑定路由事件
|
|
||||||
addRoute(routes) {
|
|
||||||
// if (Array.isArray(routes)) {
|
|
||||||
// routes.forEach(it => {
|
|
||||||
// this.#add(it)
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// this.#add(routes)
|
|
||||||
// }
|
|
||||||
// // 初始化后再添加路由, 手动执行一次回调
|
|
||||||
// if (this.#ready) {
|
|
||||||
// this.#hashchange()
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function () {
|
|
||||||
return () => new Router()
|
|
||||||
}
|
|
|
@ -24,6 +24,12 @@ class RouterView extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
#views = []
|
#views = []
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
@ -80,10 +86,15 @@ class RouterLink extends Component {
|
||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: inherit;
|
text-decoration: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -97,9 +97,9 @@ class Router {
|
||||||
#check() {
|
#check() {
|
||||||
let isHash = this.type === MODE_HASH
|
let isHash = this.type === MODE_HASH
|
||||||
let $view = window.wkitd.get(__ROUTER_VIEW__)
|
let $view = window.wkitd.get(__ROUTER_VIEW__)
|
||||||
let hash = location.hash
|
let hash = location.hash || '#/'
|
||||||
let path = isHash
|
let path = isHash
|
||||||
? location.hash
|
? hash
|
||||||
: location.href.replace(location.origin, '').replace(hash, '')
|
: location.href.replace(location.origin, '').replace(hash, '')
|
||||||
let query
|
let query
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue