Skip to content

feat: add vue 2.7 support #3763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
*.ts
26 changes: 24 additions & 2 deletions build/configs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
const path = require('path')
const buble = require('rollup-plugin-buble')
const flow = require('rollup-plugin-flow-no-whitespace')
Expand All @@ -12,9 +13,23 @@ const banner =
* @license MIT
*/`

/**
* @param {string} _path
*/
const resolve = _path => path.resolve(__dirname, '../', _path)

module.exports = [
/**
* @typedef {object} OutputOption - the option for build output
* @property {string} file
* @property {'umd' | 'cjs' | 'es'} format
* @property {'development' |'production'} [env]
* @property {boolean} [transpile=true]
*/

/**
* @type {Array<OutputOption>}
*/
const outputOptions = [
// browser dev
{
file: resolve('dist/vue-router.js'),
Expand Down Expand Up @@ -46,8 +61,15 @@ module.exports = [
env: 'production',
transpile: false
}
].map(genConfig)
]

module.exports = outputOptions.map(genConfig)

/**
*
* @param {OutputOption} opts
* @returns
*/
function genConfig (opts) {
const config = {
input: {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@
"rollup-watch": "^4.0.0",
"selenium-server": "^3.141.59",
"terser": "^4.2.0",
"typescript": "^3.5.2",
"vue": "^2.6.12",
"typescript": "^4.8.1-rc",
"vue": "^2.7.8",
"vue-loader": "^15.9.3",
"vue-server-renderer": "^2.6.12",
"vue-template-compiler": "^2.6.12",
Expand Down
38 changes: 38 additions & 0 deletions src/composable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getCurrentInstance, reactive, watchEffect } from 'vue'
import { assert } from './util/warn'

/**
* Returns the current route location. Equivalent to using `$route` inside
* templates.
*/
export function useRoute () {
const instance = getCurrentInstance()
assert(instance, `useRoute must be used inside a setup context`)
const route = reactive(Object.assign({}, instance.proxy.$root.$route))
watchEffect(() => {
Object.assign(route, instance.proxy.$root.$route)
})

return route
}

/**
* Returns the router instance. Equivalent to using `$router` inside
* templates.
*/
export function useRouter () {
const instance = getCurrentInstance()
assert(instance, `useRouter must be used inside a setup context`)
const router = instance.proxy.$root.$router
watchEffect(() => {
if (router) {
Object.assign(router, instance.proxy.$root.$router)
}
})
return router
}

// TODO: function useLink(props) { }
// TODO: function onBeforeRouteLeave(leaveGuard) { }
// TODO: function onBeforeRouteUpdate(updateGuard) { }

6 changes: 6 additions & 0 deletions src/v4-compat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { default as VueRouter } from './index'
export { default as RouterLink } from './components/link'
export { default as RouterView } from './components/view'
export { useRoute, useRouter } from './composable'
export { NavigationFailureType, isNavigationFailure } from './util/errors'
export { START as START_LOCATION } from './util/route'
2 changes: 1 addition & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { VueRouter } from './router'

export default VueRouter

export {
export type {
RouterMode,
RouteMeta,
RawLocation,
Expand Down
9 changes: 9 additions & 0 deletions types/router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,17 @@ export declare class VueRouter {

export enum NavigationFailureType {
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
}

Expand Down
166 changes: 166 additions & 0 deletions types/v4-compat.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import type { VNode } from 'vue'
import { type NavigationFailure, Route, VueRouter } from './router'

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 leave a 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'
}

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.
*/
declare const RouterLink: new (props: RouterLinkProps) => {
$props: typeof props
$scopedSlots: {
default?: ({
href,
route,
navigate,
isActive,
isExactActive
}: RouterLinkSlotArgument) => VNode[] | undefined
}
}

interface RouterViewProps {
/**
* When a <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.
*/
declare const RouterView: new (props: RouterViewProps) => {
$props: typeof props
}

declare function useRoute(): Route
declare function useRouter(): VueRouter
declare function isNavigationFailure(error: any, type?: number): error is NavigationFailure
declare const START_LOCATION: Route // TODO: fix type here

export {
useRoute,
useRouter,
isNavigationFailure,
START_LOCATION,
type RouterViewProps,
RouterView,
type RouterLinkProps,
type RouterLinkSlotArgument,
RouterLink,
}
export {
type RouterMode,
type RouteMeta,
type RawLocation,
type RedirectOption,
type RouterOptions,
type RouteConfig,
type RouteRecord,
type RouteRecordPublic,
type Location,
type Route,
type NavigationGuard,
type NavigationGuardNext,
type NavigationFailure,
NavigationFailureType,
VueRouter,
} from './router'
Loading