Skip to content

Commit

Permalink
feat: Upgrade to Vue 3 (#44)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

Require Vue 3 and Vue Router 4
  • Loading branch information
eliottvincent committed Aug 12, 2021
1 parent c62f9a0 commit a9c916b
Show file tree
Hide file tree
Showing 12 changed files with 985 additions and 3,140 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
dist
cypress/videos
cypress/screenshots
2 changes: 1 addition & 1 deletion cypress/integration/spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
describe('My First Test', () => {
it('Does not do much!', () => {
cy.visit('http://localhost:4000')
cy.visit('http://localhost:3000')
cy.wait(1000)
cy.window().then(({ pages }) => {
expect([...pages]).to.deep.equal([1, 2, 3])
Expand Down
Binary file removed cypress/videos/prefetch_spec.js.mp4
Binary file not shown.
13 changes: 13 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.jsx"></script>
</body>
</html>
105 changes: 0 additions & 105 deletions example/index.js

This file was deleted.

67 changes: 67 additions & 0 deletions example/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { createApp, h } from 'vue'
import { createRouter, createWebHashHistory, RouterView } from 'vue-router'
import RoutePrefetch from '../src'
import Nav from './nav.vue'

const app = createApp({
setup() {
return () => h(RouterView)
}
})

const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: {
render() {
return (
<div>
<h1>hi</h1>
<Nav />
</div>
)
}
}
},
{
path: '/async-page',
meta: {
prefetch(route) {
console.log(route)
}
},
component: () => import('./async-page.vue')
}
]
})

app.use(router)
app.use(RoutePrefetch)

window.pages = new Set()

const createPage = id => async () => {
console.log(`fetching page ${id}`)
window.pages.add(id)
return {
render() {
return (
<div>
<h1>page {id}</h1>
<Nav />
</div>
)
}
}
}

for (let i = 0; i < 6; i++) {
router.addRoute({
path: `/page/${i + 1}`,
component: createPage(i + 1)
})
}

app.mount('#app')
34 changes: 34 additions & 0 deletions example/nav.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div>
<ul>
<li>
<router-link to="/page/1">page 1</router-link>
</li>
<li>
<router-link to="/page/2">page 2</router-link>
</li>
<li>
<router-link to="/page/3">page 3</router-link>
</li>
</ul>
<ul style="margin-top: 110vh;" id="bottom">
<li>
<router-link to="/page/4" :prefetchFiles="['/foo']">
page 4
</router-link>
</li>
<li>
<router-link to="/page/5">page 5</router-link>
</li>
<li>
<router-link to="/async-page">async-page</router-link>
</li>
<li>
<router-link to="/page/6">page 6</router-link>
</li>
<li>
<router-link to="/page/1">page 1</router-link>
</li>
</ul>
</div>
</template>
9 changes: 9 additions & 0 deletions example/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'

export default defineConfig({
plugins: [vue()],
esbuild: {
jsxFactory: 'h'
}
})
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"lint": "xo",
"build": "bili --format esm,cjs,esm-min --minimal",
"prepublishOnly": "npm run build",
"example": "poi example/index.js --serve --jsx vue",
"example": "vite example",
"commit": "git-cz",
"cy:run": "cypress run",
"cy:open": "cypress open",
Expand All @@ -27,10 +27,12 @@
"author": "egoist<0x142857@gmail.com>",
"license": "MIT",
"devDependencies": {
"@vitejs/plugin-vue": "^1.4.0",
"@vue/compiler-sfc": "^3.1.5",
"babel-eslint": "^10.0.1",
"bili": "^4.0.9",
"commitizen": "^3.0.5",
"cypress": "^3.3.2",
"cypress": "^8.2.0",
"cz-conventional-changelog": "^2.1.0",
"eslint-config-prettier": "^3.3.0",
"eslint-config-rem": "^4.0.0",
Expand All @@ -40,12 +42,11 @@
"husky": "^1.0.0-rc.13",
"lint-staged": "^7.2.0",
"npm-run-all": "^4.1.5",
"poi": "^12.4.6",
"prettier": "^1.15.2",
"semantic-release": "^17.3.0",
"vue": "^2.5.22",
"vue-router": "^3.0.2",
"vue-template-compiler": "^2.5.22",
"vite": "^2.4.4",
"vue": "^3.1.5",
"vue-router": "^4.0.10",
"xo": "^0.23.0"
},
"xo": {
Expand Down
38 changes: 25 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import prefetch from './prefetch'
import { canPrefetch, supportIntersectionObserver, inBrowser } from './utils'

function installRouterPrefetch(
Vue,
/** @type {import('vue').App} */
app,
{ componentName = 'RouterLink', prefetch: enablePrefetch = true } = {}
) {
const observer =
Expand All @@ -29,18 +30,18 @@ function installRouterPrefetch(
}, timeout)
}

const RouterLink = Vue.component('RouterLink') || Vue.component('router-link')
const RouterLink = app.component('RouterLink') || app.component('router-link')

if (process.env.NODE_ENV === 'development' && !RouterLink) {
console.error(
`[vue-router-prefetch] You need to call Vue.use(VueRouter) before this plugin!`
`[vue-router-prefetch] You need to call app.use(VueRouter) before this plugin!`
)
}

const Link = {
name: componentName,
extends: RouterLink,
props: {
...RouterLink.props,
prefetch: {
type: Boolean,
default: enablePrefetch
Expand All @@ -53,12 +54,15 @@ function installRouterPrefetch(
default: 2000
}
},
setup(props, context) {
return RouterLink.setup(props, context)
},
mounted() {
if (this.prefetch && observer && canPrefetch) {
requestIdleCallback(this.observe, { timeout: this.timeout })
}
},
beforeDestroy() {
beforeUnmount() {
this.unobserve()
},
methods: {
Expand All @@ -72,21 +76,28 @@ function installRouterPrefetch(
observer.unobserve(this.$el)
}
},
getComponents() {
return this.$router.getMatchedComponents(this.to).filter(Component => {
return Component.cid === undefined && typeof Component === 'function'
})
getRouteComponents(route) {
return route.matched
.map(record => {
return Object.values(record.components)
})
.flat()
.filter(Component => {
return (
Component.cid === undefined && typeof Component === 'function'
)
})
},
linkPrefetch() {
const { route } = this.$router.resolve(this.to)
const route = this.$router.resolve(this.to)

if (route.meta.__prefetched) return

route.meta.__prefetched = true

if (route.meta.prefetch !== false) {
// Prefetch route component
const components = this.getComponents()
const components = this.getRouteComponents(route)
for (const Component of components) {
this.$emit('prefetch', this.to)
Component() // eslint-disable-line new-cap
Expand All @@ -113,12 +124,13 @@ function installRouterPrefetch(
}
}

Vue.component(Link.name, Link)
// `app.component(Link.name, Link)` will emit a warning
app._context.components[Link.name] = Link
}

export {
prefetch,
// Export as `install` to make `Vue.use(require('vue-router-prefetch'))` work
// Export as `install` to make `app.use(require('vue-router-prefetch'))` work
installRouterPrefetch as install
}

Expand Down

0 comments on commit a9c916b

Please sign in to comment.