first
This commit is contained in:
21
node_modules/vue-router/LICENSE
generated
vendored
Normal file
21
node_modules/vue-router/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-present Evan You
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
138
node_modules/vue-router/README.md
generated
vendored
Normal file
138
node_modules/vue-router/README.md
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
# vue-router [](https://circleci.com/gh/vuejs/vue-router)
|
||||
|
||||
> This is vue-router 3.0 which works only with Vue 2.0.
|
||||
> - For the 1.x router see the [1.0 branch](https://github.com/vuejs/vue-router/tree/1.0).
|
||||
> - For Vue Router 4 (for Vue 3) see [vuejs/router](https://github.com/vuejs/router).
|
||||
|
||||
<h2 align="center">Supporting Vue Router</h2>
|
||||
|
||||
Vue Router is part of the Vue Ecosystem and is an MIT-licensed open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:
|
||||
|
||||
- [Become a Sponsor on GitHub](https://github.com/sponsors/posva)
|
||||
- [One-time donation via PayPal](https://paypal.me/posva)
|
||||
|
||||
<!--sponsors start-->
|
||||
|
||||
<h4 align="center">Gold Sponsors</h4>
|
||||
<p align="center">
|
||||
<a href="https://vuejobs.com/?utm_source=vuerouter&utm_campaign=sponsor" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://posva-sponsors.pages.dev/logos/vuejobs.svg" media="(prefers-color-scheme: dark)" height="72px" alt="VueJobs" />
|
||||
<img src="https://posva-sponsors.pages.dev/logos/vuejobs.svg" height="72px" alt="VueJobs" />
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">Silver Sponsors</h4>
|
||||
<p align="center">
|
||||
<a href="https://www.vuemastery.com/" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://posva-sponsors.pages.dev/logos/vuemastery-dark.png" media="(prefers-color-scheme: dark)" height="42px" alt="VueMastery" />
|
||||
<img src="https://posva-sponsors.pages.dev/logos/vuemastery-light.svg" height="42px" alt="VueMastery" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.prefect.io/" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://posva-sponsors.pages.dev/logos/prefectlogo-dark.svg" media="(prefers-color-scheme: dark)" height="42px" alt="Prefect" />
|
||||
<img src="https://posva-sponsors.pages.dev/logos/prefectlogo-light.svg" height="42px" alt="Prefect" />
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">Bronze Sponsors</h4>
|
||||
<p align="center">
|
||||
<a href="https://stormier.ninja" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://avatars.githubusercontent.com/u/2486424?u=7b0c73ae5d090ce53bf59473094e9606fe082c59&v=4" media="(prefers-color-scheme: dark)" height="26px" alt="Stanislas Ormières" />
|
||||
<img src="https://avatars.githubusercontent.com/u/2486424?u=7b0c73ae5d090ce53bf59473094e9606fe082c59&v=4" height="26px" alt="Stanislas Ormières" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="www.vuejs.de" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://avatars.githubusercontent.com/u/4183726?u=6b50a8ea16de29d2982f43c5640b1db9299ebcd1&v=4" media="(prefers-color-scheme: dark)" height="26px" alt="Antony Konstantinidis" />
|
||||
<img src="https://avatars.githubusercontent.com/u/4183726?u=6b50a8ea16de29d2982f43c5640b1db9299ebcd1&v=4" height="26px" alt="Antony Konstantinidis" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://storyblok.com" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://posva-sponsors.pages.dev/logos/storyblok.png" media="(prefers-color-scheme: dark)" height="26px" alt="Storyblok" />
|
||||
<img src="https://posva-sponsors.pages.dev/logos/storyblok.png" height="26px" alt="Storyblok" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://nuxtjs.org" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source srcset="https://posva-sponsors.pages.dev/logos/nuxt-dark.svg" media="(prefers-color-scheme: dark)" height="26px" alt="NuxtJS" />
|
||||
<img src="https://posva-sponsors.pages.dev/logos/nuxt-light.svg" height="26px" alt="NuxtJS" />
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<!--sponsors end-->
|
||||
|
||||
---
|
||||
|
||||
Get started with the [documentation](http://router.vuejs.org), or play with the [examples](https://github.com/vuejs/vue-router/tree/dev/examples) (see how to run them below).
|
||||
|
||||
### Development Setup
|
||||
|
||||
```bash
|
||||
# install deps
|
||||
npm install
|
||||
|
||||
# build dist files
|
||||
npm run build
|
||||
|
||||
# serve examples at localhost:8080
|
||||
npm run dev
|
||||
|
||||
# lint & run all tests
|
||||
npm test
|
||||
|
||||
# serve docs at localhost:8080
|
||||
npm run docs
|
||||
```
|
||||
|
||||
## Releasing
|
||||
|
||||
- `yarn run release`
|
||||
- Ensure tests are passing `yarn run test`
|
||||
- Build dist files `VERSION=<the_version> yarn run build`
|
||||
- Build changelog `yarn run changelog`
|
||||
- Commit dist files `git add dist CHANGELOG.md && git commit -m "[build $VERSION]"`
|
||||
- Publish a new version `npm version $VERSION --message "[release] $VERSION"
|
||||
- Push tags `git push origin refs/tags/v$VERSION && git push`
|
||||
- Publish to npm `npm publish`
|
||||
|
||||
## Questions
|
||||
|
||||
For questions and support please use the [Discord chat server](https://chat.vuejs.org) or [the official forum](http://forum.vuejs.org). The issue list of this repo is **exclusively** for bug reports and feature requests.
|
||||
|
||||
## Issues
|
||||
|
||||
Please make sure to read the [Issue Reporting Checklist](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#issue-reporting-guidelines) before opening an issue. Issues not conforming to the guidelines may be closed immediately.
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md) before making a pull request.
|
||||
|
||||
## Changelog
|
||||
|
||||
Details changes for each release are documented in the [`CHANGELOG.md file`](https://github.com/vuejs/vue-router/blob/dev/CHANGELOG.md).
|
||||
|
||||
## Stay In Touch
|
||||
|
||||
- For latest releases and announcements, follow on Twitter: [@vuejs](https://twitter.com/vuejs)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](http://opensource.org/licenses/MIT)
|
||||
|
||||
Copyright (c) 2013-present Evan You
|
||||
|
||||
## Special Thanks
|
||||
|
||||
<a href="https://www.browserstack.com">
|
||||
<img src="/assets/browserstack-logo-600x315.png" height="80" title="BrowserStack Logo" alt="BrowserStack Logo" />
|
||||
</a>
|
||||
|
||||
Special thanks to [BrowserStack](https://www.browserstack.com) for letting the maintainers use their service to debug browser specific issues.
|
1
node_modules/vue-router/composables.d.ts
generated
vendored
Normal file
1
node_modules/vue-router/composables.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './types/composables'
|
257
node_modules/vue-router/composables.js
generated
vendored
Normal file
257
node_modules/vue-router/composables.js
generated
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
/*!
|
||||
* vue-router v3.6.5
|
||||
* (c) 2022 Evan You
|
||||
* @license MIT
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
|
||||
var vue = require('vue')
|
||||
|
||||
// dev only warn if no current instance
|
||||
|
||||
function throwNoCurrentInstance (method) {
|
||||
if (!vue.getCurrentInstance()) {
|
||||
throw new Error(
|
||||
('[vue-router]: Missing current instance. ' + method + '() must be called inside <script setup> or setup().')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function useRouter () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRouter')
|
||||
}
|
||||
|
||||
return vue.getCurrentInstance().proxy.$root.$router
|
||||
}
|
||||
|
||||
function useRoute () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRoute')
|
||||
}
|
||||
|
||||
var root = vue.getCurrentInstance().proxy.$root
|
||||
if (!root._$route) {
|
||||
var route = vue.effectScope(true).run(function () { return vue.shallowReactive(Object.assign({}, root.$router.currentRoute)) }
|
||||
)
|
||||
root._$route = route
|
||||
|
||||
root.$router.afterEach(function (to) {
|
||||
Object.assign(route, to)
|
||||
})
|
||||
}
|
||||
|
||||
return root._$route
|
||||
}
|
||||
|
||||
function onBeforeRouteUpdate (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteUpdate')
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isUpdateNavigation)
|
||||
}
|
||||
function isUpdateNavigation (to, from, depth) {
|
||||
var toMatched = to.matched
|
||||
var fromMatched = from.matched
|
||||
return (
|
||||
toMatched.length >= depth &&
|
||||
toMatched
|
||||
.slice(0, depth + 1)
|
||||
.every(function (record, i) { return record === fromMatched[i] })
|
||||
)
|
||||
}
|
||||
|
||||
function isLeaveNavigation (to, from, depth) {
|
||||
var toMatched = to.matched
|
||||
var fromMatched = from.matched
|
||||
return toMatched.length < depth || toMatched[depth] !== fromMatched[depth]
|
||||
}
|
||||
|
||||
function onBeforeRouteLeave (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteLeave')
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isLeaveNavigation)
|
||||
}
|
||||
|
||||
var noop = function () {}
|
||||
function useFilteredGuard (guard, fn) {
|
||||
var instance = vue.getCurrentInstance()
|
||||
var router = useRouter()
|
||||
|
||||
var target = instance.proxy
|
||||
// find the nearest RouterView to know the depth
|
||||
while (
|
||||
target &&
|
||||
target.$vnode &&
|
||||
target.$vnode.data &&
|
||||
target.$vnode.data.routerViewDepth == null
|
||||
) {
|
||||
target = target.$parent
|
||||
}
|
||||
|
||||
var depth =
|
||||
target && target.$vnode && target.$vnode.data
|
||||
? target.$vnode.data.routerViewDepth
|
||||
: null
|
||||
|
||||
if (depth != null) {
|
||||
var removeGuard = router.beforeEach(function (to, from, next) {
|
||||
return fn(to, from, depth) ? guard(to, from, next) : next()
|
||||
})
|
||||
|
||||
vue.onUnmounted(removeGuard)
|
||||
return removeGuard
|
||||
}
|
||||
|
||||
return noop
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
function guardEvent (e) {
|
||||
// don't redirect with control keys
|
||||
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
|
||||
// don't redirect when preventDefault called
|
||||
if (e.defaultPrevented) { return }
|
||||
// don't redirect on right click
|
||||
if (e.button !== undefined && e.button !== 0) { return }
|
||||
// don't redirect if `target="_blank"`
|
||||
if (e.currentTarget && e.currentTarget.getAttribute) {
|
||||
var target = e.currentTarget.getAttribute('target')
|
||||
if (/\b_blank\b/i.test(target)) { return }
|
||||
}
|
||||
// this may be a Weex event which doesn't have this method
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function includesParams (outer, inner) {
|
||||
var loop = function (key) {
|
||||
var innerValue = inner[key]
|
||||
var outerValue = outer[key]
|
||||
if (typeof innerValue === 'string') {
|
||||
if (innerValue !== outerValue) { return { v: false } }
|
||||
} else {
|
||||
if (
|
||||
!Array.isArray(outerValue) ||
|
||||
outerValue.length !== innerValue.length ||
|
||||
innerValue.some(function (value, i) { return value !== outerValue[i] })
|
||||
) {
|
||||
return { v: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in inner) {
|
||||
var returned = loop(key)
|
||||
|
||||
if (returned) return returned.v
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// helpers from vue router 4
|
||||
|
||||
function isSameRouteLocationParamsValue (a, b) {
|
||||
return Array.isArray(a)
|
||||
? isEquivalentArray(a, b)
|
||||
: Array.isArray(b)
|
||||
? isEquivalentArray(b, a)
|
||||
: a === b
|
||||
}
|
||||
|
||||
function isEquivalentArray (a, b) {
|
||||
return Array.isArray(b)
|
||||
? a.length === b.length && a.every(function (value, i) { return value === b[i] })
|
||||
: a.length === 1 && a[0] === b
|
||||
}
|
||||
|
||||
function isSameRouteLocationParams (a, b) {
|
||||
if (Object.keys(a).length !== Object.keys(b).length) { return false }
|
||||
|
||||
for (var key in a) {
|
||||
if (!isSameRouteLocationParamsValue(a[key], b[key])) { return false }
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function useLink (props) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useLink')
|
||||
}
|
||||
|
||||
var router = useRouter()
|
||||
var currentRoute = useRoute()
|
||||
|
||||
var resolvedRoute = vue.computed(function () { return router.resolve(vue.unref(props.to), currentRoute) })
|
||||
|
||||
var activeRecordIndex = vue.computed(function () {
|
||||
var route = resolvedRoute.value.route
|
||||
var matched = route.matched
|
||||
var length = matched.length
|
||||
var routeMatched = matched[length - 1]
|
||||
var currentMatched = currentRoute.matched
|
||||
if (!routeMatched || !currentMatched.length) { return -1 }
|
||||
var index = currentMatched.indexOf(routeMatched)
|
||||
if (index > -1) { return index }
|
||||
// possible parent record
|
||||
var parentRecord = currentMatched[currentMatched.length - 2]
|
||||
|
||||
return (
|
||||
// we are dealing with nested routes
|
||||
length > 1 &&
|
||||
// if the parent and matched route have the same path, this link is
|
||||
// referring to the empty child. Or we currently are on a different
|
||||
// child of the same parent
|
||||
parentRecord && parentRecord === routeMatched.parent
|
||||
)
|
||||
})
|
||||
|
||||
var isActive = vue.computed(
|
||||
function () {
|
||||
return activeRecordIndex.value > -1 &&
|
||||
includesParams(currentRoute.params, resolvedRoute.value.route.params)
|
||||
}
|
||||
)
|
||||
var isExactActive = vue.computed(
|
||||
function () {
|
||||
return activeRecordIndex.value > -1 &&
|
||||
activeRecordIndex.value === currentRoute.matched.length - 1 &&
|
||||
isSameRouteLocationParams(currentRoute.params, resolvedRoute.value.route.params)
|
||||
}
|
||||
)
|
||||
|
||||
var navigate = function (e) {
|
||||
var href = resolvedRoute.value.route
|
||||
if (guardEvent(e)) {
|
||||
return props.replace
|
||||
? router.replace(href)
|
||||
: router.push(href)
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return {
|
||||
href: vue.computed(function () { return resolvedRoute.value.href }),
|
||||
route: vue.computed(function () { return resolvedRoute.value.route }),
|
||||
isExactActive: isExactActive,
|
||||
isActive: isActive,
|
||||
navigate: navigate
|
||||
}
|
||||
}
|
||||
|
||||
exports.isSameRouteLocationParams = isSameRouteLocationParams
|
||||
exports.onBeforeRouteLeave = onBeforeRouteLeave
|
||||
exports.onBeforeRouteUpdate = onBeforeRouteUpdate
|
||||
exports.useLink = useLink
|
||||
exports.useRoute = useRoute
|
||||
exports.useRouter = useRouter
|
244
node_modules/vue-router/composables.mjs
generated
vendored
Normal file
244
node_modules/vue-router/composables.mjs
generated
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
/*!
|
||||
* vue-router v3.6.5
|
||||
* (c) 2022 Evan You
|
||||
* @license MIT
|
||||
*/
|
||||
import { getCurrentInstance, effectScope, shallowReactive, onUnmounted, computed, unref } from 'vue';
|
||||
|
||||
// dev only warn if no current instance
|
||||
|
||||
function throwNoCurrentInstance (method) {
|
||||
if (!getCurrentInstance()) {
|
||||
throw new Error(
|
||||
("[vue-router]: Missing current instance. " + method + "() must be called inside <script setup> or setup().")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function useRouter () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRouter');
|
||||
}
|
||||
|
||||
return getCurrentInstance().proxy.$root.$router
|
||||
}
|
||||
|
||||
function useRoute () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRoute');
|
||||
}
|
||||
|
||||
var root = getCurrentInstance().proxy.$root;
|
||||
if (!root._$route) {
|
||||
var route = effectScope(true).run(function () { return shallowReactive(Object.assign({}, root.$router.currentRoute)); }
|
||||
);
|
||||
root._$route = route;
|
||||
|
||||
root.$router.afterEach(function (to) {
|
||||
Object.assign(route, to);
|
||||
});
|
||||
}
|
||||
|
||||
return root._$route
|
||||
}
|
||||
|
||||
function onBeforeRouteUpdate (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteUpdate');
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isUpdateNavigation)
|
||||
}
|
||||
function isUpdateNavigation (to, from, depth) {
|
||||
var toMatched = to.matched;
|
||||
var fromMatched = from.matched;
|
||||
return (
|
||||
toMatched.length >= depth &&
|
||||
toMatched
|
||||
.slice(0, depth + 1)
|
||||
.every(function (record, i) { return record === fromMatched[i]; })
|
||||
)
|
||||
}
|
||||
|
||||
function isLeaveNavigation (to, from, depth) {
|
||||
var toMatched = to.matched;
|
||||
var fromMatched = from.matched;
|
||||
return toMatched.length < depth || toMatched[depth] !== fromMatched[depth]
|
||||
}
|
||||
|
||||
function onBeforeRouteLeave (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteLeave');
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isLeaveNavigation)
|
||||
}
|
||||
|
||||
var noop = function () {};
|
||||
function useFilteredGuard (guard, fn) {
|
||||
var instance = getCurrentInstance();
|
||||
var router = useRouter();
|
||||
|
||||
var target = instance.proxy;
|
||||
// find the nearest RouterView to know the depth
|
||||
while (
|
||||
target &&
|
||||
target.$vnode &&
|
||||
target.$vnode.data &&
|
||||
target.$vnode.data.routerViewDepth == null
|
||||
) {
|
||||
target = target.$parent;
|
||||
}
|
||||
|
||||
var depth =
|
||||
target && target.$vnode && target.$vnode.data
|
||||
? target.$vnode.data.routerViewDepth
|
||||
: null;
|
||||
|
||||
if (depth != null) {
|
||||
var removeGuard = router.beforeEach(function (to, from, next) {
|
||||
return fn(to, from, depth) ? guard(to, from, next) : next()
|
||||
});
|
||||
|
||||
onUnmounted(removeGuard);
|
||||
return removeGuard
|
||||
}
|
||||
|
||||
return noop
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
function guardEvent (e) {
|
||||
// don't redirect with control keys
|
||||
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
|
||||
// don't redirect when preventDefault called
|
||||
if (e.defaultPrevented) { return }
|
||||
// don't redirect on right click
|
||||
if (e.button !== undefined && e.button !== 0) { return }
|
||||
// don't redirect if `target="_blank"`
|
||||
if (e.currentTarget && e.currentTarget.getAttribute) {
|
||||
var target = e.currentTarget.getAttribute('target');
|
||||
if (/\b_blank\b/i.test(target)) { return }
|
||||
}
|
||||
// this may be a Weex event which doesn't have this method
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function includesParams (outer, inner) {
|
||||
var loop = function ( key ) {
|
||||
var innerValue = inner[key];
|
||||
var outerValue = outer[key];
|
||||
if (typeof innerValue === 'string') {
|
||||
if (innerValue !== outerValue) { return { v: false } }
|
||||
} else {
|
||||
if (
|
||||
!Array.isArray(outerValue) ||
|
||||
outerValue.length !== innerValue.length ||
|
||||
innerValue.some(function (value, i) { return value !== outerValue[i]; })
|
||||
) {
|
||||
return { v: false }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (var key in inner) {
|
||||
var returned = loop( key );
|
||||
|
||||
if ( returned ) return returned.v;
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// helpers from vue router 4
|
||||
|
||||
function isSameRouteLocationParamsValue (a, b) {
|
||||
return Array.isArray(a)
|
||||
? isEquivalentArray(a, b)
|
||||
: Array.isArray(b)
|
||||
? isEquivalentArray(b, a)
|
||||
: a === b
|
||||
}
|
||||
|
||||
function isEquivalentArray (a, b) {
|
||||
return Array.isArray(b)
|
||||
? a.length === b.length && a.every(function (value, i) { return value === b[i]; })
|
||||
: a.length === 1 && a[0] === b
|
||||
}
|
||||
|
||||
function isSameRouteLocationParams (a, b) {
|
||||
if (Object.keys(a).length !== Object.keys(b).length) { return false }
|
||||
|
||||
for (var key in a) {
|
||||
if (!isSameRouteLocationParamsValue(a[key], b[key])) { return false }
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function useLink (props) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useLink');
|
||||
}
|
||||
|
||||
var router = useRouter();
|
||||
var currentRoute = useRoute();
|
||||
|
||||
var resolvedRoute = computed(function () { return router.resolve(unref(props.to), currentRoute); });
|
||||
|
||||
var activeRecordIndex = computed(function () {
|
||||
var route = resolvedRoute.value.route;
|
||||
var matched = route.matched;
|
||||
var length = matched.length;
|
||||
var routeMatched = matched[length - 1];
|
||||
var currentMatched = currentRoute.matched;
|
||||
if (!routeMatched || !currentMatched.length) { return -1 }
|
||||
var index = currentMatched.indexOf(routeMatched);
|
||||
if (index > -1) { return index }
|
||||
// possible parent record
|
||||
var parentRecord = currentMatched[currentMatched.length - 2];
|
||||
|
||||
return (
|
||||
// we are dealing with nested routes
|
||||
length > 1 &&
|
||||
// if the parent and matched route have the same path, this link is
|
||||
// referring to the empty child. Or we currently are on a different
|
||||
// child of the same parent
|
||||
parentRecord && parentRecord === routeMatched.parent
|
||||
)
|
||||
});
|
||||
|
||||
var isActive = computed(
|
||||
function () { return activeRecordIndex.value > -1 &&
|
||||
includesParams(currentRoute.params, resolvedRoute.value.route.params); }
|
||||
);
|
||||
var isExactActive = computed(
|
||||
function () { return activeRecordIndex.value > -1 &&
|
||||
activeRecordIndex.value === currentRoute.matched.length - 1 &&
|
||||
isSameRouteLocationParams(currentRoute.params, resolvedRoute.value.route.params); }
|
||||
);
|
||||
|
||||
var navigate = function (e) {
|
||||
var href = resolvedRoute.value.route;
|
||||
if (guardEvent(e)) {
|
||||
return props.replace
|
||||
? router.replace(href)
|
||||
: router.push(href)
|
||||
}
|
||||
return Promise.resolve()
|
||||
};
|
||||
|
||||
return {
|
||||
href: computed(function () { return resolvedRoute.value.href; }),
|
||||
route: computed(function () { return resolvedRoute.value.route; }),
|
||||
isExactActive: isExactActive,
|
||||
isActive: isActive,
|
||||
navigate: navigate
|
||||
}
|
||||
}
|
||||
|
||||
export { isSameRouteLocationParams, onBeforeRouteLeave, onBeforeRouteUpdate, useLink, useRoute, useRouter };
|
3159
node_modules/vue-router/dist/vue-router.common.js
generated
vendored
Normal file
3159
node_modules/vue-router/dist/vue-router.common.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3125
node_modules/vue-router/dist/vue-router.esm.browser.js
generated
vendored
Normal file
3125
node_modules/vue-router/dist/vue-router.esm.browser.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
node_modules/vue-router/dist/vue-router.esm.browser.min.js
generated
vendored
Normal file
11
node_modules/vue-router/dist/vue-router.esm.browser.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3159
node_modules/vue-router/dist/vue-router.esm.js
generated
vendored
Normal file
3159
node_modules/vue-router/dist/vue-router.esm.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3164
node_modules/vue-router/dist/vue-router.js
generated
vendored
Normal file
3164
node_modules/vue-router/dist/vue-router.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
node_modules/vue-router/dist/vue-router.min.js
generated
vendored
Normal file
11
node_modules/vue-router/dist/vue-router.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3159
node_modules/vue-router/dist/vue-router.mjs
generated
vendored
Normal file
3159
node_modules/vue-router/dist/vue-router.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
166
node_modules/vue-router/package.json
generated
vendored
Normal file
166
node_modules/vue-router/package.json
generated
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
{
|
||||
"_from": "vue-router@3.6.5",
|
||||
"_id": "vue-router@3.6.5",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==",
|
||||
"_location": "/vue-router",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "vue-router@3.6.5",
|
||||
"name": "vue-router",
|
||||
"escapedName": "vue-router",
|
||||
"rawSpec": "3.6.5",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.6.5"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz",
|
||||
"_shasum": "95847d52b9a7e3f1361cb605c8e6441f202afad8",
|
||||
"_spec": "vue-router@3.6.5",
|
||||
"_where": "C:\\Users\\zhouxueli\\Desktop\\scheduling-app",
|
||||
"author": {
|
||||
"name": "Evan You"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vuejs/vue-router/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Official router for Vue.js 2",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.0.0",
|
||||
"@vuepress/plugin-pwa": "^1.5.3",
|
||||
"@vuepress/theme-vue": "^1.5.3",
|
||||
"axios": "^0.21.1",
|
||||
"babel-core": "^6.24.1",
|
||||
"babel-eslint": "^10.0.2",
|
||||
"babel-loader": "^7.1.3",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-flow-vue": "^1.0.0",
|
||||
"browserstack-local": "^1.4.8",
|
||||
"buble": "^0.19.8",
|
||||
"chromedriver": "^96.0.0",
|
||||
"conventional-changelog-cli": "^2.0.11",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"css-loader": "^2.1.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"es6-promise": "^4.2.8",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-plugin-flowtype": "^2.46.1",
|
||||
"eslint-plugin-jasmine": "^2.10.1",
|
||||
"eslint-plugin-vue-libs": "^2.1.0",
|
||||
"express": "^4.17.1",
|
||||
"express-urlrewrite": "^1.2.0",
|
||||
"flow-bin": "^0.66.0",
|
||||
"geckodriver": "^1.20.0",
|
||||
"jasmine": "2.8.0",
|
||||
"lint-staged": "^8.2.0",
|
||||
"nightwatch": "^1.3.6",
|
||||
"nightwatch-helpers": "^1.0.0",
|
||||
"path-to-regexp": "^1.8.0",
|
||||
"rollup": "^2.34.1",
|
||||
"rollup-plugin-buble": "^0.19.8",
|
||||
"rollup-plugin-flow-no-whitespace": "^1.0.0",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"rollup-watch": "^4.0.0",
|
||||
"selenium-server": "^3.141.59",
|
||||
"terser": "^4.2.0",
|
||||
"typescript": "^4.7.0",
|
||||
"vue": "^2.7.0",
|
||||
"vue-loader": "^15.9.3",
|
||||
"vue-server-renderer": "^2.7.0",
|
||||
"vue-template-compiler": "^2.7.0",
|
||||
"vuepress": "^1.5.3",
|
||||
"vuepress-theme-vue": "^1.1.1",
|
||||
"webpack": "^4.35.2",
|
||||
"webpack-dev-middleware": "^3.7.0",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"node": "./dist/vue-router.mjs",
|
||||
"default": "./dist/vue-router.esm.js"
|
||||
},
|
||||
"require": "./dist/vue-router.common.js",
|
||||
"types": "./types/index.d.ts"
|
||||
},
|
||||
"./composables": {
|
||||
"import": "./composables.mjs",
|
||||
"require": "./composables.js",
|
||||
"types": "./composables.d.ts"
|
||||
},
|
||||
"./dist/*": "./dist/*",
|
||||
"./types/*": "./types/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist/*.js",
|
||||
"dist/*.mjs",
|
||||
"types/*.d.ts",
|
||||
"composables.mjs",
|
||||
"composables.js",
|
||||
"composables.d.ts",
|
||||
"vetur/tags.json",
|
||||
"vetur/attributes.json"
|
||||
],
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"commit-msg": "node scripts/verifyCommitMsg.js"
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-router#readme",
|
||||
"jsdelivr": "dist/vue-router.js",
|
||||
"keywords": [
|
||||
"vue",
|
||||
"router",
|
||||
"routing"
|
||||
],
|
||||
"license": "MIT",
|
||||
"lint-staged": {
|
||||
"*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"main": "dist/vue-router.common.js",
|
||||
"module": "dist/vue-router.esm.js",
|
||||
"name": "vue-router",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-router.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build/build.js",
|
||||
"changelog": "conventional-changelog -p angular -r 2 -i CHANGELOG.md -s",
|
||||
"commit": "git-cz",
|
||||
"dev": "node examples/server.js",
|
||||
"dev:dist": "rollup -wm -c build/rollup.dev.config.js",
|
||||
"docs": "vuepress dev docs",
|
||||
"docs:build": "vuepress build docs",
|
||||
"flow": "flow check",
|
||||
"lint": "eslint src examples test",
|
||||
"release": "bash scripts/release.sh",
|
||||
"test": "npm run lint && npm run flow && npm run test:unit && npm run test:e2e && npm run test:types",
|
||||
"test:e2e": "node test/e2e/runner.js",
|
||||
"test:e2e:ci": "node test/e2e/runner.js --local -e ie,android44 -c test/e2e/nightwatch.browserstack.js test/e2e/specs/active-links.js",
|
||||
"test:e2e:ff": "node test/e2e/runner.js -e firefox -c test/e2e/nightwatch.config.js",
|
||||
"test:e2e:ie9": "node test/e2e/runner.js --local -e ie9 -c test/e2e/nightwatch.browserstack.js --skiptags history,ie9-fail",
|
||||
"test:types": "tsc -p types/test",
|
||||
"test:unit": "jasmine JASMINE_CONFIG_PATH=test/unit/jasmine.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"typings": "types/index.d.ts",
|
||||
"unpkg": "dist/vue-router.js",
|
||||
"version": "3.6.5",
|
||||
"vetur": {
|
||||
"tags": "vetur/tags.json",
|
||||
"attributes": "vetur/attributes.json"
|
||||
}
|
||||
}
|
224
node_modules/vue-router/src/components/link.js
generated
vendored
Normal file
224
node_modules/vue-router/src/components/link.js
generated
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/* @flow */
|
||||
|
||||
import { createRoute, isSameRoute, isIncludedRoute } from '../util/route'
|
||||
import { extend } from '../util/misc'
|
||||
import { normalizeLocation } from '../util/location'
|
||||
import { warn } from '../util/warn'
|
||||
|
||||
// work around weird flow bug
|
||||
const toTypes: Array<Function> = [String, Object]
|
||||
const eventTypes: Array<Function> = [String, Array]
|
||||
|
||||
const noop = () => {}
|
||||
|
||||
let warnedCustomSlot
|
||||
let warnedTagProp
|
||||
let warnedEventProp
|
||||
|
||||
export default {
|
||||
name: 'RouterLink',
|
||||
props: {
|
||||
to: {
|
||||
type: toTypes,
|
||||
required: true
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'a'
|
||||
},
|
||||
custom: Boolean,
|
||||
exact: Boolean,
|
||||
exactPath: Boolean,
|
||||
append: Boolean,
|
||||
replace: Boolean,
|
||||
activeClass: String,
|
||||
exactActiveClass: String,
|
||||
ariaCurrentValue: {
|
||||
type: String,
|
||||
default: 'page'
|
||||
},
|
||||
event: {
|
||||
type: eventTypes,
|
||||
default: 'click'
|
||||
}
|
||||
},
|
||||
render (h: Function) {
|
||||
const router = this.$router
|
||||
const current = this.$route
|
||||
const { location, route, href } = router.resolve(
|
||||
this.to,
|
||||
current,
|
||||
this.append
|
||||
)
|
||||
|
||||
const classes = {}
|
||||
const globalActiveClass = router.options.linkActiveClass
|
||||
const globalExactActiveClass = router.options.linkExactActiveClass
|
||||
// Support global empty active class
|
||||
const activeClassFallback =
|
||||
globalActiveClass == null ? 'router-link-active' : globalActiveClass
|
||||
const exactActiveClassFallback =
|
||||
globalExactActiveClass == null
|
||||
? 'router-link-exact-active'
|
||||
: globalExactActiveClass
|
||||
const activeClass =
|
||||
this.activeClass == null ? activeClassFallback : this.activeClass
|
||||
const exactActiveClass =
|
||||
this.exactActiveClass == null
|
||||
? exactActiveClassFallback
|
||||
: this.exactActiveClass
|
||||
|
||||
const compareTarget = route.redirectedFrom
|
||||
? createRoute(null, normalizeLocation(route.redirectedFrom), null, router)
|
||||
: route
|
||||
|
||||
classes[exactActiveClass] = isSameRoute(current, compareTarget, this.exactPath)
|
||||
classes[activeClass] = this.exact || this.exactPath
|
||||
? classes[exactActiveClass]
|
||||
: isIncludedRoute(current, compareTarget)
|
||||
|
||||
const ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null
|
||||
|
||||
const handler = e => {
|
||||
if (guardEvent(e)) {
|
||||
if (this.replace) {
|
||||
router.replace(location, noop)
|
||||
} else {
|
||||
router.push(location, noop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const on = { click: guardEvent }
|
||||
if (Array.isArray(this.event)) {
|
||||
this.event.forEach(e => {
|
||||
on[e] = handler
|
||||
})
|
||||
} else {
|
||||
on[this.event] = handler
|
||||
}
|
||||
|
||||
const data: any = { class: classes }
|
||||
|
||||
const scopedSlot =
|
||||
!this.$scopedSlots.$hasNormal &&
|
||||
this.$scopedSlots.default &&
|
||||
this.$scopedSlots.default({
|
||||
href,
|
||||
route,
|
||||
navigate: handler,
|
||||
isActive: classes[activeClass],
|
||||
isExactActive: classes[exactActiveClass]
|
||||
})
|
||||
|
||||
if (scopedSlot) {
|
||||
if (process.env.NODE_ENV !== 'production' && !this.custom) {
|
||||
!warnedCustomSlot && warn(false, 'In Vue Router 4, the v-slot API will by default wrap its content with an <a> element. Use the custom prop to remove this warning:\n<router-link v-slot="{ navigate, href }" custom></router-link>\n')
|
||||
warnedCustomSlot = true
|
||||
}
|
||||
if (scopedSlot.length === 1) {
|
||||
return scopedSlot[0]
|
||||
} else if (scopedSlot.length > 1 || !scopedSlot.length) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
false,
|
||||
`<router-link> with to="${
|
||||
this.to
|
||||
}" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.`
|
||||
)
|
||||
}
|
||||
return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot)
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if ('tag' in this.$options.propsData && !warnedTagProp) {
|
||||
warn(
|
||||
false,
|
||||
`<router-link>'s tag prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link.`
|
||||
)
|
||||
warnedTagProp = true
|
||||
}
|
||||
if ('event' in this.$options.propsData && !warnedEventProp) {
|
||||
warn(
|
||||
false,
|
||||
`<router-link>'s event prop is deprecated and has been removed in Vue Router 4. Use the v-slot API to remove this warning: https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link.`
|
||||
)
|
||||
warnedEventProp = true
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tag === 'a') {
|
||||
data.on = on
|
||||
data.attrs = { href, 'aria-current': ariaCurrentValue }
|
||||
} else {
|
||||
// find the first <a> child and apply listener and href
|
||||
const a = findAnchor(this.$slots.default)
|
||||
if (a) {
|
||||
// in case the <a> is a static node
|
||||
a.isStatic = false
|
||||
const aData = (a.data = extend({}, a.data))
|
||||
aData.on = aData.on || {}
|
||||
// transform existing events in both objects into arrays so we can push later
|
||||
for (const event in aData.on) {
|
||||
const handler = aData.on[event]
|
||||
if (event in on) {
|
||||
aData.on[event] = Array.isArray(handler) ? handler : [handler]
|
||||
}
|
||||
}
|
||||
// append new listeners for router-link
|
||||
for (const event in on) {
|
||||
if (event in aData.on) {
|
||||
// on[event] is always a function
|
||||
aData.on[event].push(on[event])
|
||||
} else {
|
||||
aData.on[event] = handler
|
||||
}
|
||||
}
|
||||
|
||||
const aAttrs = (a.data.attrs = extend({}, a.data.attrs))
|
||||
aAttrs.href = href
|
||||
aAttrs['aria-current'] = ariaCurrentValue
|
||||
} else {
|
||||
// doesn't have <a> child, apply listener to self
|
||||
data.on = on
|
||||
}
|
||||
}
|
||||
|
||||
return h(this.tag, data, this.$slots.default)
|
||||
}
|
||||
}
|
||||
|
||||
export function guardEvent (e: any) {
|
||||
// don't redirect with control keys
|
||||
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return
|
||||
// don't redirect when preventDefault called
|
||||
if (e.defaultPrevented) return
|
||||
// don't redirect on right click
|
||||
if (e.button !== undefined && e.button !== 0) return
|
||||
// don't redirect if `target="_blank"`
|
||||
if (e.currentTarget && e.currentTarget.getAttribute) {
|
||||
const target = e.currentTarget.getAttribute('target')
|
||||
if (/\b_blank\b/i.test(target)) return
|
||||
}
|
||||
// this may be a Weex event which doesn't have this method
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function findAnchor (children) {
|
||||
if (children) {
|
||||
let child
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
child = children[i]
|
||||
if (child.tag === 'a') {
|
||||
return child
|
||||
}
|
||||
if (child.children && (child = findAnchor(child.children))) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
155
node_modules/vue-router/src/components/view.js
generated
vendored
Normal file
155
node_modules/vue-router/src/components/view.js
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
import { warn } from '../util/warn'
|
||||
import { extend } from '../util/misc'
|
||||
import { handleRouteEntered } from '../util/route'
|
||||
|
||||
export default {
|
||||
name: 'RouterView',
|
||||
functional: true,
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: 'default'
|
||||
}
|
||||
},
|
||||
render (_, { props, children, parent, data }) {
|
||||
// used by devtools to display a router-view badge
|
||||
data.routerView = true
|
||||
|
||||
// directly use parent context's createElement() function
|
||||
// so that components rendered by router-view can resolve named slots
|
||||
const h = parent.$createElement
|
||||
const name = props.name
|
||||
const route = parent.$route
|
||||
const cache = parent._routerViewCache || (parent._routerViewCache = {})
|
||||
|
||||
// determine current view depth, also check to see if the tree
|
||||
// has been toggled inactive but kept-alive.
|
||||
let depth = 0
|
||||
let inactive = false
|
||||
while (parent && parent._routerRoot !== parent) {
|
||||
const vnodeData = parent.$vnode ? parent.$vnode.data : {}
|
||||
if (vnodeData.routerView) {
|
||||
depth++
|
||||
}
|
||||
if (vnodeData.keepAlive && parent._directInactive && parent._inactive) {
|
||||
inactive = true
|
||||
}
|
||||
parent = parent.$parent
|
||||
}
|
||||
data.routerViewDepth = depth
|
||||
|
||||
// render previous view if the tree is inactive and kept-alive
|
||||
if (inactive) {
|
||||
const cachedData = cache[name]
|
||||
const cachedComponent = cachedData && cachedData.component
|
||||
if (cachedComponent) {
|
||||
// #2301
|
||||
// pass props
|
||||
if (cachedData.configProps) {
|
||||
fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps)
|
||||
}
|
||||
return h(cachedComponent, data, children)
|
||||
} else {
|
||||
// render previous empty view
|
||||
return h()
|
||||
}
|
||||
}
|
||||
|
||||
const matched = route.matched[depth]
|
||||
const component = matched && matched.components[name]
|
||||
|
||||
// render empty node if no matched route or no config component
|
||||
if (!matched || !component) {
|
||||
cache[name] = null
|
||||
return h()
|
||||
}
|
||||
|
||||
// cache component
|
||||
cache[name] = { component }
|
||||
|
||||
// attach instance registration hook
|
||||
// this will be called in the instance's injected lifecycle hooks
|
||||
data.registerRouteInstance = (vm, val) => {
|
||||
// val could be undefined for unregistration
|
||||
const current = matched.instances[name]
|
||||
if (
|
||||
(val && current !== vm) ||
|
||||
(!val && current === vm)
|
||||
) {
|
||||
matched.instances[name] = val
|
||||
}
|
||||
}
|
||||
|
||||
// also register instance in prepatch hook
|
||||
// in case the same component instance is reused across different routes
|
||||
;(data.hook || (data.hook = {})).prepatch = (_, vnode) => {
|
||||
matched.instances[name] = vnode.componentInstance
|
||||
}
|
||||
|
||||
// register instance in init hook
|
||||
// in case kept-alive component be actived when routes changed
|
||||
data.hook.init = (vnode) => {
|
||||
if (vnode.data.keepAlive &&
|
||||
vnode.componentInstance &&
|
||||
vnode.componentInstance !== matched.instances[name]
|
||||
) {
|
||||
matched.instances[name] = vnode.componentInstance
|
||||
}
|
||||
|
||||
// if the route transition has already been confirmed then we weren't
|
||||
// able to call the cbs during confirmation as the component was not
|
||||
// registered yet, so we call it here.
|
||||
handleRouteEntered(route)
|
||||
}
|
||||
|
||||
const configProps = matched.props && matched.props[name]
|
||||
// save route and configProps in cache
|
||||
if (configProps) {
|
||||
extend(cache[name], {
|
||||
route,
|
||||
configProps
|
||||
})
|
||||
fillPropsinData(component, data, route, configProps)
|
||||
}
|
||||
|
||||
return h(component, data, children)
|
||||
}
|
||||
}
|
||||
|
||||
function fillPropsinData (component, data, route, configProps) {
|
||||
// resolve props
|
||||
let propsToPass = data.props = resolveProps(route, configProps)
|
||||
if (propsToPass) {
|
||||
// clone to prevent mutation
|
||||
propsToPass = data.props = extend({}, propsToPass)
|
||||
// pass non-declared props as attrs
|
||||
const attrs = data.attrs = data.attrs || {}
|
||||
for (const key in propsToPass) {
|
||||
if (!component.props || !(key in component.props)) {
|
||||
attrs[key] = propsToPass[key]
|
||||
delete propsToPass[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveProps (route, config) {
|
||||
switch (typeof config) {
|
||||
case 'undefined':
|
||||
return
|
||||
case 'object':
|
||||
return config
|
||||
case 'function':
|
||||
return config(route)
|
||||
case 'boolean':
|
||||
return config ? route.params : undefined
|
||||
default:
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
false,
|
||||
`props in "${route.path}" is a ${typeof config}, ` +
|
||||
`expecting an object, function or boolean.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
34
node_modules/vue-router/src/composables/globals.js
generated
vendored
Normal file
34
node_modules/vue-router/src/composables/globals.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import {
|
||||
getCurrentInstance,
|
||||
shallowReactive,
|
||||
effectScope
|
||||
} from 'vue'
|
||||
import { throwNoCurrentInstance } from './utils'
|
||||
|
||||
export function useRouter () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRouter')
|
||||
}
|
||||
|
||||
return getCurrentInstance().proxy.$root.$router
|
||||
}
|
||||
|
||||
export function useRoute () {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useRoute')
|
||||
}
|
||||
|
||||
const root = getCurrentInstance().proxy.$root
|
||||
if (!root._$route) {
|
||||
const route = effectScope(true).run(() =>
|
||||
shallowReactive(Object.assign({}, root.$router.currentRoute))
|
||||
)
|
||||
root._$route = route
|
||||
|
||||
root.$router.afterEach(to => {
|
||||
Object.assign(route, to)
|
||||
})
|
||||
}
|
||||
|
||||
return root._$route
|
||||
}
|
68
node_modules/vue-router/src/composables/guards.js
generated
vendored
Normal file
68
node_modules/vue-router/src/composables/guards.js
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
import { getCurrentInstance, onUnmounted } from 'vue'
|
||||
import { throwNoCurrentInstance } from './utils'
|
||||
import { useRouter } from './globals'
|
||||
|
||||
export function onBeforeRouteUpdate (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteUpdate')
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isUpdateNavigation)
|
||||
}
|
||||
function isUpdateNavigation (to, from, depth) {
|
||||
const toMatched = to.matched
|
||||
const fromMatched = from.matched
|
||||
return (
|
||||
toMatched.length >= depth &&
|
||||
toMatched
|
||||
.slice(0, depth + 1)
|
||||
.every((record, i) => record === fromMatched[i])
|
||||
)
|
||||
}
|
||||
|
||||
function isLeaveNavigation (to, from, depth) {
|
||||
const toMatched = to.matched
|
||||
const fromMatched = from.matched
|
||||
return toMatched.length < depth || toMatched[depth] !== fromMatched[depth]
|
||||
}
|
||||
|
||||
export function onBeforeRouteLeave (guard) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('onBeforeRouteLeave')
|
||||
}
|
||||
|
||||
return useFilteredGuard(guard, isLeaveNavigation)
|
||||
}
|
||||
|
||||
const noop = () => {}
|
||||
function useFilteredGuard (guard, fn) {
|
||||
const instance = getCurrentInstance()
|
||||
const router = useRouter()
|
||||
|
||||
let target = instance.proxy
|
||||
// find the nearest RouterView to know the depth
|
||||
while (
|
||||
target &&
|
||||
target.$vnode &&
|
||||
target.$vnode.data &&
|
||||
target.$vnode.data.routerViewDepth == null
|
||||
) {
|
||||
target = target.$parent
|
||||
}
|
||||
|
||||
const depth =
|
||||
target && target.$vnode && target.$vnode.data
|
||||
? target.$vnode.data.routerViewDepth
|
||||
: null
|
||||
|
||||
if (depth != null) {
|
||||
const removeGuard = router.beforeEach((to, from, next) => {
|
||||
return fn(to, from, depth) ? guard(to, from, next) : next()
|
||||
})
|
||||
|
||||
onUnmounted(removeGuard)
|
||||
return removeGuard
|
||||
}
|
||||
|
||||
return noop
|
||||
}
|
3
node_modules/vue-router/src/composables/index.js
generated
vendored
Normal file
3
node_modules/vue-router/src/composables/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './guards'
|
||||
export * from './globals'
|
||||
export * from './useLink'
|
113
node_modules/vue-router/src/composables/useLink.js
generated
vendored
Normal file
113
node_modules/vue-router/src/composables/useLink.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
import { computed, unref } from 'vue'
|
||||
import { guardEvent } from '../components/link'
|
||||
import { throwNoCurrentInstance } from './utils'
|
||||
import { useRouter, useRoute } from './globals'
|
||||
|
||||
function includesParams (outer, inner) {
|
||||
for (const key in inner) {
|
||||
const innerValue = inner[key]
|
||||
const outerValue = outer[key]
|
||||
if (typeof innerValue === 'string') {
|
||||
if (innerValue !== outerValue) return false
|
||||
} else {
|
||||
if (
|
||||
!Array.isArray(outerValue) ||
|
||||
outerValue.length !== innerValue.length ||
|
||||
innerValue.some((value, i) => value !== outerValue[i])
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// helpers from vue router 4
|
||||
|
||||
function isSameRouteLocationParamsValue (a, b) {
|
||||
return Array.isArray(a)
|
||||
? isEquivalentArray(a, b)
|
||||
: Array.isArray(b)
|
||||
? isEquivalentArray(b, a)
|
||||
: a === b
|
||||
}
|
||||
|
||||
function isEquivalentArray (a, b) {
|
||||
return Array.isArray(b)
|
||||
? a.length === b.length && a.every((value, i) => value === b[i])
|
||||
: a.length === 1 && a[0] === b
|
||||
}
|
||||
|
||||
export function isSameRouteLocationParams (a, b) {
|
||||
if (Object.keys(a).length !== Object.keys(b).length) return false
|
||||
|
||||
for (const key in a) {
|
||||
if (!isSameRouteLocationParamsValue(a[key], b[key])) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export function useLink (props) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throwNoCurrentInstance('useLink')
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
const currentRoute = useRoute()
|
||||
|
||||
const resolvedRoute = computed(() => router.resolve(unref(props.to), currentRoute))
|
||||
|
||||
const activeRecordIndex = computed(() => {
|
||||
const route = resolvedRoute.value.route
|
||||
const { matched } = route
|
||||
const { length } = matched
|
||||
const routeMatched = matched[length - 1]
|
||||
const currentMatched = currentRoute.matched
|
||||
if (!routeMatched || !currentMatched.length) return -1
|
||||
const index = currentMatched.indexOf(routeMatched)
|
||||
if (index > -1) return index
|
||||
// possible parent record
|
||||
const parentRecord = currentMatched[currentMatched.length - 2]
|
||||
|
||||
return (
|
||||
// we are dealing with nested routes
|
||||
length > 1 &&
|
||||
// if the parent and matched route have the same path, this link is
|
||||
// referring to the empty child. Or we currently are on a different
|
||||
// child of the same parent
|
||||
parentRecord && parentRecord === routeMatched.parent
|
||||
)
|
||||
})
|
||||
|
||||
const isActive = computed(
|
||||
() =>
|
||||
activeRecordIndex.value > -1 &&
|
||||
includesParams(currentRoute.params, resolvedRoute.value.route.params)
|
||||
)
|
||||
const isExactActive = computed(
|
||||
() =>
|
||||
activeRecordIndex.value > -1 &&
|
||||
activeRecordIndex.value === currentRoute.matched.length - 1 &&
|
||||
isSameRouteLocationParams(currentRoute.params, resolvedRoute.value.route.params)
|
||||
)
|
||||
|
||||
const navigate = e => {
|
||||
const href = resolvedRoute.value.route
|
||||
if (guardEvent(e)) {
|
||||
return props.replace
|
||||
? router.replace(href)
|
||||
: router.push(href)
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return {
|
||||
href: computed(() => resolvedRoute.value.href),
|
||||
route: computed(() => resolvedRoute.value.route),
|
||||
isExactActive,
|
||||
isActive,
|
||||
navigate
|
||||
}
|
||||
}
|
11
node_modules/vue-router/src/composables/utils.js
generated
vendored
Normal file
11
node_modules/vue-router/src/composables/utils.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
// dev only warn if no current instance
|
||||
|
||||
export function throwNoCurrentInstance (method) {
|
||||
if (!getCurrentInstance()) {
|
||||
throw new Error(
|
||||
`[vue-router]: Missing current instance. ${method}() must be called inside <script setup> or setup().`
|
||||
)
|
||||
}
|
||||
}
|
226
node_modules/vue-router/src/create-matcher.js
generated
vendored
Normal file
226
node_modules/vue-router/src/create-matcher.js
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
/* @flow */
|
||||
|
||||
import type VueRouter from './index'
|
||||
import { resolvePath } from './util/path'
|
||||
import { assert, warn } from './util/warn'
|
||||
import { createRoute } from './util/route'
|
||||
import { fillParams } from './util/params'
|
||||
import { createRouteMap } from './create-route-map'
|
||||
import { normalizeLocation } from './util/location'
|
||||
import { decode } from './util/query'
|
||||
|
||||
export type Matcher = {
|
||||
match: (raw: RawLocation, current?: Route, redirectedFrom?: Location) => Route;
|
||||
addRoutes: (routes: Array<RouteConfig>) => void;
|
||||
addRoute: (parentNameOrRoute: string | RouteConfig, route?: RouteConfig) => void;
|
||||
getRoutes: () => Array<RouteRecord>;
|
||||
};
|
||||
|
||||
export function createMatcher (
|
||||
routes: Array<RouteConfig>,
|
||||
router: VueRouter
|
||||
): Matcher {
|
||||
const { pathList, pathMap, nameMap } = createRouteMap(routes)
|
||||
|
||||
function addRoutes (routes) {
|
||||
createRouteMap(routes, pathList, pathMap, nameMap)
|
||||
}
|
||||
|
||||
function addRoute (parentOrRoute, route) {
|
||||
const parent = (typeof parentOrRoute !== 'object') ? nameMap[parentOrRoute] : undefined
|
||||
// $flow-disable-line
|
||||
createRouteMap([route || parentOrRoute], pathList, pathMap, nameMap, parent)
|
||||
|
||||
// add aliases of parent
|
||||
if (parent && parent.alias.length) {
|
||||
createRouteMap(
|
||||
// $flow-disable-line route is defined if parent is
|
||||
parent.alias.map(alias => ({ path: alias, children: [route] })),
|
||||
pathList,
|
||||
pathMap,
|
||||
nameMap,
|
||||
parent
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function getRoutes () {
|
||||
return pathList.map(path => pathMap[path])
|
||||
}
|
||||
|
||||
function match (
|
||||
raw: RawLocation,
|
||||
currentRoute?: Route,
|
||||
redirectedFrom?: Location
|
||||
): Route {
|
||||
const location = normalizeLocation(raw, currentRoute, false, router)
|
||||
const { name } = location
|
||||
|
||||
if (name) {
|
||||
const record = nameMap[name]
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(record, `Route with name '${name}' does not exist`)
|
||||
}
|
||||
if (!record) return _createRoute(null, location)
|
||||
const paramNames = record.regex.keys
|
||||
.filter(key => !key.optional)
|
||||
.map(key => key.name)
|
||||
|
||||
if (typeof location.params !== 'object') {
|
||||
location.params = {}
|
||||
}
|
||||
|
||||
if (currentRoute && typeof currentRoute.params === 'object') {
|
||||
for (const key in currentRoute.params) {
|
||||
if (!(key in location.params) && paramNames.indexOf(key) > -1) {
|
||||
location.params[key] = currentRoute.params[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
location.path = fillParams(record.path, location.params, `named route "${name}"`)
|
||||
return _createRoute(record, location, redirectedFrom)
|
||||
} else if (location.path) {
|
||||
location.params = {}
|
||||
for (let i = 0; i < pathList.length; i++) {
|
||||
const path = pathList[i]
|
||||
const record = pathMap[path]
|
||||
if (matchRoute(record.regex, location.path, location.params)) {
|
||||
return _createRoute(record, location, redirectedFrom)
|
||||
}
|
||||
}
|
||||
}
|
||||
// no match
|
||||
return _createRoute(null, location)
|
||||
}
|
||||
|
||||
function redirect (
|
||||
record: RouteRecord,
|
||||
location: Location
|
||||
): Route {
|
||||
const originalRedirect = record.redirect
|
||||
let redirect = typeof originalRedirect === 'function'
|
||||
? originalRedirect(createRoute(record, location, null, router))
|
||||
: originalRedirect
|
||||
|
||||
if (typeof redirect === 'string') {
|
||||
redirect = { path: redirect }
|
||||
}
|
||||
|
||||
if (!redirect || typeof redirect !== 'object') {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
false, `invalid redirect option: ${JSON.stringify(redirect)}`
|
||||
)
|
||||
}
|
||||
return _createRoute(null, location)
|
||||
}
|
||||
|
||||
const re: Object = redirect
|
||||
const { name, path } = re
|
||||
let { query, hash, params } = location
|
||||
query = re.hasOwnProperty('query') ? re.query : query
|
||||
hash = re.hasOwnProperty('hash') ? re.hash : hash
|
||||
params = re.hasOwnProperty('params') ? re.params : params
|
||||
|
||||
if (name) {
|
||||
// resolved named direct
|
||||
const targetRecord = nameMap[name]
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(targetRecord, `redirect failed: named route "${name}" not found.`)
|
||||
}
|
||||
return match({
|
||||
_normalized: true,
|
||||
name,
|
||||
query,
|
||||
hash,
|
||||
params
|
||||
}, undefined, location)
|
||||
} else if (path) {
|
||||
// 1. resolve relative redirect
|
||||
const rawPath = resolveRecordPath(path, record)
|
||||
// 2. resolve params
|
||||
const resolvedPath = fillParams(rawPath, params, `redirect route with path "${rawPath}"`)
|
||||
// 3. rematch with existing query and hash
|
||||
return match({
|
||||
_normalized: true,
|
||||
path: resolvedPath,
|
||||
query,
|
||||
hash
|
||||
}, undefined, location)
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(false, `invalid redirect option: ${JSON.stringify(redirect)}`)
|
||||
}
|
||||
return _createRoute(null, location)
|
||||
}
|
||||
}
|
||||
|
||||
function alias (
|
||||
record: RouteRecord,
|
||||
location: Location,
|
||||
matchAs: string
|
||||
): Route {
|
||||
const aliasedPath = fillParams(matchAs, location.params, `aliased route with path "${matchAs}"`)
|
||||
const aliasedMatch = match({
|
||||
_normalized: true,
|
||||
path: aliasedPath
|
||||
})
|
||||
if (aliasedMatch) {
|
||||
const matched = aliasedMatch.matched
|
||||
const aliasedRecord = matched[matched.length - 1]
|
||||
location.params = aliasedMatch.params
|
||||
return _createRoute(aliasedRecord, location)
|
||||
}
|
||||
return _createRoute(null, location)
|
||||
}
|
||||
|
||||
function _createRoute (
|
||||
record: ?RouteRecord,
|
||||
location: Location,
|
||||
redirectedFrom?: Location
|
||||
): Route {
|
||||
if (record && record.redirect) {
|
||||
return redirect(record, redirectedFrom || location)
|
||||
}
|
||||
if (record && record.matchAs) {
|
||||
return alias(record, location, record.matchAs)
|
||||
}
|
||||
return createRoute(record, location, redirectedFrom, router)
|
||||
}
|
||||
|
||||
return {
|
||||
match,
|
||||
addRoute,
|
||||
getRoutes,
|
||||
addRoutes
|
||||
}
|
||||
}
|
||||
|
||||
function matchRoute (
|
||||
regex: RouteRegExp,
|
||||
path: string,
|
||||
params: Object
|
||||
): boolean {
|
||||
const m = path.match(regex)
|
||||
|
||||
if (!m) {
|
||||
return false
|
||||
} else if (!params) {
|
||||
return true
|
||||
}
|
||||
|
||||
for (let i = 1, len = m.length; i < len; ++i) {
|
||||
const key = regex.keys[i - 1]
|
||||
if (key) {
|
||||
// Fix #1994: using * with props: true generates a param named 0
|
||||
params[key.name || 'pathMatch'] = typeof m[i] === 'string' ? decode(m[i]) : m[i]
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function resolveRecordPath (path: string, record: RouteRecord): string {
|
||||
return resolvePath(path, record.parent ? record.parent.path : '/', true)
|
||||
}
|
220
node_modules/vue-router/src/create-route-map.js
generated
vendored
Normal file
220
node_modules/vue-router/src/create-route-map.js
generated
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
/* @flow */
|
||||
|
||||
import Regexp from 'path-to-regexp'
|
||||
import { cleanPath } from './util/path'
|
||||
import { assert, warn } from './util/warn'
|
||||
|
||||
export function createRouteMap (
|
||||
routes: Array<RouteConfig>,
|
||||
oldPathList?: Array<string>,
|
||||
oldPathMap?: Dictionary<RouteRecord>,
|
||||
oldNameMap?: Dictionary<RouteRecord>,
|
||||
parentRoute?: RouteRecord
|
||||
): {
|
||||
pathList: Array<string>,
|
||||
pathMap: Dictionary<RouteRecord>,
|
||||
nameMap: Dictionary<RouteRecord>
|
||||
} {
|
||||
// the path list is used to control path matching priority
|
||||
const pathList: Array<string> = oldPathList || []
|
||||
// $flow-disable-line
|
||||
const pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null)
|
||||
// $flow-disable-line
|
||||
const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null)
|
||||
|
||||
routes.forEach(route => {
|
||||
addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)
|
||||
})
|
||||
|
||||
// ensure wildcard routes are always at the end
|
||||
for (let i = 0, l = pathList.length; i < l; i++) {
|
||||
if (pathList[i] === '*') {
|
||||
pathList.push(pathList.splice(i, 1)[0])
|
||||
l--
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// warn if routes do not include leading slashes
|
||||
const found = pathList
|
||||
// check for missing leading slash
|
||||
.filter(path => path && path.charAt(0) !== '*' && path.charAt(0) !== '/')
|
||||
|
||||
if (found.length > 0) {
|
||||
const pathNames = found.map(path => `- ${path}`).join('\n')
|
||||
warn(false, `Non-nested routes must include a leading slash character. Fix the following routes: \n${pathNames}`)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pathList,
|
||||
pathMap,
|
||||
nameMap
|
||||
}
|
||||
}
|
||||
|
||||
function addRouteRecord (
|
||||
pathList: Array<string>,
|
||||
pathMap: Dictionary<RouteRecord>,
|
||||
nameMap: Dictionary<RouteRecord>,
|
||||
route: RouteConfig,
|
||||
parent?: RouteRecord,
|
||||
matchAs?: string
|
||||
) {
|
||||
const { path, name } = route
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(path != null, `"path" is required in a route configuration.`)
|
||||
assert(
|
||||
typeof route.component !== 'string',
|
||||
`route config "component" for path: ${String(
|
||||
path || name
|
||||
)} cannot be a ` + `string id. Use an actual component instead.`
|
||||
)
|
||||
|
||||
warn(
|
||||
// eslint-disable-next-line no-control-regex
|
||||
!/[^\u0000-\u007F]+/.test(path),
|
||||
`Route with path "${path}" contains unencoded characters, make sure ` +
|
||||
`your path is correctly encoded before passing it to the router. Use ` +
|
||||
`encodeURI to encode static segments of your path.`
|
||||
)
|
||||
}
|
||||
|
||||
const pathToRegexpOptions: PathToRegexpOptions =
|
||||
route.pathToRegexpOptions || {}
|
||||
const normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict)
|
||||
|
||||
if (typeof route.caseSensitive === 'boolean') {
|
||||
pathToRegexpOptions.sensitive = route.caseSensitive
|
||||
}
|
||||
|
||||
const record: RouteRecord = {
|
||||
path: normalizedPath,
|
||||
regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),
|
||||
components: route.components || { default: route.component },
|
||||
alias: route.alias
|
||||
? typeof route.alias === 'string'
|
||||
? [route.alias]
|
||||
: route.alias
|
||||
: [],
|
||||
instances: {},
|
||||
enteredCbs: {},
|
||||
name,
|
||||
parent,
|
||||
matchAs,
|
||||
redirect: route.redirect,
|
||||
beforeEnter: route.beforeEnter,
|
||||
meta: route.meta || {},
|
||||
props:
|
||||
route.props == null
|
||||
? {}
|
||||
: route.components
|
||||
? route.props
|
||||
: { default: route.props }
|
||||
}
|
||||
|
||||
if (route.children) {
|
||||
// Warn if route is named, does not redirect and has a default child route.
|
||||
// If users navigate to this route by name, the default child will
|
||||
// not be rendered (GH Issue #629)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (
|
||||
route.name &&
|
||||
!route.redirect &&
|
||||
route.children.some(child => /^\/?$/.test(child.path))
|
||||
) {
|
||||
warn(
|
||||
false,
|
||||
`Named Route '${route.name}' has a default child route. ` +
|
||||
`When navigating to this named route (:to="{name: '${
|
||||
route.name
|
||||
}'}"), ` +
|
||||
`the default child route will not be rendered. Remove the name from ` +
|
||||
`this route and use the name of the default child route for named ` +
|
||||
`links instead.`
|
||||
)
|
||||
}
|
||||
}
|
||||
route.children.forEach(child => {
|
||||
const childMatchAs = matchAs
|
||||
? cleanPath(`${matchAs}/${child.path}`)
|
||||
: undefined
|
||||
addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs)
|
||||
})
|
||||
}
|
||||
|
||||
if (!pathMap[record.path]) {
|
||||
pathList.push(record.path)
|
||||
pathMap[record.path] = record
|
||||
}
|
||||
|
||||
if (route.alias !== undefined) {
|
||||
const aliases = Array.isArray(route.alias) ? route.alias : [route.alias]
|
||||
for (let i = 0; i < aliases.length; ++i) {
|
||||
const alias = aliases[i]
|
||||
if (process.env.NODE_ENV !== 'production' && alias === path) {
|
||||
warn(
|
||||
false,
|
||||
`Found an alias with the same value as the path: "${path}". You have to remove that alias. It will be ignored in development.`
|
||||
)
|
||||
// skip in dev to make it work
|
||||
continue
|
||||
}
|
||||
|
||||
const aliasRoute = {
|
||||
path: alias,
|
||||
children: route.children
|
||||
}
|
||||
addRouteRecord(
|
||||
pathList,
|
||||
pathMap,
|
||||
nameMap,
|
||||
aliasRoute,
|
||||
parent,
|
||||
record.path || '/' // matchAs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
if (!nameMap[name]) {
|
||||
nameMap[name] = record
|
||||
} else if (process.env.NODE_ENV !== 'production' && !matchAs) {
|
||||
warn(
|
||||
false,
|
||||
`Duplicate named routes definition: ` +
|
||||
`{ name: "${name}", path: "${record.path}" }`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compileRouteRegex (
|
||||
path: string,
|
||||
pathToRegexpOptions: PathToRegexpOptions
|
||||
): RouteRegExp {
|
||||
const regex = Regexp(path, [], pathToRegexpOptions)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const keys: any = Object.create(null)
|
||||
regex.keys.forEach(key => {
|
||||
warn(
|
||||
!keys[key.name],
|
||||
`Duplicate param keys in route with path: "${path}"`
|
||||
)
|
||||
keys[key.name] = true
|
||||
})
|
||||
}
|
||||
return regex
|
||||
}
|
||||
|
||||
function normalizePath (
|
||||
path: string,
|
||||
parent?: RouteRecord,
|
||||
strict?: boolean
|
||||
): string {
|
||||
if (!strict) path = path.replace(/\/$/, '')
|
||||
if (path[0] === '/') return path
|
||||
if (parent == null) return path
|
||||
return cleanPath(`${parent.path}/${path}`)
|
||||
}
|
3
node_modules/vue-router/src/entries/cjs.js
generated
vendored
Normal file
3
node_modules/vue-router/src/entries/cjs.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import VueRouter from '../router'
|
||||
|
||||
export default VueRouter
|
12
node_modules/vue-router/src/entries/esm.js
generated
vendored
Normal file
12
node_modules/vue-router/src/entries/esm.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import VueRouter from '../router'
|
||||
|
||||
export const version = '__VERSION__'
|
||||
export { isNavigationFailure, NavigationFailureType } from '../util/errors'
|
||||
export { START as START_LOCATION } from '../util/route'
|
||||
export { default as RouterLink } from '../components/link'
|
||||
export { default as RouterView } from '../components/view'
|
||||
|
||||
// we can't add the other composables here because people could still be using an older version of vue and that would
|
||||
// create a compilation error trying to import from vue
|
||||
|
||||
export default VueRouter
|
72
node_modules/vue-router/src/history/abstract.js
generated
vendored
Normal file
72
node_modules/vue-router/src/history/abstract.js
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/* @flow */
|
||||
|
||||
import type Router from '../index'
|
||||
import { History } from './base'
|
||||
import { NavigationFailureType, isNavigationFailure } from '../util/errors'
|
||||
|
||||
export class AbstractHistory extends History {
|
||||
index: number
|
||||
stack: Array<Route>
|
||||
|
||||
constructor (router: Router, base: ?string) {
|
||||
super(router, base)
|
||||
this.stack = []
|
||||
this.index = -1
|
||||
}
|
||||
|
||||
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
this.transitionTo(
|
||||
location,
|
||||
route => {
|
||||
this.stack = this.stack.slice(0, this.index + 1).concat(route)
|
||||
this.index++
|
||||
onComplete && onComplete(route)
|
||||
},
|
||||
onAbort
|
||||
)
|
||||
}
|
||||
|
||||
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
this.transitionTo(
|
||||
location,
|
||||
route => {
|
||||
this.stack = this.stack.slice(0, this.index).concat(route)
|
||||
onComplete && onComplete(route)
|
||||
},
|
||||
onAbort
|
||||
)
|
||||
}
|
||||
|
||||
go (n: number) {
|
||||
const targetIndex = this.index + n
|
||||
if (targetIndex < 0 || targetIndex >= this.stack.length) {
|
||||
return
|
||||
}
|
||||
const route = this.stack[targetIndex]
|
||||
this.confirmTransition(
|
||||
route,
|
||||
() => {
|
||||
const prev = this.current
|
||||
this.index = targetIndex
|
||||
this.updateRoute(route)
|
||||
this.router.afterHooks.forEach(hook => {
|
||||
hook && hook(route, prev)
|
||||
})
|
||||
},
|
||||
err => {
|
||||
if (isNavigationFailure(err, NavigationFailureType.duplicated)) {
|
||||
this.index = targetIndex
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
getCurrentLocation () {
|
||||
const current = this.stack[this.stack.length - 1]
|
||||
return current ? current.fullPath : '/'
|
||||
}
|
||||
|
||||
ensureURL () {
|
||||
// noop
|
||||
}
|
||||
}
|
384
node_modules/vue-router/src/history/base.js
generated
vendored
Normal file
384
node_modules/vue-router/src/history/base.js
generated
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
/* @flow */
|
||||
|
||||
import { _Vue } from '../install'
|
||||
import type Router from '../index'
|
||||
import { inBrowser } from '../util/dom'
|
||||
import { runQueue } from '../util/async'
|
||||
import { warn } from '../util/warn'
|
||||
import { START, isSameRoute, handleRouteEntered } from '../util/route'
|
||||
import {
|
||||
flatten,
|
||||
flatMapComponents,
|
||||
resolveAsyncComponents
|
||||
} from '../util/resolve-components'
|
||||
import {
|
||||
createNavigationDuplicatedError,
|
||||
createNavigationCancelledError,
|
||||
createNavigationRedirectedError,
|
||||
createNavigationAbortedError,
|
||||
isError,
|
||||
isNavigationFailure,
|
||||
NavigationFailureType
|
||||
} from '../util/errors'
|
||||
import { handleScroll } from '../util/scroll'
|
||||
|
||||
export class History {
|
||||
router: Router
|
||||
base: string
|
||||
current: Route
|
||||
pending: ?Route
|
||||
cb: (r: Route) => void
|
||||
ready: boolean
|
||||
readyCbs: Array<Function>
|
||||
readyErrorCbs: Array<Function>
|
||||
errorCbs: Array<Function>
|
||||
listeners: Array<Function>
|
||||
cleanupListeners: Function
|
||||
|
||||
// implemented by sub-classes
|
||||
+go: (n: number) => void
|
||||
+push: (loc: RawLocation, onComplete?: Function, onAbort?: Function) => void
|
||||
+replace: (
|
||||
loc: RawLocation,
|
||||
onComplete?: Function,
|
||||
onAbort?: Function
|
||||
) => void
|
||||
+ensureURL: (push?: boolean) => void
|
||||
+getCurrentLocation: () => string
|
||||
+setupListeners: Function
|
||||
|
||||
constructor (router: Router, base: ?string) {
|
||||
this.router = router
|
||||
this.base = normalizeBase(base)
|
||||
// start with a route object that stands for "nowhere"
|
||||
this.current = START
|
||||
this.pending = null
|
||||
this.ready = false
|
||||
this.readyCbs = []
|
||||
this.readyErrorCbs = []
|
||||
this.errorCbs = []
|
||||
this.listeners = []
|
||||
}
|
||||
|
||||
listen (cb: Function) {
|
||||
this.cb = cb
|
||||
}
|
||||
|
||||
onReady (cb: Function, errorCb: ?Function) {
|
||||
if (this.ready) {
|
||||
cb()
|
||||
} else {
|
||||
this.readyCbs.push(cb)
|
||||
if (errorCb) {
|
||||
this.readyErrorCbs.push(errorCb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onError (errorCb: Function) {
|
||||
this.errorCbs.push(errorCb)
|
||||
}
|
||||
|
||||
transitionTo (
|
||||
location: RawLocation,
|
||||
onComplete?: Function,
|
||||
onAbort?: Function
|
||||
) {
|
||||
let route
|
||||
// catch redirect option https://github.com/vuejs/vue-router/issues/3201
|
||||
try {
|
||||
route = this.router.match(location, this.current)
|
||||
} catch (e) {
|
||||
this.errorCbs.forEach(cb => {
|
||||
cb(e)
|
||||
})
|
||||
// Exception should still be thrown
|
||||
throw e
|
||||
}
|
||||
const prev = this.current
|
||||
this.confirmTransition(
|
||||
route,
|
||||
() => {
|
||||
this.updateRoute(route)
|
||||
onComplete && onComplete(route)
|
||||
this.ensureURL()
|
||||
this.router.afterHooks.forEach(hook => {
|
||||
hook && hook(route, prev)
|
||||
})
|
||||
|
||||
// fire ready cbs once
|
||||
if (!this.ready) {
|
||||
this.ready = true
|
||||
this.readyCbs.forEach(cb => {
|
||||
cb(route)
|
||||
})
|
||||
}
|
||||
},
|
||||
err => {
|
||||
if (onAbort) {
|
||||
onAbort(err)
|
||||
}
|
||||
if (err && !this.ready) {
|
||||
// Initial redirection should not mark the history as ready yet
|
||||
// because it's triggered by the redirection instead
|
||||
// https://github.com/vuejs/vue-router/issues/3225
|
||||
// https://github.com/vuejs/vue-router/issues/3331
|
||||
if (!isNavigationFailure(err, NavigationFailureType.redirected) || prev !== START) {
|
||||
this.ready = true
|
||||
this.readyErrorCbs.forEach(cb => {
|
||||
cb(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
confirmTransition (route: Route, onComplete: Function, onAbort?: Function) {
|
||||
const current = this.current
|
||||
this.pending = route
|
||||
const abort = err => {
|
||||
// changed after adding errors with
|
||||
// https://github.com/vuejs/vue-router/pull/3047 before that change,
|
||||
// redirect and aborted navigation would produce an err == null
|
||||
if (!isNavigationFailure(err) && isError(err)) {
|
||||
if (this.errorCbs.length) {
|
||||
this.errorCbs.forEach(cb => {
|
||||
cb(err)
|
||||
})
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(false, 'uncaught error during route navigation:')
|
||||
}
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
onAbort && onAbort(err)
|
||||
}
|
||||
const lastRouteIndex = route.matched.length - 1
|
||||
const lastCurrentIndex = current.matched.length - 1
|
||||
if (
|
||||
isSameRoute(route, current) &&
|
||||
// in the case the route map has been dynamically appended to
|
||||
lastRouteIndex === lastCurrentIndex &&
|
||||
route.matched[lastRouteIndex] === current.matched[lastCurrentIndex]
|
||||
) {
|
||||
this.ensureURL()
|
||||
if (route.hash) {
|
||||
handleScroll(this.router, current, route, false)
|
||||
}
|
||||
return abort(createNavigationDuplicatedError(current, route))
|
||||
}
|
||||
|
||||
const { updated, deactivated, activated } = resolveQueue(
|
||||
this.current.matched,
|
||||
route.matched
|
||||
)
|
||||
|
||||
const queue: Array<?NavigationGuard> = [].concat(
|
||||
// in-component leave guards
|
||||
extractLeaveGuards(deactivated),
|
||||
// global before hooks
|
||||
this.router.beforeHooks,
|
||||
// in-component update hooks
|
||||
extractUpdateHooks(updated),
|
||||
// in-config enter guards
|
||||
activated.map(m => m.beforeEnter),
|
||||
// async components
|
||||
resolveAsyncComponents(activated)
|
||||
)
|
||||
|
||||
const iterator = (hook: NavigationGuard, next) => {
|
||||
if (this.pending !== route) {
|
||||
return abort(createNavigationCancelledError(current, route))
|
||||
}
|
||||
try {
|
||||
hook(route, current, (to: any) => {
|
||||
if (to === false) {
|
||||
// next(false) -> abort navigation, ensure current URL
|
||||
this.ensureURL(true)
|
||||
abort(createNavigationAbortedError(current, route))
|
||||
} else if (isError(to)) {
|
||||
this.ensureURL(true)
|
||||
abort(to)
|
||||
} else if (
|
||||
typeof to === 'string' ||
|
||||
(typeof to === 'object' &&
|
||||
(typeof to.path === 'string' || typeof to.name === 'string'))
|
||||
) {
|
||||
// next('/') or next({ path: '/' }) -> redirect
|
||||
abort(createNavigationRedirectedError(current, route))
|
||||
if (typeof to === 'object' && to.replace) {
|
||||
this.replace(to)
|
||||
} else {
|
||||
this.push(to)
|
||||
}
|
||||
} else {
|
||||
// confirm transition and pass on the value
|
||||
next(to)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
abort(e)
|
||||
}
|
||||
}
|
||||
|
||||
runQueue(queue, iterator, () => {
|
||||
// wait until async components are resolved before
|
||||
// extracting in-component enter guards
|
||||
const enterGuards = extractEnterGuards(activated)
|
||||
const queue = enterGuards.concat(this.router.resolveHooks)
|
||||
runQueue(queue, iterator, () => {
|
||||
if (this.pending !== route) {
|
||||
return abort(createNavigationCancelledError(current, route))
|
||||
}
|
||||
this.pending = null
|
||||
onComplete(route)
|
||||
if (this.router.app) {
|
||||
this.router.app.$nextTick(() => {
|
||||
handleRouteEntered(route)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
updateRoute (route: Route) {
|
||||
this.current = route
|
||||
this.cb && this.cb(route)
|
||||
}
|
||||
|
||||
setupListeners () {
|
||||
// Default implementation is empty
|
||||
}
|
||||
|
||||
teardown () {
|
||||
// clean up event listeners
|
||||
// https://github.com/vuejs/vue-router/issues/2341
|
||||
this.listeners.forEach(cleanupListener => {
|
||||
cleanupListener()
|
||||
})
|
||||
this.listeners = []
|
||||
|
||||
// reset current history route
|
||||
// https://github.com/vuejs/vue-router/issues/3294
|
||||
this.current = START
|
||||
this.pending = null
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeBase (base: ?string): string {
|
||||
if (!base) {
|
||||
if (inBrowser) {
|
||||
// respect <base> tag
|
||||
const baseEl = document.querySelector('base')
|
||||
base = (baseEl && baseEl.getAttribute('href')) || '/'
|
||||
// strip full URL origin
|
||||
base = base.replace(/^https?:\/\/[^\/]+/, '')
|
||||
} else {
|
||||
base = '/'
|
||||
}
|
||||
}
|
||||
// make sure there's the starting slash
|
||||
if (base.charAt(0) !== '/') {
|
||||
base = '/' + base
|
||||
}
|
||||
// remove trailing slash
|
||||
return base.replace(/\/$/, '')
|
||||
}
|
||||
|
||||
function resolveQueue (
|
||||
current: Array<RouteRecord>,
|
||||
next: Array<RouteRecord>
|
||||
): {
|
||||
updated: Array<RouteRecord>,
|
||||
activated: Array<RouteRecord>,
|
||||
deactivated: Array<RouteRecord>
|
||||
} {
|
||||
let i
|
||||
const max = Math.max(current.length, next.length)
|
||||
for (i = 0; i < max; i++) {
|
||||
if (current[i] !== next[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return {
|
||||
updated: next.slice(0, i),
|
||||
activated: next.slice(i),
|
||||
deactivated: current.slice(i)
|
||||
}
|
||||
}
|
||||
|
||||
function extractGuards (
|
||||
records: Array<RouteRecord>,
|
||||
name: string,
|
||||
bind: Function,
|
||||
reverse?: boolean
|
||||
): Array<?Function> {
|
||||
const guards = flatMapComponents(records, (def, instance, match, key) => {
|
||||
const guard = extractGuard(def, name)
|
||||
if (guard) {
|
||||
return Array.isArray(guard)
|
||||
? guard.map(guard => bind(guard, instance, match, key))
|
||||
: bind(guard, instance, match, key)
|
||||
}
|
||||
})
|
||||
return flatten(reverse ? guards.reverse() : guards)
|
||||
}
|
||||
|
||||
function extractGuard (
|
||||
def: Object | Function,
|
||||
key: string
|
||||
): NavigationGuard | Array<NavigationGuard> {
|
||||
if (typeof def !== 'function') {
|
||||
// extend now so that global mixins are applied.
|
||||
def = _Vue.extend(def)
|
||||
}
|
||||
return def.options[key]
|
||||
}
|
||||
|
||||
function extractLeaveGuards (deactivated: Array<RouteRecord>): Array<?Function> {
|
||||
return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
|
||||
}
|
||||
|
||||
function extractUpdateHooks (updated: Array<RouteRecord>): Array<?Function> {
|
||||
return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
|
||||
}
|
||||
|
||||
function bindGuard (guard: NavigationGuard, instance: ?_Vue): ?NavigationGuard {
|
||||
if (instance) {
|
||||
return function boundRouteGuard () {
|
||||
return guard.apply(instance, arguments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extractEnterGuards (
|
||||
activated: Array<RouteRecord>
|
||||
): Array<?Function> {
|
||||
return extractGuards(
|
||||
activated,
|
||||
'beforeRouteEnter',
|
||||
(guard, _, match, key) => {
|
||||
return bindEnterGuard(guard, match, key)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function bindEnterGuard (
|
||||
guard: NavigationGuard,
|
||||
match: RouteRecord,
|
||||
key: string
|
||||
): NavigationGuard {
|
||||
return function routeEnterGuard (to, from, next) {
|
||||
return guard(to, from, cb => {
|
||||
if (typeof cb === 'function') {
|
||||
if (!match.enteredCbs[key]) {
|
||||
match.enteredCbs[key] = []
|
||||
}
|
||||
match.enteredCbs[key].push(cb)
|
||||
}
|
||||
next(cb)
|
||||
})
|
||||
}
|
||||
}
|
152
node_modules/vue-router/src/history/hash.js
generated
vendored
Normal file
152
node_modules/vue-router/src/history/hash.js
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/* @flow */
|
||||
|
||||
import type Router from '../index'
|
||||
import { History } from './base'
|
||||
import { cleanPath } from '../util/path'
|
||||
import { getLocation } from './html5'
|
||||
import { setupScroll, handleScroll } from '../util/scroll'
|
||||
import { pushState, replaceState, supportsPushState } from '../util/push-state'
|
||||
|
||||
export class HashHistory extends History {
|
||||
constructor (router: Router, base: ?string, fallback: boolean) {
|
||||
super(router, base)
|
||||
// check history fallback deeplinking
|
||||
if (fallback && checkFallback(this.base)) {
|
||||
return
|
||||
}
|
||||
ensureSlash()
|
||||
}
|
||||
|
||||
// this is delayed until the app mounts
|
||||
// to avoid the hashchange listener being fired too early
|
||||
setupListeners () {
|
||||
if (this.listeners.length > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const router = this.router
|
||||
const expectScroll = router.options.scrollBehavior
|
||||
const supportsScroll = supportsPushState && expectScroll
|
||||
|
||||
if (supportsScroll) {
|
||||
this.listeners.push(setupScroll())
|
||||
}
|
||||
|
||||
const handleRoutingEvent = () => {
|
||||
const current = this.current
|
||||
if (!ensureSlash()) {
|
||||
return
|
||||
}
|
||||
this.transitionTo(getHash(), route => {
|
||||
if (supportsScroll) {
|
||||
handleScroll(this.router, route, current, true)
|
||||
}
|
||||
if (!supportsPushState) {
|
||||
replaceHash(route.fullPath)
|
||||
}
|
||||
})
|
||||
}
|
||||
const eventType = supportsPushState ? 'popstate' : 'hashchange'
|
||||
window.addEventListener(
|
||||
eventType,
|
||||
handleRoutingEvent
|
||||
)
|
||||
this.listeners.push(() => {
|
||||
window.removeEventListener(eventType, handleRoutingEvent)
|
||||
})
|
||||
}
|
||||
|
||||
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
const { current: fromRoute } = this
|
||||
this.transitionTo(
|
||||
location,
|
||||
route => {
|
||||
pushHash(route.fullPath)
|
||||
handleScroll(this.router, route, fromRoute, false)
|
||||
onComplete && onComplete(route)
|
||||
},
|
||||
onAbort
|
||||
)
|
||||
}
|
||||
|
||||
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
const { current: fromRoute } = this
|
||||
this.transitionTo(
|
||||
location,
|
||||
route => {
|
||||
replaceHash(route.fullPath)
|
||||
handleScroll(this.router, route, fromRoute, false)
|
||||
onComplete && onComplete(route)
|
||||
},
|
||||
onAbort
|
||||
)
|
||||
}
|
||||
|
||||
go (n: number) {
|
||||
window.history.go(n)
|
||||
}
|
||||
|
||||
ensureURL (push?: boolean) {
|
||||
const current = this.current.fullPath
|
||||
if (getHash() !== current) {
|
||||
push ? pushHash(current) : replaceHash(current)
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentLocation () {
|
||||
return getHash()
|
||||
}
|
||||
}
|
||||
|
||||
function checkFallback (base) {
|
||||
const location = getLocation(base)
|
||||
if (!/^\/#/.test(location)) {
|
||||
window.location.replace(cleanPath(base + '/#' + location))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function ensureSlash (): boolean {
|
||||
const path = getHash()
|
||||
if (path.charAt(0) === '/') {
|
||||
return true
|
||||
}
|
||||
replaceHash('/' + path)
|
||||
return false
|
||||
}
|
||||
|
||||
export function getHash (): string {
|
||||
// We can't use window.location.hash here because it's not
|
||||
// consistent across browsers - Firefox will pre-decode it!
|
||||
let href = window.location.href
|
||||
const index = href.indexOf('#')
|
||||
// empty path
|
||||
if (index < 0) return ''
|
||||
|
||||
href = href.slice(index + 1)
|
||||
|
||||
return href
|
||||
}
|
||||
|
||||
function getUrl (path) {
|
||||
const href = window.location.href
|
||||
const i = href.indexOf('#')
|
||||
const base = i >= 0 ? href.slice(0, i) : href
|
||||
return `${base}#${path}`
|
||||
}
|
||||
|
||||
function pushHash (path) {
|
||||
if (supportsPushState) {
|
||||
pushState(getUrl(path))
|
||||
} else {
|
||||
window.location.hash = path
|
||||
}
|
||||
}
|
||||
|
||||
function replaceHash (path) {
|
||||
if (supportsPushState) {
|
||||
replaceState(getUrl(path))
|
||||
} else {
|
||||
window.location.replace(getUrl(path))
|
||||
}
|
||||
}
|
100
node_modules/vue-router/src/history/html5.js
generated
vendored
Normal file
100
node_modules/vue-router/src/history/html5.js
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/* @flow */
|
||||
|
||||
import type Router from '../index'
|
||||
import { History } from './base'
|
||||
import { cleanPath } from '../util/path'
|
||||
import { START } from '../util/route'
|
||||
import { setupScroll, handleScroll } from '../util/scroll'
|
||||
import { pushState, replaceState, supportsPushState } from '../util/push-state'
|
||||
|
||||
export class HTML5History extends History {
|
||||
_startLocation: string
|
||||
|
||||
constructor (router: Router, base: ?string) {
|
||||
super(router, base)
|
||||
|
||||
this._startLocation = getLocation(this.base)
|
||||
}
|
||||
|
||||
setupListeners () {
|
||||
if (this.listeners.length > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const router = this.router
|
||||
const expectScroll = router.options.scrollBehavior
|
||||
const supportsScroll = supportsPushState && expectScroll
|
||||
|
||||
if (supportsScroll) {
|
||||
this.listeners.push(setupScroll())
|
||||
}
|
||||
|
||||
const handleRoutingEvent = () => {
|
||||
const current = this.current
|
||||
|
||||
// Avoiding first `popstate` event dispatched in some browsers but first
|
||||
// history route not updated since async guard at the same time.
|
||||
const location = getLocation(this.base)
|
||||
if (this.current === START && location === this._startLocation) {
|
||||
return
|
||||
}
|
||||
|
||||
this.transitionTo(location, route => {
|
||||
if (supportsScroll) {
|
||||
handleScroll(router, route, current, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
window.addEventListener('popstate', handleRoutingEvent)
|
||||
this.listeners.push(() => {
|
||||
window.removeEventListener('popstate', handleRoutingEvent)
|
||||
})
|
||||
}
|
||||
|
||||
go (n: number) {
|
||||
window.history.go(n)
|
||||
}
|
||||
|
||||
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
const { current: fromRoute } = this
|
||||
this.transitionTo(location, route => {
|
||||
pushState(cleanPath(this.base + route.fullPath))
|
||||
handleScroll(this.router, route, fromRoute, false)
|
||||
onComplete && onComplete(route)
|
||||
}, onAbort)
|
||||
}
|
||||
|
||||
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
const { current: fromRoute } = this
|
||||
this.transitionTo(location, route => {
|
||||
replaceState(cleanPath(this.base + route.fullPath))
|
||||
handleScroll(this.router, route, fromRoute, false)
|
||||
onComplete && onComplete(route)
|
||||
}, onAbort)
|
||||
}
|
||||
|
||||
ensureURL (push?: boolean) {
|
||||
if (getLocation(this.base) !== this.current.fullPath) {
|
||||
const current = cleanPath(this.base + this.current.fullPath)
|
||||
push ? pushState(current) : replaceState(current)
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentLocation (): string {
|
||||
return getLocation(this.base)
|
||||
}
|
||||
}
|
||||
|
||||
export function getLocation (base: string): string {
|
||||
let path = window.location.pathname
|
||||
const pathLowerCase = path.toLowerCase()
|
||||
const baseLowerCase = base.toLowerCase()
|
||||
// base="/a" shouldn't turn path="/app" into "/a/pp"
|
||||
// https://github.com/vuejs/vue-router/issues/3555
|
||||
// so we ensure the trailing slash in the base
|
||||
if (base && ((pathLowerCase === baseLowerCase) ||
|
||||
(pathLowerCase.indexOf(cleanPath(baseLowerCase + '/')) === 0))) {
|
||||
path = path.slice(base.length)
|
||||
}
|
||||
return (path || '/') + window.location.search + window.location.hash
|
||||
}
|
3
node_modules/vue-router/src/index.js
generated
vendored
Normal file
3
node_modules/vue-router/src/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import VueRouter from './entries/cjs'
|
||||
|
||||
export default VueRouter
|
52
node_modules/vue-router/src/install.js
generated
vendored
Normal file
52
node_modules/vue-router/src/install.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
import View from './components/view'
|
||||
import Link from './components/link'
|
||||
|
||||
export let _Vue
|
||||
|
||||
export function install (Vue) {
|
||||
if (install.installed && _Vue === Vue) return
|
||||
install.installed = true
|
||||
|
||||
_Vue = Vue
|
||||
|
||||
const isDef = v => v !== undefined
|
||||
|
||||
const registerInstance = (vm, callVal) => {
|
||||
let i = vm.$options._parentVnode
|
||||
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
|
||||
i(vm, callVal)
|
||||
}
|
||||
}
|
||||
|
||||
Vue.mixin({
|
||||
beforeCreate () {
|
||||
if (isDef(this.$options.router)) {
|
||||
this._routerRoot = this
|
||||
this._router = this.$options.router
|
||||
this._router.init(this)
|
||||
Vue.util.defineReactive(this, '_route', this._router.history.current)
|
||||
} else {
|
||||
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
|
||||
}
|
||||
registerInstance(this, this)
|
||||
},
|
||||
destroyed () {
|
||||
registerInstance(this)
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(Vue.prototype, '$router', {
|
||||
get () { return this._routerRoot._router }
|
||||
})
|
||||
|
||||
Object.defineProperty(Vue.prototype, '$route', {
|
||||
get () { return this._routerRoot._route }
|
||||
})
|
||||
|
||||
Vue.component('RouterView', View)
|
||||
Vue.component('RouterLink', Link)
|
||||
|
||||
const strats = Vue.config.optionMergeStrategies
|
||||
// use the same hook merging strategy for route hooks
|
||||
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
|
||||
}
|
294
node_modules/vue-router/src/router.js
generated
vendored
Normal file
294
node_modules/vue-router/src/router.js
generated
vendored
Normal file
@ -0,0 +1,294 @@
|
||||
/* @flow */
|
||||
|
||||
import { install } from './install'
|
||||
import { START } from './util/route'
|
||||
import { assert, warn } from './util/warn'
|
||||
import { inBrowser } from './util/dom'
|
||||
import { cleanPath } from './util/path'
|
||||
import { createMatcher } from './create-matcher'
|
||||
import { normalizeLocation } from './util/location'
|
||||
import { supportsPushState } from './util/push-state'
|
||||
import { handleScroll } from './util/scroll'
|
||||
import { isNavigationFailure, NavigationFailureType } from './util/errors'
|
||||
|
||||
import { HashHistory } from './history/hash'
|
||||
import { HTML5History } from './history/html5'
|
||||
import { AbstractHistory } from './history/abstract'
|
||||
|
||||
import type { Matcher } from './create-matcher'
|
||||
|
||||
export default class VueRouter {
|
||||
static install: () => void
|
||||
static version: string
|
||||
static isNavigationFailure: Function
|
||||
static NavigationFailureType: any
|
||||
static START_LOCATION: Route
|
||||
|
||||
app: any
|
||||
apps: Array<any>
|
||||
ready: boolean
|
||||
readyCbs: Array<Function>
|
||||
options: RouterOptions
|
||||
mode: string
|
||||
history: HashHistory | HTML5History | AbstractHistory
|
||||
matcher: Matcher
|
||||
fallback: boolean
|
||||
beforeHooks: Array<?NavigationGuard>
|
||||
resolveHooks: Array<?NavigationGuard>
|
||||
afterHooks: Array<?AfterNavigationHook>
|
||||
|
||||
constructor (options: RouterOptions = {}) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(this instanceof VueRouter, `Router must be called with the new operator.`)
|
||||
}
|
||||
this.app = null
|
||||
this.apps = []
|
||||
this.options = options
|
||||
this.beforeHooks = []
|
||||
this.resolveHooks = []
|
||||
this.afterHooks = []
|
||||
this.matcher = createMatcher(options.routes || [], this)
|
||||
|
||||
let mode = options.mode || 'hash'
|
||||
this.fallback =
|
||||
mode === 'history' && !supportsPushState && options.fallback !== false
|
||||
if (this.fallback) {
|
||||
mode = 'hash'
|
||||
}
|
||||
if (!inBrowser) {
|
||||
mode = 'abstract'
|
||||
}
|
||||
this.mode = mode
|
||||
|
||||
switch (mode) {
|
||||
case 'history':
|
||||
this.history = new HTML5History(this, options.base)
|
||||
break
|
||||
case 'hash':
|
||||
this.history = new HashHistory(this, options.base, this.fallback)
|
||||
break
|
||||
case 'abstract':
|
||||
this.history = new AbstractHistory(this, options.base)
|
||||
break
|
||||
default:
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(false, `invalid mode: ${mode}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match (raw: RawLocation, current?: Route, redirectedFrom?: Location): Route {
|
||||
return this.matcher.match(raw, current, redirectedFrom)
|
||||
}
|
||||
|
||||
get currentRoute (): ?Route {
|
||||
return this.history && this.history.current
|
||||
}
|
||||
|
||||
init (app: any /* Vue component instance */) {
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
assert(
|
||||
install.installed,
|
||||
`not installed. Make sure to call \`Vue.use(VueRouter)\` ` +
|
||||
`before creating root instance.`
|
||||
)
|
||||
|
||||
this.apps.push(app)
|
||||
|
||||
// set up app destroyed handler
|
||||
// https://github.com/vuejs/vue-router/issues/2639
|
||||
app.$once('hook:destroyed', () => {
|
||||
// clean out app from this.apps array once destroyed
|
||||
const index = this.apps.indexOf(app)
|
||||
if (index > -1) this.apps.splice(index, 1)
|
||||
// ensure we still have a main app or null if no apps
|
||||
// we do not release the router so it can be reused
|
||||
if (this.app === app) this.app = this.apps[0] || null
|
||||
|
||||
if (!this.app) this.history.teardown()
|
||||
})
|
||||
|
||||
// main app previously initialized
|
||||
// return as we don't need to set up new history listener
|
||||
if (this.app) {
|
||||
return
|
||||
}
|
||||
|
||||
this.app = app
|
||||
|
||||
const history = this.history
|
||||
|
||||
if (history instanceof HTML5History || history instanceof HashHistory) {
|
||||
const handleInitialScroll = routeOrError => {
|
||||
const from = history.current
|
||||
const expectScroll = this.options.scrollBehavior
|
||||
const supportsScroll = supportsPushState && expectScroll
|
||||
|
||||
if (supportsScroll && 'fullPath' in routeOrError) {
|
||||
handleScroll(this, routeOrError, from, false)
|
||||
}
|
||||
}
|
||||
const setupListeners = routeOrError => {
|
||||
history.setupListeners()
|
||||
handleInitialScroll(routeOrError)
|
||||
}
|
||||
history.transitionTo(
|
||||
history.getCurrentLocation(),
|
||||
setupListeners,
|
||||
setupListeners
|
||||
)
|
||||
}
|
||||
|
||||
history.listen(route => {
|
||||
this.apps.forEach(app => {
|
||||
app._route = route
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach (fn: Function): Function {
|
||||
return registerHook(this.beforeHooks, fn)
|
||||
}
|
||||
|
||||
beforeResolve (fn: Function): Function {
|
||||
return registerHook(this.resolveHooks, fn)
|
||||
}
|
||||
|
||||
afterEach (fn: Function): Function {
|
||||
return registerHook(this.afterHooks, fn)
|
||||
}
|
||||
|
||||
onReady (cb: Function, errorCb?: Function) {
|
||||
this.history.onReady(cb, errorCb)
|
||||
}
|
||||
|
||||
onError (errorCb: Function) {
|
||||
this.history.onError(errorCb)
|
||||
}
|
||||
|
||||
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
// $flow-disable-line
|
||||
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.history.push(location, resolve, reject)
|
||||
})
|
||||
} else {
|
||||
this.history.push(location, onComplete, onAbort)
|
||||
}
|
||||
}
|
||||
|
||||
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
||||
// $flow-disable-line
|
||||
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.history.replace(location, resolve, reject)
|
||||
})
|
||||
} else {
|
||||
this.history.replace(location, onComplete, onAbort)
|
||||
}
|
||||
}
|
||||
|
||||
go (n: number) {
|
||||
this.history.go(n)
|
||||
}
|
||||
|
||||
back () {
|
||||
this.go(-1)
|
||||
}
|
||||
|
||||
forward () {
|
||||
this.go(1)
|
||||
}
|
||||
|
||||
getMatchedComponents (to?: RawLocation | Route): Array<any> {
|
||||
const route: any = to
|
||||
? to.matched
|
||||
? to
|
||||
: this.resolve(to).route
|
||||
: this.currentRoute
|
||||
if (!route) {
|
||||
return []
|
||||
}
|
||||
return [].concat.apply(
|
||||
[],
|
||||
route.matched.map(m => {
|
||||
return Object.keys(m.components).map(key => {
|
||||
return m.components[key]
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
resolve (
|
||||
to: RawLocation,
|
||||
current?: Route,
|
||||
append?: boolean
|
||||
): {
|
||||
location: Location,
|
||||
route: Route,
|
||||
href: string,
|
||||
// for backwards compat
|
||||
normalizedTo: Location,
|
||||
resolved: Route
|
||||
} {
|
||||
current = current || this.history.current
|
||||
const location = normalizeLocation(to, current, append, this)
|
||||
const route = this.match(location, current)
|
||||
const fullPath = route.redirectedFrom || route.fullPath
|
||||
const base = this.history.base
|
||||
const href = createHref(base, fullPath, this.mode)
|
||||
return {
|
||||
location,
|
||||
route,
|
||||
href,
|
||||
// for backwards compat
|
||||
normalizedTo: location,
|
||||
resolved: route
|
||||
}
|
||||
}
|
||||
|
||||
getRoutes () {
|
||||
return this.matcher.getRoutes()
|
||||
}
|
||||
|
||||
addRoute (parentOrRoute: string | RouteConfig, route?: RouteConfig) {
|
||||
this.matcher.addRoute(parentOrRoute, route)
|
||||
if (this.history.current !== START) {
|
||||
this.history.transitionTo(this.history.getCurrentLocation())
|
||||
}
|
||||
}
|
||||
|
||||
addRoutes (routes: Array<RouteConfig>) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(false, 'router.addRoutes() is deprecated and has been removed in Vue Router 4. Use router.addRoute() instead.')
|
||||
}
|
||||
this.matcher.addRoutes(routes)
|
||||
if (this.history.current !== START) {
|
||||
this.history.transitionTo(this.history.getCurrentLocation())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerHook (list: Array<any>, fn: Function): Function {
|
||||
list.push(fn)
|
||||
return () => {
|
||||
const i = list.indexOf(fn)
|
||||
if (i > -1) list.splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function createHref (base: string, fullPath: string, mode) {
|
||||
var path = mode === 'hash' ? '#' + fullPath : fullPath
|
||||
return base ? cleanPath(base + '/' + path) : path
|
||||
}
|
||||
|
||||
// We cannot remove this as it would be a breaking change
|
||||
VueRouter.install = install
|
||||
VueRouter.version = '__VERSION__'
|
||||
VueRouter.isNavigationFailure = isNavigationFailure
|
||||
VueRouter.NavigationFailureType = NavigationFailureType
|
||||
VueRouter.START_LOCATION = START
|
||||
|
||||
if (inBrowser && window.Vue) {
|
||||
window.Vue.use(VueRouter)
|
||||
}
|
18
node_modules/vue-router/src/util/async.js
generated
vendored
Normal file
18
node_modules/vue-router/src/util/async.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/* @flow */
|
||||
|
||||
export function runQueue (queue: Array<?NavigationGuard>, fn: Function, cb: Function) {
|
||||
const step = index => {
|
||||
if (index >= queue.length) {
|
||||
cb()
|
||||
} else {
|
||||
if (queue[index]) {
|
||||
fn(queue[index], () => {
|
||||
step(index + 1)
|
||||
})
|
||||
} else {
|
||||
step(index + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
step(0)
|
||||
}
|
3
node_modules/vue-router/src/util/dom.js
generated
vendored
Normal file
3
node_modules/vue-router/src/util/dom.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
export const inBrowser = typeof window !== 'undefined'
|
86
node_modules/vue-router/src/util/errors.js
generated
vendored
Normal file
86
node_modules/vue-router/src/util/errors.js
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
// When changing thing, also edit router.d.ts
|
||||
export const NavigationFailureType = {
|
||||
redirected: 2,
|
||||
aborted: 4,
|
||||
cancelled: 8,
|
||||
duplicated: 16
|
||||
}
|
||||
|
||||
export function createNavigationRedirectedError (from, to) {
|
||||
return createRouterError(
|
||||
from,
|
||||
to,
|
||||
NavigationFailureType.redirected,
|
||||
`Redirected when going from "${from.fullPath}" to "${stringifyRoute(
|
||||
to
|
||||
)}" via a navigation guard.`
|
||||
)
|
||||
}
|
||||
|
||||
export function createNavigationDuplicatedError (from, to) {
|
||||
const error = createRouterError(
|
||||
from,
|
||||
to,
|
||||
NavigationFailureType.duplicated,
|
||||
`Avoided redundant navigation to current location: "${from.fullPath}".`
|
||||
)
|
||||
// backwards compatible with the first introduction of Errors
|
||||
error.name = 'NavigationDuplicated'
|
||||
return error
|
||||
}
|
||||
|
||||
export function createNavigationCancelledError (from, to) {
|
||||
return createRouterError(
|
||||
from,
|
||||
to,
|
||||
NavigationFailureType.cancelled,
|
||||
`Navigation cancelled from "${from.fullPath}" to "${
|
||||
to.fullPath
|
||||
}" with a new navigation.`
|
||||
)
|
||||
}
|
||||
|
||||
export function createNavigationAbortedError (from, to) {
|
||||
return createRouterError(
|
||||
from,
|
||||
to,
|
||||
NavigationFailureType.aborted,
|
||||
`Navigation aborted from "${from.fullPath}" to "${
|
||||
to.fullPath
|
||||
}" via a navigation guard.`
|
||||
)
|
||||
}
|
||||
|
||||
function createRouterError (from, to, type, message) {
|
||||
const error = new Error(message)
|
||||
error._isRouter = true
|
||||
error.from = from
|
||||
error.to = to
|
||||
error.type = type
|
||||
|
||||
return error
|
||||
}
|
||||
|
||||
const propertiesToLog = ['params', 'query', 'hash']
|
||||
|
||||
function stringifyRoute (to) {
|
||||
if (typeof to === 'string') return to
|
||||
if ('path' in to) return to.path
|
||||
const location = {}
|
||||
propertiesToLog.forEach(key => {
|
||||
if (key in to) location[key] = to[key]
|
||||
})
|
||||
return JSON.stringify(location, null, 2)
|
||||
}
|
||||
|
||||
export function isError (err) {
|
||||
return Object.prototype.toString.call(err).indexOf('Error') > -1
|
||||
}
|
||||
|
||||
export function isNavigationFailure (err, errorType) {
|
||||
return (
|
||||
isError(err) &&
|
||||
err._isRouter &&
|
||||
(errorType == null || err.type === errorType)
|
||||
)
|
||||
}
|
69
node_modules/vue-router/src/util/location.js
generated
vendored
Normal file
69
node_modules/vue-router/src/util/location.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/* @flow */
|
||||
|
||||
import type VueRouter from '../index'
|
||||
import { parsePath, resolvePath } from './path'
|
||||
import { resolveQuery } from './query'
|
||||
import { fillParams } from './params'
|
||||
import { warn } from './warn'
|
||||
import { extend } from './misc'
|
||||
|
||||
export function normalizeLocation (
|
||||
raw: RawLocation,
|
||||
current: ?Route,
|
||||
append: ?boolean,
|
||||
router: ?VueRouter
|
||||
): Location {
|
||||
let next: Location = typeof raw === 'string' ? { path: raw } : raw
|
||||
// named target
|
||||
if (next._normalized) {
|
||||
return next
|
||||
} else if (next.name) {
|
||||
next = extend({}, raw)
|
||||
const params = next.params
|
||||
if (params && typeof params === 'object') {
|
||||
next.params = extend({}, params)
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
// relative params
|
||||
if (!next.path && next.params && current) {
|
||||
next = extend({}, next)
|
||||
next._normalized = true
|
||||
const params: any = extend(extend({}, current.params), next.params)
|
||||
if (current.name) {
|
||||
next.name = current.name
|
||||
next.params = params
|
||||
} else if (current.matched.length) {
|
||||
const rawPath = current.matched[current.matched.length - 1].path
|
||||
next.path = fillParams(rawPath, params, `path ${current.path}`)
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(false, `relative params navigation requires a current route.`)
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
const parsedPath = parsePath(next.path || '')
|
||||
const basePath = (current && current.path) || '/'
|
||||
const path = parsedPath.path
|
||||
? resolvePath(parsedPath.path, basePath, append || next.append)
|
||||
: basePath
|
||||
|
||||
const query = resolveQuery(
|
||||
parsedPath.query,
|
||||
next.query,
|
||||
router && router.options.parseQuery
|
||||
)
|
||||
|
||||
let hash = next.hash || parsedPath.hash
|
||||
if (hash && hash.charAt(0) !== '#') {
|
||||
hash = `#${hash}`
|
||||
}
|
||||
|
||||
return {
|
||||
_normalized: true,
|
||||
path,
|
||||
query,
|
||||
hash
|
||||
}
|
||||
}
|
6
node_modules/vue-router/src/util/misc.js
generated
vendored
Normal file
6
node_modules/vue-router/src/util/misc.js
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export function extend (a, b) {
|
||||
for (const key in b) {
|
||||
a[key] = b[key]
|
||||
}
|
||||
return a
|
||||
}
|
37
node_modules/vue-router/src/util/params.js
generated
vendored
Normal file
37
node_modules/vue-router/src/util/params.js
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/* @flow */
|
||||
|
||||
import { warn } from './warn'
|
||||
import Regexp from 'path-to-regexp'
|
||||
|
||||
// $flow-disable-line
|
||||
const regexpCompileCache: {
|
||||
[key: string]: Function
|
||||
} = Object.create(null)
|
||||
|
||||
export function fillParams (
|
||||
path: string,
|
||||
params: ?Object,
|
||||
routeMsg: string
|
||||
): string {
|
||||
params = params || {}
|
||||
try {
|
||||
const filler =
|
||||
regexpCompileCache[path] ||
|
||||
(regexpCompileCache[path] = Regexp.compile(path))
|
||||
|
||||
// Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }}
|
||||
// and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string
|
||||
if (typeof params.pathMatch === 'string') params[0] = params.pathMatch
|
||||
|
||||
return filler(params, { pretty: true })
|
||||
} catch (e) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// Fix #3072 no warn if `pathMatch` is string
|
||||
warn(typeof params.pathMatch === 'string', `missing param for ${routeMsg}: ${e.message}`)
|
||||
}
|
||||
return ''
|
||||
} finally {
|
||||
// delete the 0 if it was added
|
||||
delete params[0]
|
||||
}
|
||||
}
|
74
node_modules/vue-router/src/util/path.js
generated
vendored
Normal file
74
node_modules/vue-router/src/util/path.js
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/* @flow */
|
||||
|
||||
export function resolvePath (
|
||||
relative: string,
|
||||
base: string,
|
||||
append?: boolean
|
||||
): string {
|
||||
const firstChar = relative.charAt(0)
|
||||
if (firstChar === '/') {
|
||||
return relative
|
||||
}
|
||||
|
||||
if (firstChar === '?' || firstChar === '#') {
|
||||
return base + relative
|
||||
}
|
||||
|
||||
const stack = base.split('/')
|
||||
|
||||
// remove trailing segment if:
|
||||
// - not appending
|
||||
// - appending to trailing slash (last segment is empty)
|
||||
if (!append || !stack[stack.length - 1]) {
|
||||
stack.pop()
|
||||
}
|
||||
|
||||
// resolve relative path
|
||||
const segments = relative.replace(/^\//, '').split('/')
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const segment = segments[i]
|
||||
if (segment === '..') {
|
||||
stack.pop()
|
||||
} else if (segment !== '.') {
|
||||
stack.push(segment)
|
||||
}
|
||||
}
|
||||
|
||||
// ensure leading slash
|
||||
if (stack[0] !== '') {
|
||||
stack.unshift('')
|
||||
}
|
||||
|
||||
return stack.join('/')
|
||||
}
|
||||
|
||||
export function parsePath (path: string): {
|
||||
path: string;
|
||||
query: string;
|
||||
hash: string;
|
||||
} {
|
||||
let hash = ''
|
||||
let query = ''
|
||||
|
||||
const hashIndex = path.indexOf('#')
|
||||
if (hashIndex >= 0) {
|
||||
hash = path.slice(hashIndex)
|
||||
path = path.slice(0, hashIndex)
|
||||
}
|
||||
|
||||
const queryIndex = path.indexOf('?')
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1)
|
||||
path = path.slice(0, queryIndex)
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
query,
|
||||
hash
|
||||
}
|
||||
}
|
||||
|
||||
export function cleanPath (path: string): string {
|
||||
return path.replace(/\/(?:\s*\/)+/g, '/')
|
||||
}
|
46
node_modules/vue-router/src/util/push-state.js
generated
vendored
Normal file
46
node_modules/vue-router/src/util/push-state.js
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/* @flow */
|
||||
|
||||
import { inBrowser } from './dom'
|
||||
import { saveScrollPosition } from './scroll'
|
||||
import { genStateKey, setStateKey, getStateKey } from './state-key'
|
||||
import { extend } from './misc'
|
||||
|
||||
export const supportsPushState =
|
||||
inBrowser &&
|
||||
(function () {
|
||||
const ua = window.navigator.userAgent
|
||||
|
||||
if (
|
||||
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
|
||||
ua.indexOf('Mobile Safari') !== -1 &&
|
||||
ua.indexOf('Chrome') === -1 &&
|
||||
ua.indexOf('Windows Phone') === -1
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
return window.history && typeof window.history.pushState === 'function'
|
||||
})()
|
||||
|
||||
export function pushState (url?: string, replace?: boolean) {
|
||||
saveScrollPosition()
|
||||
// try...catch the pushState call to get around Safari
|
||||
// DOM Exception 18 where it limits to 100 pushState calls
|
||||
const history = window.history
|
||||
try {
|
||||
if (replace) {
|
||||
// preserve existing history state as it could be overriden by the user
|
||||
const stateCopy = extend({}, history.state)
|
||||
stateCopy.key = getStateKey()
|
||||
history.replaceState(stateCopy, '', url)
|
||||
} else {
|
||||
history.pushState({ key: setStateKey(genStateKey()) }, '', url)
|
||||
}
|
||||
} catch (e) {
|
||||
window.location[replace ? 'replace' : 'assign'](url)
|
||||
}
|
||||
}
|
||||
|
||||
export function replaceState (url?: string) {
|
||||
pushState(url, true)
|
||||
}
|
113
node_modules/vue-router/src/util/query.js
generated
vendored
Normal file
113
node_modules/vue-router/src/util/query.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/* @flow */
|
||||
|
||||
import { warn } from './warn'
|
||||
|
||||
const encodeReserveRE = /[!'()*]/g
|
||||
const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
|
||||
const commaRE = /%2C/g
|
||||
|
||||
// fixed encodeURIComponent which is more conformant to RFC3986:
|
||||
// - escapes [!'()*]
|
||||
// - preserve commas
|
||||
const encode = str =>
|
||||
encodeURIComponent(str)
|
||||
.replace(encodeReserveRE, encodeReserveReplacer)
|
||||
.replace(commaRE, ',')
|
||||
|
||||
export function decode (str: string) {
|
||||
try {
|
||||
return decodeURIComponent(str)
|
||||
} catch (err) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(false, `Error decoding "${str}". Leaving it intact.`)
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
export function resolveQuery (
|
||||
query: ?string,
|
||||
extraQuery: Dictionary<string> = {},
|
||||
_parseQuery: ?Function
|
||||
): Dictionary<string> {
|
||||
const parse = _parseQuery || parseQuery
|
||||
let parsedQuery
|
||||
try {
|
||||
parsedQuery = parse(query || '')
|
||||
} catch (e) {
|
||||
process.env.NODE_ENV !== 'production' && warn(false, e.message)
|
||||
parsedQuery = {}
|
||||
}
|
||||
for (const key in extraQuery) {
|
||||
const value = extraQuery[key]
|
||||
parsedQuery[key] = Array.isArray(value)
|
||||
? value.map(castQueryParamValue)
|
||||
: castQueryParamValue(value)
|
||||
}
|
||||
return parsedQuery
|
||||
}
|
||||
|
||||
const castQueryParamValue = value => (value == null || typeof value === 'object' ? value : String(value))
|
||||
|
||||
function parseQuery (query: string): Dictionary<string> {
|
||||
const res = {}
|
||||
|
||||
query = query.trim().replace(/^(\?|#|&)/, '')
|
||||
|
||||
if (!query) {
|
||||
return res
|
||||
}
|
||||
|
||||
query.split('&').forEach(param => {
|
||||
const parts = param.replace(/\+/g, ' ').split('=')
|
||||
const key = decode(parts.shift())
|
||||
const val = parts.length > 0 ? decode(parts.join('=')) : null
|
||||
|
||||
if (res[key] === undefined) {
|
||||
res[key] = val
|
||||
} else if (Array.isArray(res[key])) {
|
||||
res[key].push(val)
|
||||
} else {
|
||||
res[key] = [res[key], val]
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
export function stringifyQuery (obj: Dictionary<string>): string {
|
||||
const res = obj
|
||||
? Object.keys(obj)
|
||||
.map(key => {
|
||||
const val = obj[key]
|
||||
|
||||
if (val === undefined) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (val === null) {
|
||||
return encode(key)
|
||||
}
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
const result = []
|
||||
val.forEach(val2 => {
|
||||
if (val2 === undefined) {
|
||||
return
|
||||
}
|
||||
if (val2 === null) {
|
||||
result.push(encode(key))
|
||||
} else {
|
||||
result.push(encode(key) + '=' + encode(val2))
|
||||
}
|
||||
})
|
||||
return result.join('&')
|
||||
}
|
||||
|
||||
return encode(key) + '=' + encode(val)
|
||||
})
|
||||
.filter(x => x.length > 0)
|
||||
.join('&')
|
||||
: null
|
||||
return res ? `?${res}` : ''
|
||||
}
|
109
node_modules/vue-router/src/util/resolve-components.js
generated
vendored
Normal file
109
node_modules/vue-router/src/util/resolve-components.js
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/* @flow */
|
||||
|
||||
import { _Vue } from '../install'
|
||||
import { warn } from './warn'
|
||||
import { isError } from '../util/errors'
|
||||
|
||||
export function resolveAsyncComponents (matched: Array<RouteRecord>): Function {
|
||||
return (to, from, next) => {
|
||||
let hasAsync = false
|
||||
let pending = 0
|
||||
let error = null
|
||||
|
||||
flatMapComponents(matched, (def, _, match, key) => {
|
||||
// if it's a function and doesn't have cid attached,
|
||||
// assume it's an async component resolve function.
|
||||
// we are not using Vue's default async resolving mechanism because
|
||||
// we want to halt the navigation until the incoming component has been
|
||||
// resolved.
|
||||
if (typeof def === 'function' && def.cid === undefined) {
|
||||
hasAsync = true
|
||||
pending++
|
||||
|
||||
const resolve = once(resolvedDef => {
|
||||
if (isESModule(resolvedDef)) {
|
||||
resolvedDef = resolvedDef.default
|
||||
}
|
||||
// save resolved on async factory in case it's used elsewhere
|
||||
def.resolved = typeof resolvedDef === 'function'
|
||||
? resolvedDef
|
||||
: _Vue.extend(resolvedDef)
|
||||
match.components[key] = resolvedDef
|
||||
pending--
|
||||
if (pending <= 0) {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
const reject = once(reason => {
|
||||
const msg = `Failed to resolve async component ${key}: ${reason}`
|
||||
process.env.NODE_ENV !== 'production' && warn(false, msg)
|
||||
if (!error) {
|
||||
error = isError(reason)
|
||||
? reason
|
||||
: new Error(msg)
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
let res
|
||||
try {
|
||||
res = def(resolve, reject)
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
if (res) {
|
||||
if (typeof res.then === 'function') {
|
||||
res.then(resolve, reject)
|
||||
} else {
|
||||
// new syntax in Vue 2.3
|
||||
const comp = res.component
|
||||
if (comp && typeof comp.then === 'function') {
|
||||
comp.then(resolve, reject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!hasAsync) next()
|
||||
}
|
||||
}
|
||||
|
||||
export function flatMapComponents (
|
||||
matched: Array<RouteRecord>,
|
||||
fn: Function
|
||||
): Array<?Function> {
|
||||
return flatten(matched.map(m => {
|
||||
return Object.keys(m.components).map(key => fn(
|
||||
m.components[key],
|
||||
m.instances[key],
|
||||
m, key
|
||||
))
|
||||
}))
|
||||
}
|
||||
|
||||
export function flatten (arr: Array<any>): Array<any> {
|
||||
return Array.prototype.concat.apply([], arr)
|
||||
}
|
||||
|
||||
const hasSymbol =
|
||||
typeof Symbol === 'function' &&
|
||||
typeof Symbol.toStringTag === 'symbol'
|
||||
|
||||
function isESModule (obj) {
|
||||
return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
|
||||
}
|
||||
|
||||
// in Webpack 2, require.ensure now also returns a Promise
|
||||
// so the resolve/reject functions may get called an extra time
|
||||
// if the user uses an arrow function shorthand that happens to
|
||||
// return that Promise.
|
||||
function once (fn) {
|
||||
let called = false
|
||||
return function (...args) {
|
||||
if (called) return
|
||||
called = true
|
||||
return fn.apply(this, args)
|
||||
}
|
||||
}
|
151
node_modules/vue-router/src/util/route.js
generated
vendored
Normal file
151
node_modules/vue-router/src/util/route.js
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
/* @flow */
|
||||
|
||||
import type VueRouter from '../index'
|
||||
import { stringifyQuery } from './query'
|
||||
|
||||
const trailingSlashRE = /\/?$/
|
||||
|
||||
export function createRoute (
|
||||
record: ?RouteRecord,
|
||||
location: Location,
|
||||
redirectedFrom?: ?Location,
|
||||
router?: VueRouter
|
||||
): Route {
|
||||
const stringifyQuery = router && router.options.stringifyQuery
|
||||
|
||||
let query: any = location.query || {}
|
||||
try {
|
||||
query = clone(query)
|
||||
} catch (e) {}
|
||||
|
||||
const route: Route = {
|
||||
name: location.name || (record && record.name),
|
||||
meta: (record && record.meta) || {},
|
||||
path: location.path || '/',
|
||||
hash: location.hash || '',
|
||||
query,
|
||||
params: location.params || {},
|
||||
fullPath: getFullPath(location, stringifyQuery),
|
||||
matched: record ? formatMatch(record) : []
|
||||
}
|
||||
if (redirectedFrom) {
|
||||
route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery)
|
||||
}
|
||||
return Object.freeze(route)
|
||||
}
|
||||
|
||||
function clone (value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(clone)
|
||||
} else if (value && typeof value === 'object') {
|
||||
const res = {}
|
||||
for (const key in value) {
|
||||
res[key] = clone(value[key])
|
||||
}
|
||||
return res
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
// the starting route that represents the initial state
|
||||
export const START = createRoute(null, {
|
||||
path: '/'
|
||||
})
|
||||
|
||||
function formatMatch (record: ?RouteRecord): Array<RouteRecord> {
|
||||
const res = []
|
||||
while (record) {
|
||||
res.unshift(record)
|
||||
record = record.parent
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function getFullPath (
|
||||
{ path, query = {}, hash = '' },
|
||||
_stringifyQuery
|
||||
): string {
|
||||
const stringify = _stringifyQuery || stringifyQuery
|
||||
return (path || '/') + stringify(query) + hash
|
||||
}
|
||||
|
||||
export function isSameRoute (a: Route, b: ?Route, onlyPath: ?boolean): boolean {
|
||||
if (b === START) {
|
||||
return a === b
|
||||
} else if (!b) {
|
||||
return false
|
||||
} else if (a.path && b.path) {
|
||||
return a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && (onlyPath ||
|
||||
a.hash === b.hash &&
|
||||
isObjectEqual(a.query, b.query))
|
||||
} else if (a.name && b.name) {
|
||||
return (
|
||||
a.name === b.name &&
|
||||
(onlyPath || (
|
||||
a.hash === b.hash &&
|
||||
isObjectEqual(a.query, b.query) &&
|
||||
isObjectEqual(a.params, b.params))
|
||||
)
|
||||
)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isObjectEqual (a = {}, b = {}): boolean {
|
||||
// handle null value #1566
|
||||
if (!a || !b) return a === b
|
||||
const aKeys = Object.keys(a).sort()
|
||||
const bKeys = Object.keys(b).sort()
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
return false
|
||||
}
|
||||
return aKeys.every((key, i) => {
|
||||
const aVal = a[key]
|
||||
const bKey = bKeys[i]
|
||||
if (bKey !== key) return false
|
||||
const bVal = b[key]
|
||||
// query values can be null and undefined
|
||||
if (aVal == null || bVal == null) return aVal === bVal
|
||||
// check nested equality
|
||||
if (typeof aVal === 'object' && typeof bVal === 'object') {
|
||||
return isObjectEqual(aVal, bVal)
|
||||
}
|
||||
return String(aVal) === String(bVal)
|
||||
})
|
||||
}
|
||||
|
||||
export function isIncludedRoute (current: Route, target: Route): boolean {
|
||||
return (
|
||||
current.path.replace(trailingSlashRE, '/').indexOf(
|
||||
target.path.replace(trailingSlashRE, '/')
|
||||
) === 0 &&
|
||||
(!target.hash || current.hash === target.hash) &&
|
||||
queryIncludes(current.query, target.query)
|
||||
)
|
||||
}
|
||||
|
||||
function queryIncludes (current: Dictionary<string>, target: Dictionary<string>): boolean {
|
||||
for (const key in target) {
|
||||
if (!(key in current)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function handleRouteEntered (route: Route) {
|
||||
for (let i = 0; i < route.matched.length; i++) {
|
||||
const record = route.matched[i]
|
||||
for (const name in record.instances) {
|
||||
const instance = record.instances[name]
|
||||
const cbs = record.enteredCbs[name]
|
||||
if (!instance || !cbs) continue
|
||||
delete record.enteredCbs[name]
|
||||
for (let i = 0; i < cbs.length; i++) {
|
||||
if (!instance._isBeingDestroyed) cbs[i](instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
175
node_modules/vue-router/src/util/scroll.js
generated
vendored
Normal file
175
node_modules/vue-router/src/util/scroll.js
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/* @flow */
|
||||
|
||||
import type Router from '../index'
|
||||
import { assert } from './warn'
|
||||
import { getStateKey, setStateKey } from './state-key'
|
||||
import { extend } from './misc'
|
||||
|
||||
const positionStore = Object.create(null)
|
||||
|
||||
export function setupScroll () {
|
||||
// Prevent browser scroll behavior on History popstate
|
||||
if ('scrollRestoration' in window.history) {
|
||||
window.history.scrollRestoration = 'manual'
|
||||
}
|
||||
// Fix for #1585 for Firefox
|
||||
// Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678
|
||||
// Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with
|
||||
// window.location.protocol + '//' + window.location.host
|
||||
// location.host contains the port and location.hostname doesn't
|
||||
const protocolAndPath = window.location.protocol + '//' + window.location.host
|
||||
const absolutePath = window.location.href.replace(protocolAndPath, '')
|
||||
// preserve existing history state as it could be overriden by the user
|
||||
const stateCopy = extend({}, window.history.state)
|
||||
stateCopy.key = getStateKey()
|
||||
window.history.replaceState(stateCopy, '', absolutePath)
|
||||
window.addEventListener('popstate', handlePopState)
|
||||
return () => {
|
||||
window.removeEventListener('popstate', handlePopState)
|
||||
}
|
||||
}
|
||||
|
||||
export function handleScroll (
|
||||
router: Router,
|
||||
to: Route,
|
||||
from: Route,
|
||||
isPop: boolean
|
||||
) {
|
||||
if (!router.app) {
|
||||
return
|
||||
}
|
||||
|
||||
const behavior = router.options.scrollBehavior
|
||||
if (!behavior) {
|
||||
return
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(typeof behavior === 'function', `scrollBehavior must be a function`)
|
||||
}
|
||||
|
||||
// wait until re-render finishes before scrolling
|
||||
router.app.$nextTick(() => {
|
||||
const position = getScrollPosition()
|
||||
const shouldScroll = behavior.call(
|
||||
router,
|
||||
to,
|
||||
from,
|
||||
isPop ? position : null
|
||||
)
|
||||
|
||||
if (!shouldScroll) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof shouldScroll.then === 'function') {
|
||||
shouldScroll
|
||||
.then(shouldScroll => {
|
||||
scrollToPosition((shouldScroll: any), position)
|
||||
})
|
||||
.catch(err => {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(false, err.toString())
|
||||
}
|
||||
})
|
||||
} else {
|
||||
scrollToPosition(shouldScroll, position)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function saveScrollPosition () {
|
||||
const key = getStateKey()
|
||||
if (key) {
|
||||
positionStore[key] = {
|
||||
x: window.pageXOffset,
|
||||
y: window.pageYOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handlePopState (e) {
|
||||
saveScrollPosition()
|
||||
if (e.state && e.state.key) {
|
||||
setStateKey(e.state.key)
|
||||
}
|
||||
}
|
||||
|
||||
function getScrollPosition (): ?Object {
|
||||
const key = getStateKey()
|
||||
if (key) {
|
||||
return positionStore[key]
|
||||
}
|
||||
}
|
||||
|
||||
function getElementPosition (el: Element, offset: Object): Object {
|
||||
const docEl: any = document.documentElement
|
||||
const docRect = docEl.getBoundingClientRect()
|
||||
const elRect = el.getBoundingClientRect()
|
||||
return {
|
||||
x: elRect.left - docRect.left - offset.x,
|
||||
y: elRect.top - docRect.top - offset.y
|
||||
}
|
||||
}
|
||||
|
||||
function isValidPosition (obj: Object): boolean {
|
||||
return isNumber(obj.x) || isNumber(obj.y)
|
||||
}
|
||||
|
||||
function normalizePosition (obj: Object): Object {
|
||||
return {
|
||||
x: isNumber(obj.x) ? obj.x : window.pageXOffset,
|
||||
y: isNumber(obj.y) ? obj.y : window.pageYOffset
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeOffset (obj: Object): Object {
|
||||
return {
|
||||
x: isNumber(obj.x) ? obj.x : 0,
|
||||
y: isNumber(obj.y) ? obj.y : 0
|
||||
}
|
||||
}
|
||||
|
||||
function isNumber (v: any): boolean {
|
||||
return typeof v === 'number'
|
||||
}
|
||||
|
||||
const hashStartsWithNumberRE = /^#\d/
|
||||
|
||||
function scrollToPosition (shouldScroll, position) {
|
||||
const isObject = typeof shouldScroll === 'object'
|
||||
if (isObject && typeof shouldScroll.selector === 'string') {
|
||||
// getElementById would still fail if the selector contains a more complicated query like #main[data-attr]
|
||||
// but at the same time, it doesn't make much sense to select an element with an id and an extra selector
|
||||
const el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line
|
||||
? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line
|
||||
: document.querySelector(shouldScroll.selector)
|
||||
|
||||
if (el) {
|
||||
let offset =
|
||||
shouldScroll.offset && typeof shouldScroll.offset === 'object'
|
||||
? shouldScroll.offset
|
||||
: {}
|
||||
offset = normalizeOffset(offset)
|
||||
position = getElementPosition(el, offset)
|
||||
} else if (isValidPosition(shouldScroll)) {
|
||||
position = normalizePosition(shouldScroll)
|
||||
}
|
||||
} else if (isObject && isValidPosition(shouldScroll)) {
|
||||
position = normalizePosition(shouldScroll)
|
||||
}
|
||||
|
||||
if (position) {
|
||||
// $flow-disable-line
|
||||
if ('scrollBehavior' in document.documentElement.style) {
|
||||
window.scrollTo({
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
// $flow-disable-line
|
||||
behavior: shouldScroll.behavior
|
||||
})
|
||||
} else {
|
||||
window.scrollTo(position.x, position.y)
|
||||
}
|
||||
}
|
||||
}
|
22
node_modules/vue-router/src/util/state-key.js
generated
vendored
Normal file
22
node_modules/vue-router/src/util/state-key.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/* @flow */
|
||||
import { inBrowser } from './dom'
|
||||
|
||||
// use User Timing api (if present) for more accurate key precision
|
||||
const Time =
|
||||
inBrowser && window.performance && window.performance.now
|
||||
? window.performance
|
||||
: Date
|
||||
|
||||
export function genStateKey (): string {
|
||||
return Time.now().toFixed(3)
|
||||
}
|
||||
|
||||
let _key: string = genStateKey()
|
||||
|
||||
export function getStateKey () {
|
||||
return _key
|
||||
}
|
||||
|
||||
export function setStateKey (key: string) {
|
||||
return (_key = key)
|
||||
}
|
14
node_modules/vue-router/src/util/warn.js
generated
vendored
Normal file
14
node_modules/vue-router/src/util/warn.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/* @flow */
|
||||
|
||||
export function assert (condition: any, message: string) {
|
||||
if (!condition) {
|
||||
throw new Error(`[vue-router] ${message}`)
|
||||
}
|
||||
}
|
||||
|
||||
export function warn (condition: any, message: string) {
|
||||
if (!condition) {
|
||||
typeof console !== 'undefined' && console.warn(`[vue-router] ${message}`)
|
||||
}
|
||||
}
|
||||
|
51
node_modules/vue-router/types/composables.d.ts
generated
vendored
Normal file
51
node_modules/vue-router/types/composables.d.ts
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
import type { Route, NavigationGuard, default as VueRouter } from './index'
|
||||
|
||||
/**
|
||||
* Returns the current route location. Equivalent to using `$route` inside templates.
|
||||
*/
|
||||
export function useRoute(): Route
|
||||
|
||||
/**
|
||||
* Returns the router instance. Equivalent to using `$router` inside templates.
|
||||
*/
|
||||
export function useRouter(): VueRouter
|
||||
|
||||
/**
|
||||
* Add a navigation guard that triggers whenever the current location is about to be updated. Similar to beforeRouteUpdate but can be used in any component. The guard is removed when the component is unmounted.
|
||||
*
|
||||
* @param updateGuard
|
||||
*/
|
||||
export function onBeforeRouteUpdate(updateGuard: NavigationGuard): void
|
||||
|
||||
/**
|
||||
* Add a navigation guard that triggers whenever the component for the current location is about to be left. Similar to beforeRouteLeave but can be used in any component. The guard is removed when the component is unmounted.
|
||||
*
|
||||
* @param leaveGuard
|
||||
*/
|
||||
export function onBeforeRouteLeave(leaveGuard: NavigationGuard): void
|
||||
|
||||
export interface RouterLinkOptions {
|
||||
/**
|
||||
* Route Location the link should navigate to when clicked on.
|
||||
*/
|
||||
to: Route | Ref<Route>
|
||||
/**
|
||||
* Calls `router.replace` instead of `router.push`.
|
||||
*/
|
||||
replace?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Vue Router 4 `useLink()` function. Note the active behavior is different from Vue Router 3 as highlighted in the
|
||||
* migration guide (https://router.vuejs.org/guide/migration/index.html#removal-of-the-exact-prop-in-router-link)
|
||||
*
|
||||
* @param props - object containing a `to` property with the location
|
||||
*/
|
||||
export function useLink({ to, replace }: RouterLinkOptions): {
|
||||
route: ComputedRef<Route>,
|
||||
isActive: ComputedRef<boolean>,
|
||||
isExactActive: ComputedRef<boolean>,
|
||||
href: ComputedRef<string>,
|
||||
navigate: () => Promise<void>,
|
||||
}
|
23
node_modules/vue-router/types/index.d.ts
generated
vendored
Normal file
23
node_modules/vue-router/types/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import './vue'
|
||||
import { VueRouter, RouterLink, RouterView, START_LOCATION, NavigationFailureType, isNavigationFailure } from './router'
|
||||
|
||||
export default VueRouter
|
||||
export { RouterView, RouterLink, START_LOCATION, NavigationFailureType, isNavigationFailure }
|
||||
|
||||
export type {
|
||||
RouterMode,
|
||||
RouteMeta,
|
||||
RawLocation,
|
||||
RedirectOption,
|
||||
RouterOptions,
|
||||
RouteConfig,
|
||||
RouteRecord,
|
||||
RouteRecordPublic,
|
||||
Location,
|
||||
Route,
|
||||
NavigationGuard,
|
||||
NavigationGuardNext,
|
||||
NavigationFailure
|
||||
} from './router'
|
||||
|
||||
import './composables'
|
573
node_modules/vue-router/types/router.d.ts
generated
vendored
Normal file
573
node_modules/vue-router/types/router.d.ts
generated
vendored
Normal file
@ -0,0 +1,573 @@
|
||||
import Vue, {
|
||||
PluginFunction,
|
||||
AsyncComponent,
|
||||
VNode,
|
||||
Component as _Component
|
||||
} from 'vue'
|
||||
|
||||
type Component =
|
||||
| {}
|
||||
| _Component<any, any, any, any>
|
||||
| AsyncComponent<any, any, any, any>
|
||||
|
||||
type Dictionary<T> = { [key: string]: T }
|
||||
type ErrorHandler = (err: Error) => void
|
||||
|
||||
export type RouterMode = 'hash' | 'history' | 'abstract'
|
||||
export type RawLocation = string | Location
|
||||
export type RedirectOption = RawLocation | ((to: Route) => RawLocation)
|
||||
export type NavigationGuardNext<V extends Vue = Vue> = (
|
||||
to?: RawLocation | false | ((vm: V) => any) | void
|
||||
) => void
|
||||
|
||||
export type NavigationGuard<V extends Vue = Vue> = (
|
||||
to: Route,
|
||||
from: Route,
|
||||
next: NavigationGuardNext<V>
|
||||
) => any
|
||||
|
||||
/**
|
||||
* Router instance.
|
||||
*/
|
||||
export declare class VueRouter {
|
||||
constructor(options?: RouterOptions)
|
||||
|
||||
app: Vue
|
||||
/**
|
||||
* Original options object passed to create the Router
|
||||
*/
|
||||
options: RouterOptions
|
||||
/**
|
||||
* Configured mode when creating the Router instance.
|
||||
*/
|
||||
mode: RouterMode
|
||||
/**
|
||||
* Current {@link Route}
|
||||
*/
|
||||
currentRoute: Route
|
||||
|
||||
/**
|
||||
* Add a navigation guard that executes before any navigation.
|
||||
*
|
||||
* @param guard - navigation guard to add
|
||||
* @returns a function that removes the registered guard
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* router.beforeEach((to, from, next) => {
|
||||
* // must call `next`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
beforeEach(guard: NavigationGuard): () => void
|
||||
/**
|
||||
* Add a navigation guard that executes before navigation is about to be resolved. At this state all component have
|
||||
* been fetched and other navigation guards have been successful.
|
||||
*
|
||||
* @param guard - navigation guard to add
|
||||
* @returns a function that removes the registered guard
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* router.beforeResolve((to, from, next) => {
|
||||
* // must call `next`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
beforeResolve(guard: NavigationGuard): () => void
|
||||
/**
|
||||
* Add a navigation hook that is executed after every navigation. Returns a function that removes the registered hook.
|
||||
*
|
||||
* @param hook - navigation hook to add
|
||||
* @returns a function that removes the registered guard
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* router.afterEach((to, from) => {
|
||||
* console.log('after navigation')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
afterEach(hook: (to: Route, from: Route) => any): () => void
|
||||
/**
|
||||
* Programmatically navigate to a new URL by pushing an entry in the history stack.
|
||||
*
|
||||
* @param to Route location to navigate to
|
||||
*/
|
||||
push(to: RawLocation): Promise<Route>
|
||||
/**
|
||||
* Programmatically navigate to a new URL by pushing an entry in the history stack.
|
||||
*
|
||||
* @param to Route location to navigate to
|
||||
* @param onComplete Navigation success callback
|
||||
* @param onAbort Navigation aborted callback
|
||||
*/
|
||||
push(
|
||||
to: RawLocation,
|
||||
onComplete?: (route: Route) => void,
|
||||
onAbort?: ErrorHandler
|
||||
): void
|
||||
/**
|
||||
* Programmatically navigate to a new URL by replacing the current entry in the history stack.
|
||||
*
|
||||
* @param to Route location to navigate to
|
||||
*/
|
||||
replace(to: RawLocation): Promise<Route>
|
||||
/**
|
||||
* Programmatically navigate to a new URL by replacing the current entry in the history stack.
|
||||
*
|
||||
* @param to Route location to navigate to
|
||||
* @param onComplete Navigation success callback
|
||||
* @param onAbort Navigation aborted callback
|
||||
*/
|
||||
replace(
|
||||
to: RawLocation,
|
||||
onComplete?: (route: Route) => void,
|
||||
onAbort?: ErrorHandler
|
||||
): void
|
||||
/**
|
||||
* Allows you to move forward or backward through the history. Calls `history.go()`.
|
||||
*
|
||||
* @param delta The position in the history to which you want to move, relative to the current page
|
||||
*/
|
||||
go(n: number): void
|
||||
/**
|
||||
* Go back in history if possible by calling `history.back()`. Equivalent to `router.go(-1)`.
|
||||
*/
|
||||
back(): void
|
||||
/**
|
||||
* Go forward in history if possible by calling `history.forward()`. Equivalent to `router.go(1)`.
|
||||
*/
|
||||
forward(): void
|
||||
match (raw: RawLocation, current?: Route, redirectedFrom?: Location): Route
|
||||
getMatchedComponents(to?: RawLocation | Route): Component[]
|
||||
/**
|
||||
* This method queues a callback to be called when the router has completed the initial navigation, which means it has
|
||||
* resolved all async enter hooks and async components that are associated with the initial route.
|
||||
*
|
||||
* This is useful in server-side rendering to ensure consistent output on both the server and the client.
|
||||
* @param cb onReady callback.
|
||||
* @param errorCb errorCb will be called when the initial route resolution runs into an error (e.g. failed to resolve
|
||||
* an async component).
|
||||
*/
|
||||
onReady(cb: () => void, errorCb?: ErrorHandler): void
|
||||
/**
|
||||
* Adds an error handler that is called every time a non caught error happens during navigation. This includes errors
|
||||
* thrown synchronously and asynchronously, errors returned or passed to `next` in any navigation guard, and errors
|
||||
* occurred when trying to resolve an async component that is required to render a route.
|
||||
*
|
||||
* @param handler - error handler to register
|
||||
*/
|
||||
onError(cb: ErrorHandler): void
|
||||
/**
|
||||
* @deprecated use {@link addRoute | router.addRoute()} instead
|
||||
*/
|
||||
addRoutes(routes: RouteConfig[]): void
|
||||
/**
|
||||
* Add a new {@link RouteConfig | route record} as the child of an existing route. If the route has a `name` and there
|
||||
* is already an existing one with the same one, it overwrites it.
|
||||
*
|
||||
* @param parentName - Parent Route Record where `route` should be appended at
|
||||
* @param route - Route Record to add
|
||||
*/
|
||||
addRoute(parentName: string, route: RouteConfig): void
|
||||
/**
|
||||
* Add a new {@link RouteConfig | route} to the router. If the route has a `name` and there is already an existing one
|
||||
* with the same one, it overwrites it.
|
||||
* @param route - Route Record to add
|
||||
*/
|
||||
addRoute(route: RouteConfig): void
|
||||
/**
|
||||
* Get the list of all the active route records.
|
||||
*/
|
||||
getRoutes(): RouteRecordPublic[]
|
||||
|
||||
/**
|
||||
*
|
||||
* @param to Route location
|
||||
* @param current current is the current Route by default (most of the time you don't need to change this)
|
||||
* @param append allows you to append the path to the `current` route (as with `router-link`)
|
||||
*/
|
||||
resolve(
|
||||
to: RawLocation,
|
||||
current?: Route,
|
||||
append?: boolean
|
||||
): {
|
||||
location: Location
|
||||
route: Route
|
||||
href: string
|
||||
/**
|
||||
* backwards compat
|
||||
*/
|
||||
normalizedTo: Location
|
||||
/**
|
||||
* backwards compat
|
||||
*/
|
||||
resolved: Route
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static install: PluginFunction<never>
|
||||
static version: string
|
||||
|
||||
static isNavigationFailure: typeof isNavigationFailure
|
||||
static NavigationFailureType: {
|
||||
[k in keyof typeof NavigationFailureType]: NavigationFailureType
|
||||
}
|
||||
|
||||
static START_LOCATION: Route
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration with all possible types for navigation failures.
|
||||
*
|
||||
* Can be passed to {@link isNavigationFailure} to check for specific failures.
|
||||
*/
|
||||
export enum NavigationFailureType {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
redirected = 2,
|
||||
/**
|
||||
* An aborted navigation is a navigation that failed because a navigation guard returned `false` or called
|
||||
* `next(false)`
|
||||
*/
|
||||
aborted = 4,
|
||||
/**
|
||||
* A cancelled navigation is a navigation that failed because a more recent navigation finished started (not
|
||||
* necessarily finished).
|
||||
*/
|
||||
cancelled = 8,
|
||||
/**
|
||||
* A duplicated navigation is a navigation that failed because it was initiated while already being at the exact same
|
||||
* location.
|
||||
*/
|
||||
duplicated = 16
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended Error that contains extra information regarding a failed navigation.
|
||||
*/
|
||||
export interface NavigationFailure extends Error {
|
||||
/**
|
||||
* Route location we were navigating from
|
||||
*/
|
||||
from: Route
|
||||
/**
|
||||
* Route location we were navigating to
|
||||
*/
|
||||
to: Route
|
||||
/**
|
||||
* Type of the navigation. One of {@link NavigationFailureType}
|
||||
*/
|
||||
type: NavigationFailureType.aborted | NavigationFailureType.cancelled | NavigationFailureType.duplicated
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an object is a {@link NavigationFailure}.
|
||||
*/
|
||||
export declare function isNavigationFailure(error: any, type?: NavigationFailureType): error is NavigationFailure
|
||||
|
||||
type Position = { x: number; y: number }
|
||||
type PositionResult = Position | { selector: string; offset?: Position, behavior?: ScrollBehavior } | void
|
||||
|
||||
|
||||
/**
|
||||
* Options to initialize a {@link VueRouter} instance.
|
||||
*/
|
||||
export interface RouterOptions {
|
||||
routes?: RouteConfig[]
|
||||
/**
|
||||
* Configure the router mode.
|
||||
*
|
||||
* default: `"hash"` (in browser) | `"abstract"` (in Node.js)
|
||||
*
|
||||
* available values: `"hash" | "history" | "abstract"`
|
||||
* - `"hash"`: uses the URL hash for routing. Works in all Vue-supported browsers, including those that do not support
|
||||
* HTML5 History API.
|
||||
* - `"history"`: requires HTML5 History API and server config. See HTML5 History Mode.
|
||||
* - `"abstract"`: works in all JavaScript environments, e.g. server-side with Node.js. **The router will
|
||||
* automatically be forced into this mode if no browser API is present.**
|
||||
*/
|
||||
mode?: RouterMode
|
||||
fallback?: boolean
|
||||
base?: string
|
||||
/**
|
||||
* Default class applied to active {@link RouterLink}. If none is provided, `router-link-active` will be applied.
|
||||
*/
|
||||
linkActiveClass?: string
|
||||
/**
|
||||
* Default class applied to active {@link RouterLink}. If none is provided, `router-link-exact-active` will be
|
||||
* applied.
|
||||
*/
|
||||
linkExactActiveClass?: string
|
||||
/**
|
||||
* Custom implementation to parse a query. See its counterpart, {@link stringifyQuery}.
|
||||
*/
|
||||
parseQuery?: (query: string) => Object
|
||||
/**
|
||||
* Custom implementation to stringify a query object. Should not prepend a leading `?`. {@link parseQuery} counterpart
|
||||
* to handle query parsing.
|
||||
*/
|
||||
stringifyQuery?: (query: Object) => string
|
||||
/**
|
||||
* Function to control scrolling when navigating between pages. Can return a Promise to delay scrolling.
|
||||
*
|
||||
* For more details see {@link Scroll Behavior}.
|
||||
*/
|
||||
scrollBehavior?: (
|
||||
to: Route,
|
||||
from: Route,
|
||||
savedPosition: Position | void
|
||||
) => PositionResult | Promise<PositionResult> | undefined | null
|
||||
}
|
||||
|
||||
type RoutePropsFunction = (route: Route) => Object
|
||||
|
||||
export interface PathToRegexpOptions {
|
||||
sensitive?: boolean
|
||||
strict?: boolean
|
||||
end?: boolean
|
||||
}
|
||||
|
||||
interface _RouteConfigBase {
|
||||
path: string
|
||||
name?: string
|
||||
children?: RouteConfig[]
|
||||
redirect?: RedirectOption
|
||||
alias?: string | string[]
|
||||
meta?: RouteMeta
|
||||
beforeEnter?: NavigationGuard
|
||||
caseSensitive?: boolean
|
||||
pathToRegexpOptions?: PathToRegexpOptions
|
||||
}
|
||||
|
||||
interface RouteConfigSingleView extends _RouteConfigBase {
|
||||
component?: Component
|
||||
props?: boolean | Object | RoutePropsFunction
|
||||
}
|
||||
|
||||
interface RouteConfigMultipleViews extends _RouteConfigBase {
|
||||
components?: Dictionary<Component>
|
||||
props?: Dictionary<boolean | Object | RoutePropsFunction>
|
||||
}
|
||||
|
||||
export type RouteConfig = RouteConfigSingleView | RouteConfigMultipleViews
|
||||
|
||||
export interface RouteRecord {
|
||||
path: string
|
||||
regex: RegExp
|
||||
components: Dictionary<Component>
|
||||
instances: Dictionary<Vue>
|
||||
name?: string
|
||||
parent?: RouteRecord
|
||||
redirect?: RedirectOption
|
||||
matchAs?: string
|
||||
meta: RouteMeta
|
||||
beforeEnter?: (
|
||||
route: Route,
|
||||
redirect: (location: RawLocation) => void,
|
||||
next: () => void
|
||||
) => any
|
||||
props:
|
||||
| boolean
|
||||
| Object
|
||||
| RoutePropsFunction
|
||||
| Dictionary<boolean | Object | RoutePropsFunction>
|
||||
}
|
||||
|
||||
export interface RouteRecordPublic {
|
||||
path: string
|
||||
components: Dictionary<Component>
|
||||
instances: Dictionary<Vue>
|
||||
name?: string
|
||||
redirect?: RedirectOption
|
||||
meta: any
|
||||
beforeEnter?: (
|
||||
route: Route,
|
||||
redirect: (location: RawLocation) => void,
|
||||
next: () => void
|
||||
) => any
|
||||
props:
|
||||
| boolean
|
||||
| Object
|
||||
| RoutePropsFunction
|
||||
| Dictionary<boolean | Object | RoutePropsFunction>
|
||||
}
|
||||
|
||||
|
||||
export interface Location {
|
||||
name?: string
|
||||
path?: string
|
||||
hash?: string
|
||||
query?: Dictionary<string | (string | null)[] | null | undefined>
|
||||
params?: Dictionary<string>
|
||||
append?: boolean
|
||||
replace?: boolean
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
path: string
|
||||
name?: string | null
|
||||
hash: string
|
||||
query: Dictionary<string | (string | null)[]>
|
||||
params: Dictionary<string>
|
||||
fullPath: string
|
||||
matched: RouteRecord[]
|
||||
redirectedFrom?: string
|
||||
meta?: RouteMeta
|
||||
}
|
||||
|
||||
export interface RouteMeta extends Record<string | number | symbol, any> {}
|
||||
|
||||
export interface RouterLinkProps {
|
||||
/**
|
||||
* Denotes the target route of the link. When clicked, the value of the `to` prop will be passed to
|
||||
* `router.push()` internally, so the value can be either a string or a location descriptor object.
|
||||
*/
|
||||
to: string | Location
|
||||
/**
|
||||
* Setting `replace` prop will call `router.replace()` instead of `router.push()` when clicked, so the navigation will
|
||||
* not create a new history record.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
replace?: boolean
|
||||
/**
|
||||
* Setting `append` prop always appends the relative path to the current path. For example, assuming we are navigating
|
||||
* from `/a` to a relative link `b`, without `append` we will end up at `/b`, but with append we will end up at
|
||||
* `/a/b`.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
append?: boolean
|
||||
/**
|
||||
* Sometimes we want <RouterLink> to render as another tag, e.g <li>. Then we can use tag prop to specify which tag to
|
||||
* render to, and it will still listen to click events for navigation.
|
||||
*
|
||||
* @default "a"
|
||||
*/
|
||||
tag?: string
|
||||
/**
|
||||
* Configure the active CSS class applied when the link is active. Note the default value can also be configured
|
||||
* globally via the `linkActiveClass` router constructor option.
|
||||
*
|
||||
* @default "router-link-active"
|
||||
*/
|
||||
activeClass?: string
|
||||
/**
|
||||
* The default active class matching behavior is **inclusive match**. For example, `<RouterLink to="/a">` will get
|
||||
* this class applied as long as the current path starts with `/a/` or is `/a`.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
exact?: boolean
|
||||
/**
|
||||
* Allows matching only using the `path` section of the url, effectively ignoring the `query` and the `hash` sections.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
exactPath?: boolean
|
||||
/**
|
||||
* Configure the active CSS class applied when the link is active with exact path match. Note the default value can
|
||||
* also be configured globally via the `linkExactPathActiveClass` router constructor option.
|
||||
*
|
||||
* @default "router-link-exact-path-active"
|
||||
*/
|
||||
exactPathActiveClass?: string
|
||||
|
||||
/**
|
||||
* Specify the event(s) that can trigger the link navigation.
|
||||
*
|
||||
* @default 'click'
|
||||
*/
|
||||
event?: string | ReadonlyArray<string>
|
||||
/**
|
||||
* Configure the active CSS class applied when the link is active with exact match. Note the default value can also be
|
||||
* configured globally via the `linkExactActiveClass` router constructor option.
|
||||
*
|
||||
* @default "router-link-exact-active"
|
||||
*/
|
||||
exactActiveClass?: string
|
||||
/**
|
||||
* Configure the value of `aria-current` when the link is active with exact match. It must be one of the allowed
|
||||
* values for [aria-current](https://www.w3.org/TR/wai-aria-1.2/#aria-current) in the ARIA spec. In most cases, the
|
||||
* default of page should be the best fit.
|
||||
*
|
||||
* @default "page"
|
||||
*/
|
||||
ariaCurrentValue?:
|
||||
| 'page'
|
||||
| 'step'
|
||||
| 'location'
|
||||
| 'date'
|
||||
| 'time'
|
||||
| 'true'
|
||||
| 'false'
|
||||
}
|
||||
|
||||
export interface RouterLinkSlotArgument {
|
||||
/**
|
||||
* resolved url. This would be the `href` attribute of an `a` element
|
||||
*/
|
||||
href: string
|
||||
/**
|
||||
* resolved normalized location
|
||||
*/
|
||||
route: Route
|
||||
/**
|
||||
* function to trigger the navigation. It will automatically prevent events when necessary, the same way `RouterLink`
|
||||
* does
|
||||
*/
|
||||
navigate: (e?: MouseEvent) => Promise<undefined | NavigationFailure>
|
||||
/**
|
||||
* `true` if the [active class](https://v3.router.vuejs.org/api/#active-class) should be applied. Allows to apply an
|
||||
* arbitrary class
|
||||
*/
|
||||
isActive: boolean
|
||||
/**
|
||||
* `true` if the [exact active class](https://v3.router.vuejs.org/api/#exact-active-class) should be applied. Allows
|
||||
* to apply an arbitrary class
|
||||
*/
|
||||
isExactActive: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to render a link that triggers a navigation on click.
|
||||
*/
|
||||
export declare const RouterLink: new () => {
|
||||
$props: RouterLinkProps
|
||||
$scopedSlots: {
|
||||
default?: ({
|
||||
href,
|
||||
route,
|
||||
navigate,
|
||||
isActive,
|
||||
isExactActive
|
||||
}: RouterLinkSlotArgument) => VNode[] | undefined
|
||||
}
|
||||
}
|
||||
|
||||
export interface RouterViewProps {
|
||||
/**
|
||||
* When a {@link RouterView | `<RouterView />`} has a name, it will render the component with the corresponding name
|
||||
* in the matched route record's components option. See [Named
|
||||
* Views](https://v3.router.vuejs.org/guide/essentials/named-views.html) for an example.
|
||||
*
|
||||
* @default "default"
|
||||
*/
|
||||
name?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to display the current route the user is at.
|
||||
*/
|
||||
export declare const RouterView: new () => {
|
||||
$props: RouterViewProps
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial route location where the router is. Can be used in navigation guards to differentiate the initial navigation.
|
||||
*/
|
||||
export declare const START_LOCATION: Route
|
22
node_modules/vue-router/types/vue.d.ts
generated
vendored
Normal file
22
node_modules/vue-router/types/vue.d.ts
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Augment the typings of Vue.js
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import VueRouter, { Route, NavigationGuard } from './index'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
$router: VueRouter
|
||||
$route: Route
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue/types/options' {
|
||||
interface ComponentOptions<V extends Vue> {
|
||||
router?: VueRouter
|
||||
beforeRouteEnter?: NavigationGuard<V>
|
||||
beforeRouteLeave?: NavigationGuard<V>
|
||||
beforeRouteUpdate?: NavigationGuard<V>
|
||||
}
|
||||
}
|
38
node_modules/vue-router/vetur/attributes.json
generated
vendored
Normal file
38
node_modules/vue-router/vetur/attributes.json
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "When a `<router-view>` has a `name` prop, it will render the component with the corresponding name in the matched route record's components option."
|
||||
},
|
||||
"to": {
|
||||
"description": "Denotes the target route of the link. When clicked, the value of the `to` prop will be internally passed to `router.push()`, so the value can be either a string or a location descriptor object."
|
||||
},
|
||||
"append": {
|
||||
"type": "boolean",
|
||||
"description": "Setting the append prop always appends the relative path to the current path. For example, assuming we are navigating from /a to a relative link b, without append we will end up at /b, but with append we will end up at /a/b."
|
||||
},
|
||||
"tag": {
|
||||
"description": "Specify which tag to render to, and it will still listen to click events for navigation. By default, an `a` tag is rendered."
|
||||
},
|
||||
"event": {
|
||||
"description": "Specify the event(s) that can trigger the link navigation. By default, the `click` event triggers a navigation."
|
||||
},
|
||||
"replace": {
|
||||
"type": "boolean",
|
||||
"description": "Call `router.replace()` instead of `router.push()` when the link is clicked, so the navigation replaces the current history entry."
|
||||
},
|
||||
"exact": {
|
||||
"description": "The default active class matching behavior is inclusive match. For example, `<router-link to=\"/a\">` will get this class applied as long as the current path starts with /a/ or is /a.\nOne consequence of this is that `<router-link to=\"/\">` will be active for every route! To force the link into \"exact match mode\", use the exact prop: `<router-link to=\"/\" exact>`"
|
||||
},
|
||||
"active-class": {
|
||||
"type": "string",
|
||||
"description": "Configure the active CSS class applied when the link is active. Note the default value can also be configured globally via the `linkActiveClass` router constructor option."
|
||||
},
|
||||
"exact-active-class": {
|
||||
"type": "string",
|
||||
"description": "Configure the active CSS class applied when the link is exactly active. Note the default value can also be configured globally via the `linkExactActiveClass` router constructor option."
|
||||
},
|
||||
"aria-current-value": {
|
||||
"options": ["page", "step", "location", "date", "time", "true", "false"],
|
||||
"description": "Configure the value of `aria-current` when the link is active with exact match. It must be one of the [allowed values for `aria-current`](https://www.w3.org/TR/wai-aria-1.2/#aria-current) in the ARIA spec. In most cases, the default of `page` should be the best fit."
|
||||
}
|
||||
}
|
20
node_modules/vue-router/vetur/tags.json
generated
vendored
Normal file
20
node_modules/vue-router/vetur/tags.json
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"router-view": {
|
||||
"attributes": ["name"],
|
||||
"description": "Component that renders the matched component for the current location. Components rendered by `<router-view>` can also contain their own `<router-view>` to render nested routes."
|
||||
},
|
||||
"router-link": {
|
||||
"attributes": [
|
||||
"to",
|
||||
"replace",
|
||||
"append",
|
||||
"tag",
|
||||
"active-class",
|
||||
"exact",
|
||||
"event",
|
||||
"exact-active-class",
|
||||
"aria-current-value"
|
||||
],
|
||||
"description": "Component that renders an `<a>` with the correct `href` attribute and click listeners to trigger a local navigation when clicked. Can also customize its rendering by providing the `custom` prop and using its `v-slot` API."
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user