Skip to content
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

feat: support scoped and v-bind() #11459

Closed
wants to merge 12 commits into from
Closed
29 changes: 14 additions & 15 deletions packages/vant-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vant/cli",
"version": "5.1.0",
"name": "@cfit/vant-cli",
"version": "0.0.2",
"type": "module",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand All @@ -27,24 +27,21 @@
"vant"
],
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/vant-ui/vant.git",
"directory": "packages/vant-cli"
},
"bugs": "https://github.com/vant-ui/vant/issues",
"author": "chenjiahan",
"license": "MIT",
"peerDependencies": {
"vue": "^2.7.14 || ^3.2.45",
"vue-router": "^3.6.5 || ^4.1.5"
},
"devDependencies": {
"@jest/types": "^29.1.2",
"@types/fs-extra": "^9.0.13",
"@types/less": "^3.0.3",
"@types/lodash": "^4.14.191",
"@types/markdown-it": "^12.2.3",
"vue": "^3.2.45"
"vue": "2.7.14",
"vue-router": "3.6.5"
},
"dependencies": {
"@babel/core": "^7.18.13",
Expand All @@ -54,7 +51,10 @@
"@vant/touch-emulator": "^1.4.0",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"@vitejs/plugin-vue2": "^2.2.0",
"@vitejs/plugin-vue2-jsx": "^1.1.0",
"@vue/babel-plugin-jsx": "^1.1.1",
"@vue/babel-preset-jsx": "^1.4.0",
"autoprefixer": "^10.4.8",
"commander": "^9.4.0",
"consola": "^2.15.3",
Expand Down Expand Up @@ -86,13 +86,12 @@
"transliteration": "^2.3.5",
"typescript": "^4.8.2",
"vite": "^4.0.3",
"vite-plugin-md": "^0.11.9",
"vue-router": "^4.1.5"
"vite-plugin-md": "^0.11.9"
},
"release-it": {
"git": {
"tag": false,
"commitMessage": "release: @vant/cli ${version}"
"commitMessage": "release: @cfit/vant-cli ${version}"
}
}
}
10 changes: 7 additions & 3 deletions packages/vant-cli/site/common/iframe-sync.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ref } from 'vue';
import { config } from 'site-desktop-shared';

export function getCurrentRoute() {
const currentRoute = window.vueRouter?.currentRoute;
return currentRoute?.value || currentRoute;
}

let queue = [];
let isIframeReady = false;

Expand All @@ -25,8 +30,7 @@ if (window.top === window) {
}

function getCurrentDir() {
const router = window.vueRouter;
const { path } = router.currentRoute.value;
const { path } = getCurrentRoute();

if (config.site.simulator?.routeMapper) {
return config.site.simulator?.routeMapper(path);
Expand Down Expand Up @@ -110,7 +114,7 @@ export function listenToSyncPath(router) {

const path = event.data?.value || '';
// should preserve hash for anchor
if (router.currentRoute.value.path !== path) {
if (getCurrentRoute().path !== path) {
router.replace(path).catch(() => {});
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/vant-cli/site/desktop/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import App from './App.vue';
import DemoPlayground from './components/DemoPlayground.vue';
import { router } from './router';

window.app = createApp(App)
const app = createApp(App)
.use(router)
.component(DemoPlayground.name, DemoPlayground);

setTimeout(() => {
window.app.mount('#app');
app.mount('#app');
}, 0);
14 changes: 14 additions & 0 deletions packages/vant-cli/site/desktop/vue2/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Vue from 'vue';
import App from '../App.vue';
import DemoPlayground from '../components/DemoPlayground.vue';
import { router } from './router';

const app = new Vue({
router,
render: (h) => h(App),
});
Vue.component(DemoPlayground.name, DemoPlayground);

setTimeout(() => {
app.$mount('#app');
}, 0);
124 changes: 124 additions & 0 deletions packages/vant-cli/site/desktop/vue2/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router';
import { isMobile, decamelize } from '../../common';
import { config, documents } from 'site-desktop-shared';
import { getLang, setDefaultLang } from '../../common/locales';
import { listenToSyncPath, syncPathToChild } from '../../common/iframe-sync';

if (isMobile) {
location.replace('mobile.html' + location.hash);

Check warning

Code scanning / CodeQL

Client-side URL redirect

Untrusted URL redirection depends on a [user-provided value](1).
}

Vue.use(VueRouter);

const { locales, defaultLang } = config.site;

setDefaultLang(defaultLang);

function parseName(name) {
if (name.indexOf('_') !== -1) {
const pairs = name.split('_');
const component = pairs.shift();

return {
component: `${decamelize(component)}`,
lang: pairs.join('-'),
};
}

return {
component: `${decamelize(name)}`,
lang: '',
};
}

function getLangFromRoute(route) {
const lang = route.path.split('/')[1];
const langs = Object.keys(locales);

if (langs.indexOf(lang) !== -1) {
return lang;
}

return getLang();
}

function getRoutes() {
const routes: any[] = [];
const names = Object.keys(documents);

function addHomeRoute(Home, lang) {
routes.push({
name: lang || 'home',
path: `/${lang || ''}`,
component: Home,
meta: { lang },
});
}

names.forEach((name) => {
const { component, lang } = parseName(name);

if (component === 'home') {
addHomeRoute(documents[name], lang);
}

if (lang) {
routes.push({
name: `${lang}/${component}`,
path: `/${lang}/${component}`,
component: documents[name],
meta: {
lang,
name: component,
},
});
} else {
routes.push({
name: `${component}`,
path: `/${component}`,
component: documents[name],
meta: {
name: component,
},
});
}
});

if (locales) {
routes.push({
name: 'notFound',
path: '/:path(.*)+',
redirect: (route) => ({
name: getLangFromRoute(route),
}),
});
} else {
routes.push({
name: 'notFound',
path: '/:path(.*)+',
redirect: {
name: 'home',
},
});
}

return routes;
}

export const router = new VueRouter({
routes: getRoutes(),
scrollBehavior() {
return { x: 0, y: 0 };
},
});

router.afterEach(() => {
nextTick(syncPathToChild);
});

if (config.site.simulator?.syncPathFromSimulator !== false) {
listenToSyncPath(router);
}

window.vueRouter = router;
4 changes: 4 additions & 0 deletions packages/vant-cli/site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
</head>
<body>
<div id="app"></div>
<% if (isVue2) { %>
<script type="module" src="/desktop/vue2/main.js"></script>
<% } else { %>
<script type="module" src="/desktop/main.js"></script>
<% } %>
</body>
</html>
4 changes: 4 additions & 0 deletions packages/vant-cli/site/mobile.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
</head>
<body>
<div id="app"></div>
<% if (isVue2) { %>
<script type="module" src="/mobile/vue2/main.js"></script>
<% } else { %>
<script type="module" src="/mobile/main.js"></script>
<% } %>
</body>
</html>
18 changes: 10 additions & 8 deletions packages/vant-cli/site/mobile/App.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<template>
<demo-nav />
<router-view v-slot="{ Component }">
<demo-section>
<keep-alive>
<component :is="Component" />
</keep-alive>
</demo-section>
</router-view>
<div>
<demo-nav />
<router-view v-slot="{ Component }">
<demo-section>
<keep-alive>
<component :is="Component" />
</keep-alive>
</demo-section>
</router-view>
</div>
</template>

<script>
Expand Down
4 changes: 2 additions & 2 deletions packages/vant-cli/site/mobile/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { router } from './router';
import App from './App.vue';
import '@vant/touch-emulator';

window.app = createApp(App)
const app = createApp(App)
.use(router)
.component(DemoBlock.name, DemoBlock)
.component(DemoSection.name, DemoSection);

setTimeout(() => {
window.app.mount('#app');
app.mount('#app');
}, 0);

// https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari/33681490#33681490
Expand Down
2 changes: 1 addition & 1 deletion packages/vant-cli/site/mobile/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import DemoHome from './components/DemoHome.vue';
import { decamelize } from '../common';
import { demos, config } from 'site-mobile-shared';
import { getLang, setDefaultLang } from '../common/locales';
import { listenToSyncPath, syncPathToParent } from '../common/iframe-sync';
import { listenToSyncPath, syncPathToParent, getCurrentRoute } from '../common/iframe-sync';

const { locales, defaultLang } = config.site;

Expand Down
22 changes: 22 additions & 0 deletions packages/vant-cli/site/mobile/vue2/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Vue from 'vue';
import DemoBlock from '../components/DemoBlock.vue';
import DemoSection from '../components/DemoSection.vue';
import { router } from './router';
import App from '../App.vue';
import '@vant/touch-emulator';

const app = new Vue({
router,
render: (h) => h(App),
});
Vue.component(DemoBlock.name, DemoBlock);
Vue.component(DemoSection.name, DemoSection);

setTimeout(() => {
app.$mount('#app');
}, 0);

// https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari/33681490#33681490
document.addEventListener('touchstart', () => {}, {
passive: true,
});