Compare commits

...

49 Commits

Author SHA1 Message Date
chenjiahan
b45b0b7608 chore: update branches in GitHub actions 2022-09-10 21:57:09 +08:00
chenjiahan
c309ca2aaf docs: switch dev branch to v4 2022-09-10 21:53:49 +08:00
chenjiahan
66df033ec8 Merge branch 'dev' into next 2022-09-10 21:51:26 +08:00
neverland
e2ea3be819
feat: export props of all components (#11024) 2022-09-10 21:49:21 +08:00
neverland
019c328975
chore: remove *.less from sideEffects (#11023) 2022-09-10 17:17:23 +08:00
neverland
0e55b72200
feat(Image): add block prop (#11022) 2022-09-10 17:13:14 +08:00
neverland
69d3ba000c
chore: bump pnpm version to 7.11 (#11021) 2022-09-10 12:46:55 +08:00
neverland
9418fe371d
docs: improve use component guide (#11020) 2022-09-10 12:28:43 +08:00
neverland
5d8282ddae
docs(Toast): add component usage guide (#11019) 2022-09-10 11:40:11 +08:00
neverland
43ff890d79
feat(Toast): add message slot (#11018) 2022-09-10 11:32:38 +08:00
neverland
98642589ee
docs: add picker-group to migration guide (#11016) 2022-09-08 23:16:08 +08:00
neverland
6f910c9913
feat(Dialog): message-align can be justify (#11014) 2022-09-07 23:20:28 +08:00
chenjiahan
1b08f84ac6 docs(changelog): @vant/cli 4.0.4 2022-09-06 00:03:50 +08:00
chenjiahan
f0d3e04fba release: @vant/cli 4.0.4 2022-09-06 00:03:00 +08:00
neverland
830a1eb5cf
fix(@vant/cli): failed to build types of sfc (#11012) 2022-09-06 00:00:28 +08:00
Fengyuan Chen
cd439c04f3 fix(utils): avoid getting unexpected value (#11010)
For example, when calling `get({}, 'button.small')`, it expects to return an empty string, but return a function (`''.small` is a native function, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/small).
2022-09-05 23:42:11 +08:00
neverland
0aac165d4e
fix(Picker): failed to update value in some cases (#11009) 2022-09-04 21:00:18 +08:00
chenjiahan
f60a3b840d docs(changelog): vant@4.0.0-rc.0 2022-09-04 14:51:32 +08:00
chenjiahan
997f3e0acd release: 4.0.0-rc.0 2022-09-04 14:49:15 +08:00
chenjiahan
e2fe50250c Merge branch 'dev' into next 2022-09-04 14:34:46 +08:00
neverland
bc024a105c
docs(changelog): vant@3.6.2 (#11008) 2022-09-04 14:31:12 +08:00
chenjiahan
7afb74345a release: 3.6.2 2022-09-04 14:26:50 +08:00
neverland
65fdb2155b
chore: bump all deps (#11007)
* chore: bump all deps

* chore: fix type

* chore: fix withInstall type
2022-09-04 14:24:59 +08:00
neverland
c6bc97f4e4
docs: update quickstart guide (#11006)
* docs: update quickstart guide

* docs: update
2022-09-04 10:01:19 +08:00
chenjiahan
7d023fd6e4 docs: update babel-plugin-import tip 2022-09-04 09:59:42 +08:00
neverland
1afe960f30
feat: add new PickerGroup component (#11005)
* feat: add PickerGroup component

* chore: remove log

* chore: en doc

* chore: add snapshot

* docs: update
2022-09-04 09:39:37 +08:00
neverland
3e039b02b5
docs: add function component style guide (#11003) 2022-09-02 23:24:27 +08:00
Alan Wang
1837ed712f
fix(indexBar): index-bar not positioned correctly when scrolled to the bottom (#10994) 2022-09-02 23:01:22 +08:00
chenjiahan
94c5afe65c release: @vant/area-data 1.3.2 2022-09-01 23:23:23 +08:00
yanbo
5174a1a668
fix(area-data): update counties of Daxinganling region (#11000) 2022-09-01 16:29:17 +08:00
童欧巴
ed8cd77449
docs: fix card overflow issue (#10988)
Co-authored-by: huoyitong <huoyitong@lixiang.com>
2022-08-29 18:44:18 +08:00
neverland
a677bee2b8
fix(DatePicker): min-date prop not work correctly (#10985) 2022-08-28 17:11:04 +08:00
neverland
05544c109f
fix(DatePicker): failed to update model value (#10984) 2022-08-28 16:59:41 +08:00
neverland
21c57caa9b
docs(DatePicker): fix toolbar slot name (#10983) 2022-08-28 11:52:14 +08:00
chenjiahan
66aa2906e0 docs(DatePicker): fix basic usage 2022-08-28 11:01:49 +08:00
chenjiahan
61ef6b9a98 chore(Picker): add getEventParams function 2022-08-28 10:50:49 +08:00
neverland
c25acb8d46
chore(PIcker): split PickerToolbar component (#10982) 2022-08-28 10:43:14 +08:00
chenjiahan
8bcb34724f fix(Picker): fix passive event 2022-08-28 10:01:14 +08:00
chenjiahan
cf5e7e6629 Merge branch 'dev' into next 2022-08-28 09:47:56 +08:00
neverland
a02cfe9604
fix(Swipe): should not prevent touch move when reach edge (#10980) 2022-08-27 15:44:06 +08:00
neverland
71354f7742
fix(@vant/cli): add passive for global touchstart (#10979) 2022-08-27 15:22:56 +08:00
neverland
84b05f0668
docs: prefer using externalVue in nuxt 3 (#10978) 2022-08-27 15:07:43 +08:00
neverland
95542bf06e
docs: add nuxt 3 guide (#10977) 2022-08-27 13:48:59 +08:00
neverland
8d15fa4fdf
fix(Calendar): allow default date to be maxDate when enable allowSameDay (#10976) 2022-08-27 11:29:30 +08:00
chenyunjie
35f81fb208
fix(Calendar): range type defaultDate when set allowSameDay (#10971) 2022-08-27 11:15:46 +08:00
neverland
da3400435f
fix: reduce passive event warning of touchmove event (#10975) 2022-08-27 11:12:36 +08:00
neverland
50ee584953
docs(changelog): vant@4.0.0-beta.1 (#10966) 2022-08-24 22:53:35 +08:00
chenjiahan
6a7376d15d docs(changelog): 3.6.1 2022-08-24 22:43:13 +08:00
chenjiahan
2cca630808 release: 3.6.1 2022-08-24 22:40:20 +08:00
241 changed files with 6723 additions and 1190 deletions

View File

@ -2,7 +2,7 @@ name: Deploy V4 Site
on:
push:
branches: [next]
branches: [dev]
paths:
- 'packages/vant/docs/**'

View File

@ -2,7 +2,7 @@ name: Sync to Gitee
on:
push:
branches: [dev, 2.x, gh-pages]
branches: [dev, 2.x, 3.x, gh-pages]
workflow_dispatch:

2
.npmrc
View File

@ -1 +1,3 @@
registry=https://registry.npmmirror.com/
strict-peer-dependencies=false

View File

@ -14,14 +14,14 @@
"*.{ts,tsx,js,vue,less}": "prettier --write",
"*.{ts,tsx,js,vue}": "eslint --fix"
},
"packageManager": "pnpm@7.1.6",
"packageManager": "pnpm@7.11.0",
"devDependencies": {
"@vant/cli": "workspace:*",
"@vant/eslint-config": "workspace:*",
"eslint": "^8.2.0",
"eslint": "^8.23.0",
"husky": "^8.0.1",
"nano-staged": "^0.8.0",
"prettier": "^2.5.0",
"prettier": "^2.7.1",
"rimraf": "^3.0.2"
},
"pnpm": {

View File

@ -32,15 +32,15 @@
"license": "MIT",
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/inquirer": "^8.1.3",
"release-it": "^15.1.1",
"typescript": "^4.7.4"
"@types/inquirer": "^8.2.3",
"release-it": "^15.4.1",
"typescript": "^4.8.2"
},
"dependencies": {
"consola": "^2.11.3",
"fast-glob": "^3.2.4",
"fs-extra": "^10.0.0",
"inquirer": "^8.0.0",
"fast-glob": "^3.2.11",
"fs-extra": "^10.1.0",
"inquirer": "^8.2.4",
"picocolors": "^1.0.0"
},
"release-it": {

View File

@ -1,6 +1,6 @@
{
"name": "@vant/area-data",
"version": "1.3.1",
"version": "1.3.2",
"description": "Vant 省市区数据",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.mjs",
@ -36,9 +36,9 @@
"author": "chenjiahan",
"license": "MIT",
"devDependencies": {
"esbuild": "^0.14.29",
"release-it": "^15.1.1",
"typescript": "^4.7.4"
"esbuild": "^0.14.54",
"release-it": "^15.4.1",
"typescript": "^4.8.2"
},
"release-it": {
"git": {

View File

@ -1150,10 +1150,10 @@ export const areaList = {
232701: '漠河市',
232721: '呼玛县',
232722: '塔河县',
232790: '松岭区',
232791: '呼中区',
232792: '加格达奇区',
232793: '新林区',
232761: '加格达奇区',
232762: '松岭区',
232763: '新林区',
232764: '呼中区',
310101: '黄浦区',
310104: '徐汇区',
310105: '长宁区',

View File

@ -31,6 +31,12 @@ yarn add stylelint@13 @vant/stylelint-config
现在会默认生成 WebStorm 所需的 web-types.json 文件到 `lib/web-types.json` 目录下。
## v4.0.4
`2022-07-02`
- 修复构建 sfc 文件的类型定义时报错的问题
## v4.0.3
`2022-07-02`

View File

@ -1,6 +1,6 @@
{
"name": "@vant/cli",
"version": "4.0.3",
"version": "4.0.4",
"type": "module",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
@ -39,56 +39,56 @@
"author": "chenjiahan",
"license": "MIT",
"devDependencies": {
"@jest/types": "^27.5.1",
"@types/fs-extra": "^9.0.13",
"@types/less": "^3.0.3",
"@types/markdown-it": "^12.2.3",
"@jest/types": "^27",
"vue": "^3.2.27",
"react": "^18",
"react-dom": "^18"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vue": "^3.2.38"
},
"dependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"@docsearch/css": "^3.0.0",
"@docsearch/js": "^3.0.0",
"@types/jest": "^27.0.3",
"@vant/eslint-config": "^3.3.2",
"@vant/touch-emulator": "^1.3.2",
"@vitejs/plugin-vue": "^3.0.1",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"@babel/core": "^7.18.13",
"@babel/preset-typescript": "^7.18.6",
"@docsearch/css": "^3.2.1",
"@docsearch/js": "^3.2.1",
"@types/jest": "^27.5.2",
"@vant/eslint-config": "^3.5.0",
"@vant/touch-emulator": "^1.4.0",
"@vitejs/plugin-vue": "^3.0.3",
"@vitejs/plugin-vue-jsx": "^2.0.1",
"@vue/babel-plugin-jsx": "^1.1.1",
"autoprefixer": "^10.4.0",
"commander": "^9.3.0",
"autoprefixer": "^10.4.8",
"commander": "^9.4.0",
"consola": "^2.15.3",
"conventional-changelog": "^3.1.24",
"esbuild": "^0.14.29",
"eslint": "^8.1.0",
"conventional-changelog": "^3.1.25",
"esbuild": "^0.14.54",
"eslint": "^8.23.0",
"execa": "^5.1.1",
"fast-glob": "^3.2.7",
"fs-extra": "^10.0.0",
"fast-glob": "^3.2.11",
"fs-extra": "^10.1.0",
"hash-sum": "^2.0.0",
"highlight.js": "^11.3.1",
"highlight.js": "^11.6.0",
"husky": "^8.0.1",
"jest": "^27.3.1",
"jest-canvas-mock": "^2.3.1",
"jest": "^27.5.1",
"jest-canvas-mock": "^2.4.0",
"jest-serializer-html": "^7.1.0",
"less": "^4.1.2",
"markdown-it": "^12.2.0",
"markdown-it-anchor": "^8.4.1",
"less": "^4.1.3",
"markdown-it": "^12.3.2",
"markdown-it-anchor": "^8.6.4",
"nano-staged": "^0.8.0",
"nanospinner": "^1.1.0",
"picocolors": "^1.0.0",
"postcss": "^8.3.11",
"postcss-load-config": "^3.1.0",
"prettier": "^2.5.0",
"release-it": "^15.1.1",
"transliteration": "^2.2.0",
"typescript": "^4.7.4",
"vite": "^3.0.0",
"vite-plugin-html": "^2.1.1",
"vite-plugin-md": "^0.11.4",
"vue-router": "^4.0.12"
"postcss": "^8.4.16",
"postcss-load-config": "^3.1.4",
"prettier": "^2.7.1",
"release-it": "^15.4.1",
"transliteration": "^2.3.5",
"typescript": "^4.8.2",
"vite": "^3.0.9",
"vite-plugin-html": "^2.1.2",
"vite-plugin-md": "^0.11.9",
"vue-router": "^4.1.5"
},
"release-it": {
"git": {

View File

@ -87,6 +87,7 @@ export default {
padding: 24px;
background-color: var(--van-doc-background-2);
border-radius: var(--van-doc-border-radius);
overflow: auto;
> pre code {
position: relative;

View File

@ -30,7 +30,7 @@
</script>
<% } %>
</head>
<body ontouchstart>
<body>
<div id="app"></div>
<script type="module" src="/desktop/main.js"></script>
</body>

View File

@ -39,7 +39,7 @@
</script>
<% } %>
</head>
<body ontouchstart>
<body>
<div id="app"></div>
<script type="module" src="/mobile/main.js"></script>
</body>

View File

@ -13,3 +13,8 @@ window.app = createApp(App)
setTimeout(() => {
window.app.mount('#app');
}, 0);
// https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari/33681490#33681490
document.addEventListener('touchstart', () => {}, {
passive: true,
});

View File

@ -87,11 +87,6 @@ export async function compileSfc(filePath: string): Promise<any> {
new Promise((resolve) => {
let script = '';
// the generated render fn lacks type definitions
if (lang === 'ts') {
script += '// @ts-nocheck\n';
}
let bindingMetadata;
if (descriptor.scriptSetup) {
const { bindings, content } = compileScript(descriptor, {
@ -125,6 +120,12 @@ export async function compileSfc(filePath: string): Promise<any> {
script += `\n${EXPORT} ${VUEIDS}`;
// ts-nocheck should be placed on the first line
// the generated render fn lacks type definitions
if (lang === 'ts') {
script = '// @ts-nocheck\n' + script;
}
outputFile(scriptFilePath, script).then(resolve);
})
);

View File

@ -20,17 +20,17 @@
"author": "chenjiahan",
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "^5.30.3",
"@typescript-eslint/parser": "^5.30.3",
"@typescript-eslint/eslint-plugin": "^5.36.1",
"@typescript-eslint/parser": "^5.36.1",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-vue": "^9.1.1"
"eslint-plugin-vue": "^9.4.0"
},
"devDependencies": {
"enhanced-resolve": "^5.10.0",
"eslint": "^8.19.0",
"typescript": "^4.7.4"
"eslint": "^8.23.0",
"typescript": "^4.8.2"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0"

View File

@ -23,7 +23,7 @@
"author": "chenjiahan",
"license": "MIT",
"devDependencies": {
"release-it": "^15.1.1"
"release-it": "^15.4.1"
},
"release-it": {
"git": {

View File

@ -37,12 +37,12 @@
"author": "chenjiahan",
"license": "MIT",
"dependencies": {
"@popperjs/core": "^2.9.2"
"@popperjs/core": "^2.11.6"
},
"devDependencies": {
"esbuild": "^0.14.29",
"release-it": "^15.1.1",
"typescript": "^4.7.4"
"esbuild": "^0.14.54",
"release-it": "^15.4.1",
"typescript": "^4.8.2"
},
"release-it": {
"git": {

View File

@ -37,10 +37,10 @@
"author": "chenjiahan",
"license": "MIT",
"devDependencies": {
"esbuild": "^0.14.29",
"release-it": "^15.1.1",
"typescript": "^4.7.4",
"vue": "^3.2.27"
"esbuild": "^0.14.54",
"release-it": "^15.4.1",
"typescript": "^4.8.2",
"vue": "^3.2.38"
},
"release-it": {
"git": {

View File

@ -19,6 +19,77 @@ Vant follows [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
## Details
### [v4.0.0-rc.0](https://github.com/vant-ui/vant/compare/v3.6.2...v4.0.0-rc.0)
`2022-09-04`
**New Component**
- Add new component [PickerGroup](#/en-US/picker-group) [#11005](https://github.com/vant-ui/vant/issues/11005)
**Bug Fixes**
- DatePicker: failed to update model value [#10984](https://github.com/vant-ui/vant/issues/10984)
- DatePicker: min-date prop not work correctly [#10985](https://github.com/vant-ui/vant/issues/10985)
### [v4.0.0-beta.1](https://github.com/vant-ui/vant/compare/v3.6.0...v4.0.0-beta.1)
`2022-08-24`
**Breaking Changes**
- Popup: improve style when position is center [#10965](https://github.com/vant-ui/vant/issues/10965)
```less
// Vant 3
.van-popup--center {
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
// Vant 4
.van-popup--center {
left: 0;
right: 0;
width: fit-content;
max-width: calc(100vw - var(--van-padding-md) * 2);
margin: 0 auto;
transform: translateY(-50%);
}
```
**New Component**
- Add new component [Space](#/en-US/space), contributed by [@LadyChatterleyLover](https://github.com/LadyChatterleyLover) [#10857](https://github.com/vant-ui/vant/issues/10857)
**Feature**
- ConfigProvider: add z-index prop [#10915](https://github.com/vant-ui/vant/issues/10915)
- Form: add validateEmpty option of rule [#10913](https://github.com/vant-ui/vant/issues/10913)
- Popup: add role and tabindex for a11y [#10894](https://github.com/vant-ui/vant/issues/10894)
- TouchEmulator: support .mjs extension [#10888](https://github.com/vant-ui/vant/issues/10888)
**Feature**
- ConfigProvider: add theme-vars-dark and theme-vars-light props [#10939](https://github.com/vant-ui/vant/issues/10939)
- Picker: add clickOption event [#10865](https://github.com/vant-ui/vant/issues/10865)
- add correct passive flag to improve scroll performance [#10951](https://github.com/vant-ui/vant/issues/10951)
- @vant/use: improve useEventListener typing [#10952](https://github.com/vant-ui/vant/issues/10952)
**Bug Fixes**
- ConfigProvider: should remove theme class on unmount [#10898](https://github.com/vant-ui/vant/issues/10898)
- reduce passive event warning of touchstart event [#10954](https://github.com/vant-ui/vant/issues/10954)
- Tabs: resize not work for swipeable tabs [#10964](https://github.com/vant-ui/vant/issues/10964)
- Fix incorrect tag name in WebStorm [#10946](https://github.com/vant-ui/vant/issues/10946)
- Badge: should hide string zero when using show-zero prop [#10921](https://github.com/vant-ui/vant/issues/10921)
- Calendar: content disappeared when hiding [#10910](https://github.com/vant-ui/vant/issues/10910)
- Calendar: reading getFullYear error in some cases [#10909](https://github.com/vant-ui/vant/issues/10909)
- Empty: generate unique id to avoid render issue [#10943](https://github.com/vant-ui/vant/issues/10943)
- Popover: can not scroll inside popup [#10949](https://github.com/vant-ui/vant/issues/10949)
- PullRefresh: fix passive event warning [#10938](https://github.com/vant-ui/vant/issues/10938)
- Search: --van-search-input-height var not work [#10911](https://github.com/vant-ui/vant/issues/10911)
### [v4.0.0-beta.0](https://github.com/vant-ui/vant/compare/v3.5.2...v4.0.0-beta.0)
`2022-07-16`

View File

@ -19,6 +19,78 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
## 更新内容
### [v4.0.0-rc.0](https://github.com/vant-ui/vant/compare/v3.6.2...v4.0.0-rc.0)
`2022-09-04`
**Feature**
- 新增 [PickerGroup 选择器组](#/zh-CN/picker-group) 组件
**Bug Fixes**
- DatePicker: 修复未正确更新 modelValue 的问题 [#10984](https://github.com/vant-ui/vant/issues/10984)
- DatePicker: 修复 min-date 属性未正确生效的问题 [#10985](https://github.com/vant-ui/vant/issues/10985)
### [v4.0.0-beta.1](https://github.com/vant-ui/vant/compare/v3.6.0...v4.0.0-beta.1)
`2022-08-24`
**Breaking Changes**
- Popup: 默认添加了 `box-sizing: border-box` 样式。
- Popup: 调整了 `position="center"` 时的水平居中方式,以解决弹窗宽度无法正确自适应的问题。
```less
// Vant 3
.van-popup--center {
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
// Vant 4
.van-popup--center {
left: 0;
right: 0;
width: fit-content;
max-width: calc(100vw - var(--van-padding-md) * 2);
margin: 0 auto;
transform: translateY(-50%);
}
```
**New Component**
- 新增 [Space 间距](#/zh-CN/space) 组件, 由 [@LadyChatterleyLover](https://github.com/LadyChatterleyLover) 贡献 [#10857](https://github.com/vant-ui/vant/issues/10857)
**Feature**
- ConfigProvider: 新增 z-index 属性,用于设置弹窗组件的 z-index [#10915](https://github.com/vant-ui/vant/issues/10915)
- Form: 新增 rule 的 validateEmpty 选项 [#10913](https://github.com/vant-ui/vant/issues/10913)
- Popup: 新增 role 和 tabindex优化无障碍访问 [#10894](https://github.com/vant-ui/vant/issues/10894)
- TouchEmulator: 支持 .mjs 后缀 [#10888](https://github.com/vant-ui/vant/issues/10888)
**Feature**
- ConfigProvider: 新增 theme-vars-dark 和 theme-vars-light 属性 [#10939](https://github.com/vant-ui/vant/issues/10939)
- Picker: 新增 clickOption 事件 [#10865](https://github.com/vant-ui/vant/issues/10865)
- 为 scroll 事件添加了正确的 passive 标记来提升滚动性能 [#10951](https://github.com/vant-ui/vant/issues/10951)
- @vant/use: 优化 useEventListener 类型定义 [#10952](https://github.com/vant-ui/vant/issues/10952)
**Bug Fixes**
- ConfigProvider: 修复销毁时没有回收全局样式类的问题 [#10898](https://github.com/vant-ui/vant/issues/10898)
- 修复 touchstart 导致控制台出现 passive event warning 的问题 [#10954](https://github.com/vant-ui/vant/issues/10954)
- Tabs: 修复开启 swipeable 时resize 方法无法正确生效的问题 [#10964](https://github.com/vant-ui/vant/issues/10964)
- 修复在 WebStorm 下标签无法自动补全的问题 [#10946](https://github.com/vant-ui/vant/issues/10946)
- Badge: 修复使用 show-zero 时字符串 `'0'` 不生效的问题 [#10921](https://github.com/vant-ui/vant/issues/10921)
- Calendar: 修复关闭弹窗过程中内容白屏的问题 [#10910](https://github.com/vant-ui/vant/issues/10910)
- Calendar: 修复控制台出现读取 getFullYear 异常的问题 [#10909](https://github.com/vant-ui/vant/issues/10909)
- Empty: 修复在 Tab 下嵌套使用时渲染异常的问题 [#10943](https://github.com/vant-ui/vant/issues/10943)
- Popover: 修复在 Popup 下嵌套使用时无法滚动的问题 [#10949](https://github.com/vant-ui/vant/issues/10949)
- PullRefresh: 修复 Chrome 控制台出现 passive event warning 的问题 [#10938](https://github.com/vant-ui/vant/issues/10938)
- Search: 修复 --van-search-input-height 样式变量不生效的问题 [#10911](https://github.com/vant-ui/vant/issues/10911)
### [v4.0.0-beta.0](https://github.com/vant-ui/vant/compare/v3.5.2...v4.0.0-beta.0)
`2022-07-16`

View File

@ -4,7 +4,7 @@
感谢你使用 Vant。
以下是关于向 Vant 提交反馈或代码的指南。在向 Vant 提交 issue 或者 PR 之前,请先花几分钟时间阅读以下文字
以下是关于向 Vant 提交反馈或代码的指南。在向 Vant 提交 issue 或者 PR 之前,请先花几分钟时间阅读以下内容
### Issue 规范
@ -15,7 +15,7 @@
### 本地开发
在进行本地开发前,请先确保你的开发环境中安装了 [Node.js >= 14](https://nodejs.org) 和 [pnpm](https://pnpm.io).
在进行本地开发前,请先确保你的开发环境中安装了 [Node.js >= 14.19.0](https://nodejs.org)。
按照下面的步骤操作,即可在本地开发 Vant 组件。
@ -23,6 +23,12 @@
# 克隆仓库
git clone git@github.com:vant-ui/vant.git
# 启用 pnpm 包管理器
corepack enable
# 如果无法使用 corepack你也可以手动安装 pnpm
npm install -g pnpm@7
# 安装依赖
pnpm i
@ -32,9 +38,9 @@ pnpm dev
仓库的不同分支对应不同的 Vant 版本,请切换到对应分支进行开发:
- dev 分支对应 Vant 4 版本,适用于 Vue 3
- 3.x 分支对应 Vant 3 版本 ,适用于 Vue 3
- 2.x 分支对应 Vant 2 版本,适用于 Vue 2
- dev 分支对应 Vant 3 版本 ,适用于 Vue 3
- next 分支对应 Vant 4 版本,适用于 Vue 3
### 镜像仓库

View File

@ -8,7 +8,7 @@
### 移除 babel-plugin-import
Vant 4 不再支持 `babel-plugin-import`,请移除项目中依赖的 `babel-plugin-import` 插件。
Vant 4.0 版本开始,将不再支持 `babel-plugin-import`,请移除项目中依赖的 `babel-plugin-import` 插件。
只需要删除 `babel.config.js` 中的以下代码即可:
@ -28,8 +28,8 @@ module.exports = {
移除 `babel-plugin-import` 有以下收益:
- 可以不再依赖 babel从而使用 esbuild、swc 等更高效的编译工具,提升项目编译效率。
- 不再受到 `babel-plugin-import` 的 import 写法限制,可以从 vant 中导入组件以外的内容,比如 Vant 4 中新增的 `showToast` 等方法:
- 不再强依赖 babel项目可以使用 esbuild、swc 等更高效的编译工具,大幅度提升编译效率。
- 不再受到 `babel-plugin-import` 的 import 写法限制,可以从 vant 中导入除了组件以外的其他内容,比如 Vant 4 中新增的 `showToast` 等方法:
```ts
import { showToast, showDialog } from 'vant';
@ -83,20 +83,23 @@ import 'vant/lib/index.css';
DatetimePicker 组件被拆分为:
- TimePicker: 用于时间选择。
- DatePicker: 用于日期选择。
- [TimePicker](#/zh-CN/time-picker): 用于时间选择。
- [DatePicker](#/zh-CN/date-picker): 用于日期选择。
- [PickerGroup](#/zh-CN/picker-group): 用于用于结合多个 Picker 选择器组件。
同时,这两个组件也基于新版 Picker 组件进行重构,并优化了部分 API 设计。
同时,TimePicker 和 DatePicker 组件也基于新版 Picker 组件进行重构,并优化了部分 API 设计。
#### 主要变更
以下是 TimePicker 和 DatePicker 的主要 API 变化,更多细节请参考 [TimePicker](#/zh-CN/time-picker) 和 [DatePicker](#/zh-CN/date-picker) 文档。
- `v-model` 绑定的值调整为数组格式
- 新增 `columns-type` 属性,用于控制选项类型和顺序
- 移除 `type` 属性和 `columns-order` 属性
- 移除 `getPicker` 方法
- 调整 `confirm``cancel``change` 事件的参数,与 Picker 组件保持一致
> 详细用法请参见 [TimePicker 组件](#/zh-CN/time-picker) 和 [DatePicker 组件](#/zh-CN/date-picker) 文档。
> Vant 4 不再提供旧版的 DatetimePicker 组件,使用 PickerGroup 组件可以实现更灵活、更丰富的交互效果,具体用法请参考 [PickerGroup](#/zh-CN/picker-group) 组件文档。
### Area 组件重构

View File

@ -212,3 +212,24 @@ import 'vant/es/image-preview/style';
```
> Tip: "Full Import" and "On-demand Import" should not be used at the same time, otherwise it will lead to problems such as code duplication and style overrides.
## With Frameworks
### Use Vant in Nuxt 3
When using Vant in Nuxt 3, you should add `/vant/` to the `build.transpile`:
```ts
import { defineNuxtConfig } from 'nuxt';
export default defineNuxtConfig({
experimental: {
externalVue: true,
},
});
```
Reference:
- [nuxt/framework#6761](https://github.com/nuxt/framework/issues/6761)
- [nuxt/framework#4084](https://github.com/nuxt/framework/issues/4084)

View File

@ -93,9 +93,9 @@ pnpm add vant
## 引入组件
### 方法一. 基础用法
### 方法一. 常规用法
下面是使用 Vant 组件的基础用法示例:
下面是使用 Vant 组件的用法示例:
```js
import { createApp } from 'vue';
@ -110,15 +110,15 @@ const app = createApp();
app.use(Button);
```
Vant 支持多种组件注册方式,除了在 app 上全局注册组件,你也可以选择其他的方式,详见 [组件注册](#/zh-CN/advanced-usage#zu-jian-zhu-ce) 章节。
Vant 支持多种组件注册方式,除了在 app 上全局注册组件,你也可以选择其他的方式,比如局部注册,详见 [组件注册](#/zh-CN/advanced-usage#zu-jian-zhu-ce) 章节。
> 提示Vant 默认支持 Tree Shaking因此你不需要配置任何插件通过 Tree Shaking 即可移除不需要的 JS 代码,但 CSS 样式无法通过这种方式优化,如果需要按需引入 CSS 样式,请参考下面的方法二。
### 方法二. 按需引入组件
### 方法二. 按需引入组件样式
在基于 `vite``webpack``vue-cli` 的项目中使用 Vant 时,可以使用 [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components) 插件,它可以自动引入组件,并按需引入组件的样式。
相比于基础用法,这种方式可以按需引入组件的 CSS 样式,从而减少一部分代码体积。
相比于常规用法,这种方式可以按需引入组件的 CSS 样式,从而减少一部分代码体积,但使用起来会变得繁琐一些。如果业务对 CSS 的体积要求不是特别极致,我们推荐使用更简便的常规用法
#### 1. 安装插件
@ -216,4 +216,58 @@ import { showImagePreview } from 'vant';
import 'vant/es/image-preview/style';
```
你可以在项目的入口文件或公共模块中引入以上组件的样式,这样在业务代码中使用组件时,便不再需要重复引入样式了。
> 提示:在单个项目中不应该同时使用「全量引入」和「按需引入」,否则会导致代码重复、样式错乱等问题。
## 在框架中使用
### 在 Nuxt 3 中使用
在 Nuxt 3 中使用 Vant 时,由于 Nuxt 3 框架本身的限制,需要在 `nuxt.config.ts` 中添加以下配置:
```ts
import { defineNuxtConfig } from 'nuxt';
export default defineNuxtConfig({
experimental: {
externalVue: true,
},
});
```
关于该问题的背景,可以参考以下 issue
- [nuxt/framework#6761](https://github.com/nuxt/framework/issues/6761)
- [nuxt/framework#4084](https://github.com/nuxt/framework/issues/4084)
## 迁移提示
### 移除 babel-plugin-import
从 Vant 4.0 版本开始,将不再支持 `babel-plugin-import`,请移除项目中依赖的 `babel-plugin-import` 插件。
只需要删除 `babel.config.js` 中的以下代码即可:
```diff
module.exports = {
plugins: [
- ['import', {
- libraryName: 'vant',
- libraryDirectory: 'es',
- style: true
- }, 'vant']
]
};
```
#### 收益
移除 `babel-plugin-import` 有以下收益:
- 不再强依赖 babel项目可以使用 esbuild、swc 等更高效的编译工具,大幅度提升编译效率。
- 不再受到 `babel-plugin-import` 的 import 写法限制,可以从 vant 中导入除了组件以外的其他内容,比如 Vant 4 中新增的 `showToast` 等方法:
```ts
import { showToast, showDialog } from 'vant';
```

View File

@ -1,6 +1,6 @@
{
"name": "vant",
"version": "4.0.0-beta.1",
"version": "4.0.0-rc.0",
"description": "Mobile UI Components built on Vue",
"main": "lib/vant.cjs.js",
"module": "es/index.mjs",
@ -55,21 +55,21 @@
"vue": "^3.0.0"
},
"devDependencies": {
"@types/node": "^16",
"@types/node": "^16.11.56",
"@types/jest": "^27.0.0",
"@vant/area-data": "workspace:*",
"@vant/cli": "workspace:*",
"@vant/eslint-config": "workspace:*",
"@vue/runtime-core": "^3.2.27",
"@vue/test-utils": "^2.0.1",
"typescript": "^4.7.4",
"vue": "^3.2.27",
"vue-router": "^4.0.12"
"@vue/runtime-core": "^3.2.38",
"@vue/test-utils": "^2.0.2",
"typescript": "^4.8.2",
"vue": "^3.2.38",
"vue-router": "^4.1.5"
},
"sideEffects": [
"es/**/style/*",
"lib/**/style/*",
"*.css",
"*.less"
"*.css"
],
"web-types": "lib/web-types.json"
}

View File

@ -17,7 +17,7 @@ import { Button, ButtonType } from '../button';
const [name, bem] = createNamespace('action-bar-button');
const actionBarButtonProps = extend({}, routeProps, {
export const actionBarButtonProps = extend({}, routeProps, {
type: String as PropType<ButtonType>,
text: String,
icon: String,

View File

@ -3,6 +3,7 @@ import _ActionBarButton from './ActionBarButton';
export const ActionBarButton = withInstall(_ActionBarButton);
export default ActionBarButton;
export { actionBarButtonProps } from './ActionBarButton';
export type { ActionBarButtonProps } from './ActionBarButton';
declare module 'vue' {

View File

@ -12,7 +12,7 @@ import { Badge, type BadgeProps } from '../badge';
const [name, bem] = createNamespace('action-bar-icon');
const actionBarIconProps = extend({}, routeProps, {
export const actionBarIconProps = extend({}, routeProps, {
dot: Boolean,
text: String,
icon: String,

View File

@ -3,6 +3,7 @@ import _ActionBarIcon from './ActionBarIcon';
export const ActionBarIcon = withInstall(_ActionBarIcon);
export default ActionBarIcon;
export { actionBarIconProps } from './ActionBarIcon';
export type { ActionBarIconProps } from './ActionBarIcon';
declare module 'vue' {

View File

@ -7,7 +7,7 @@ const [name, bem] = createNamespace('action-bar');
export const ACTION_BAR_KEY = Symbol(name);
const actionBarProps = {
export const actionBarProps = {
placeholder: Boolean,
safeAreaInsetBottom: truthProp,
};

View File

@ -3,6 +3,7 @@ import _ActionBar from './ActionBar';
export const ActionBar = withInstall(_ActionBar);
export default ActionBar;
export { actionBarProps } from './ActionBar';
export type { ActionBarProps } from './ActionBar';
declare module 'vue' {

View File

@ -29,7 +29,7 @@ export type ActionSheetAction = {
className?: unknown;
};
const actionSheetProps = extend({}, popupSharedProps, {
export const actionSheetProps = extend({}, popupSharedProps, {
title: String,
round: truthProp,
actions: makeArrayProp<ActionSheetAction>(),

View File

@ -3,6 +3,7 @@ import _ActionSheet from './ActionSheet';
export const ActionSheet = withInstall(_ActionSheet);
export default ActionSheet;
export { actionSheetProps } from './ActionSheet';
export type { ActionSheetProps, ActionSheetAction } from './ActionSheet';
declare module 'vue' {

View File

@ -54,7 +54,7 @@ const DEFAULT_DATA: AddressEditInfo = {
addressDetail: '',
};
const addressEditProps = {
export const addressEditProps = {
areaList: Object as PropType<AreaList>,
isSaving: Boolean,
isDeleting: Boolean,

View File

@ -3,6 +3,7 @@ import _AddressEdit, { AddressEditProps } from './AddressEdit';
export const AddressEdit = withInstall(_AddressEdit);
export default AddressEdit;
export { addressEditProps } from './AddressEdit';
export type { AddressEditProps };
export type {
AddressEditInfo,

View File

@ -15,7 +15,7 @@ import AddressListItem, { AddressListAddress } from './AddressListItem';
const [name, bem, t] = createNamespace('address-list');
const addressListProps = {
export const addressListProps = {
list: makeArrayProp<AddressListAddress>(),
modelValue: numericProp,
switchable: truthProp,

View File

@ -3,6 +3,7 @@ import _AddressList from './AddressList';
export const AddressList = withInstall(_AddressList);
export default AddressList;
export { addressListProps } from './AddressList';
export type { AddressListProps } from './AddressList';
export type { AddressListAddress } from './AddressListItem';

View File

@ -30,7 +30,7 @@ import type { PickerExpose } from '../picker/types';
const [name, bem] = createNamespace('area');
const areaProps = extend({}, pickerSharedProps, {
export const areaProps = extend({}, pickerSharedProps, {
modelValue: String,
columnsNum: makeNumericProp(3),
columnsPlaceholder: makeArrayProp<string>(),

View File

@ -3,6 +3,7 @@ import _Area from './Area';
export const Area = withInstall(_Area);
export default Area;
export { areaProps } from './Area';
export type { AreaProps } from './Area';
export type { AreaList, AreaInstance } from './types';

View File

@ -24,7 +24,7 @@ export type BadgePosition =
| 'bottom-left'
| 'bottom-right';
const badgeProps = {
export const badgeProps = {
dot: Boolean,
max: numericProp,
tag: makeStringProp<keyof HTMLElementTagNameMap>('div'),

View File

@ -3,6 +3,7 @@ import _Badge from './Badge';
export const Badge = withInstall(_Badge);
export default Badge;
export { badgeProps } from './Badge';
export type { BadgeProps, BadgePosition } from './Badge';
declare module 'vue' {

View File

@ -30,7 +30,7 @@ import {
const [name, bem] = createNamespace('button');
const buttonProps = extend({}, routeProps, {
export const buttonProps = extend({}, routeProps, {
tag: makeStringProp<keyof HTMLElementTagNameMap>('button'),
text: String,
icon: String,

View File

@ -3,6 +3,7 @@ import _Button from './Button';
export const Button = withInstall(_Button);
export default Button;
export { buttonProps } from './Button';
export type { ButtonProps } from './Button';
export type {
ButtonType,

View File

@ -53,7 +53,7 @@ import type {
CalendarMonthInstance,
} from './types';
const calendarProps = {
export const calendarProps = {
show: Boolean,
type: makeStringProp<CalendarType>('single'),
title: String,
@ -134,7 +134,7 @@ export default defineComponent({
};
const getInitialDate = (defaultDate = props.defaultDate) => {
const { type, minDate, maxDate } = props;
const { type, minDate, maxDate, allowSameDay } = props;
if (defaultDate === null) {
return defaultDate;
@ -149,9 +149,12 @@ export default defineComponent({
const start = limitDateRange(
defaultDate[0] || now,
minDate,
getPrevDay(maxDate)
allowSameDay ? maxDate : getPrevDay(maxDate)
);
const end = limitDateRange(
defaultDate[1] || now,
allowSameDay ? minDate : getNextDay(minDate)
);
const end = limitDateRange(defaultDate[1] || now, getNextDay(minDate));
return [start, end];
}

View File

@ -3,6 +3,7 @@ import _Calendar from './Calendar';
export const Calendar = withInstall(_Calendar);
export default Calendar;
export { calendarProps } from './Calendar';
export type { CalendarProps } from './Calendar';
export type {
CalendarType,

View File

@ -270,3 +270,41 @@ test('should emit overRange when exceeded max range', async () => {
expect(onOverRange).toHaveBeenCalledTimes(1);
});
test('should allow default date to be minDate when using allowSameDay prop', () => {
const minDate = new Date(1800, 0, 1);
const maxDate = new Date(1800, 0, 29);
const wrapper = mount(Calendar, {
props: {
type: 'range',
poppable: false,
minDate,
maxDate,
defaultDate: [minDate, minDate],
lazyRender: false,
allowSameDay: true,
},
});
wrapper.find('.van-calendar__confirm').trigger('click');
expect(wrapper.emitted<[Date]>('confirm')![0][0]).toEqual([minDate, minDate]);
});
test('should allow default date to be maxDate when using allowSameDay prop', () => {
const minDate = new Date(1800, 0, 1);
const maxDate = new Date(1800, 0, 29);
const wrapper = mount(Calendar, {
props: {
type: 'range',
poppable: false,
minDate,
maxDate,
defaultDate: [maxDate, maxDate],
lazyRender: false,
allowSameDay: true,
},
});
wrapper.find('.van-calendar__confirm').trigger('click');
expect(wrapper.emitted<[Date]>('confirm')![0][0]).toEqual([maxDate, maxDate]);
});

View File

@ -9,7 +9,7 @@ import { Image } from '../image';
const [name, bem] = createNamespace('card');
const cardProps = {
export const cardProps = {
tag: String,
num: numericProp,
desc: String,

View File

@ -3,6 +3,7 @@ import _Card from './Card';
export const Card = withInstall(_Card);
export default Card;
export { cardProps } from './Card';
export type { CardProps } from './Card';
declare module 'vue' {

View File

@ -28,7 +28,7 @@ import type { CascaderTab, CascaderOption, CascaderFieldNames } from './types';
const [name, bem, t] = createNamespace('cascader');
const cascaderProps = {
export const cascaderProps = {
title: String,
options: makeArrayProp<CascaderOption>(),
closeable: truthProp,

View File

@ -3,6 +3,7 @@ import _Cascader from './Cascader';
export const Cascader = withInstall(_Cascader);
export default Cascader;
export { cascaderProps } from './Cascader';
export type { CascaderProps } from './Cascader';
export type { CascaderOption, CascaderFieldNames } from './types';

View File

@ -3,7 +3,7 @@ import { truthProp, createNamespace, BORDER_TOP_BOTTOM } from '../utils';
const [name, bem] = createNamespace('cell-group');
const cellGroupProps = {
export const cellGroupProps = {
title: String,
inset: Boolean,
border: truthProp,

View File

@ -3,6 +3,7 @@ import _CellGroup from './CellGroup';
export const CellGroup = withInstall(_CellGroup);
export default CellGroup;
export { cellGroupProps } from './CellGroup';
export type { CellGroupProps } from './CellGroup';
declare module 'vue' {

View File

@ -49,7 +49,7 @@ export const cellSharedProps = {
},
};
const cellProps = extend({}, cellSharedProps, routeProps);
export const cellProps = extend({}, cellSharedProps, routeProps);
export type CellProps = ExtractPropTypes<typeof cellProps>;

View File

@ -3,6 +3,7 @@ import _Cell from './Cell';
export const Cell = withInstall(_Cell);
export default Cell;
export { cellProps } from './Cell';
export type { CellSize, CellProps, CellArrowDirection } from './Cell';
declare module 'vue' {

View File

@ -23,7 +23,7 @@ import type {
const [name, bem] = createNamespace('checkbox-group');
const checkboxGroupProps = {
export const checkboxGroupProps = {
max: numericProp,
disabled: Boolean,
iconSize: numericProp,

View File

@ -3,6 +3,7 @@ import _CheckboxGroup from './CheckboxGroup';
export const CheckboxGroup = withInstall(_CheckboxGroup);
export default CheckboxGroup;
export { checkboxGroupProps } from './CheckboxGroup';
export type { CheckboxGroupProps } from './CheckboxGroup';
export type {
CheckboxGroupInstance,

View File

@ -16,7 +16,7 @@ import type { CheckboxExpose } from './types';
const [name, bem] = createNamespace('checkbox');
const checkboxProps = extend({}, checkerProps, {
export const checkboxProps = extend({}, checkerProps, {
bindGroup: truthProp,
});

View File

@ -3,6 +3,7 @@ import _Checkbox from './Checkbox';
export const Checkbox = withInstall(_Checkbox);
export default Checkbox;
export { checkboxProps } from './Checkbox';
export type { CheckboxProps } from './Checkbox';
export type {
CheckboxShape,

View File

@ -34,7 +34,7 @@ function getPath(clockwise: boolean, viewBoxSize: number) {
export type CircleStartPosition = 'top' | 'right' | 'bottom' | 'left';
const circleProps = {
export const circleProps = {
text: String,
size: numericProp,
fill: makeStringProp('none'),

View File

@ -3,6 +3,7 @@ import _Circle from './Circle';
export const Circle = withInstall(_Circle);
export default Circle;
export { circleProps } from './Circle';
export type { CircleProps, CircleStartPosition } from './Circle';
declare module 'vue' {

View File

@ -10,7 +10,7 @@ import { ROW_KEY } from '../row/Row';
const [name, bem] = createNamespace('col');
const colProps = {
export const colProps = {
tag: makeStringProp<keyof HTMLElementTagNameMap>('div'),
span: makeNumericProp(0),
offset: numericProp,

View File

@ -3,6 +3,7 @@ import _Col from './Col';
export const Col = withInstall(_Col);
export default Col;
export { colProps } from './Col';
export type { ColProps } from './Col';
declare module 'vue' {

View File

@ -30,7 +30,7 @@ const [name, bem] = createNamespace('collapse-item');
const CELL_SLOTS = ['icon', 'title', 'value', 'label', 'right-icon'] as const;
const collapseItemProps = extend({}, cellSharedProps, {
export const collapseItemProps = extend({}, cellSharedProps, {
name: numericProp,
isLink: truthProp,
disabled: Boolean,

View File

@ -3,6 +3,7 @@ import _CollapseItem from './CollapseItem';
export const CollapseItem = withInstall(_CollapseItem);
export default CollapseItem;
export { collapseItemProps } from './CollapseItem';
export type { CollapseItemProps } from './CollapseItem';
export type { CollapseItemInstance } from './types';

View File

@ -30,7 +30,7 @@ export type CollapseToggleAllOptions =
export const COLLAPSE_KEY: InjectionKey<CollapseProvide> = Symbol(name);
const collapseProps = {
export const collapseProps = {
border: truthProp,
accordion: Boolean,
modelValue: {

View File

@ -3,6 +3,7 @@ import _Collapse from './Collapse';
export const Collapse = withInstall(_Collapse);
export default Collapse;
export { collapseProps } from './Collapse';
export type {
CollapseProps,
CollapseInstance,

View File

@ -35,7 +35,7 @@ export const CONFIG_PROVIDER_KEY: InjectionKey<ConfigProviderProvide> =
export type ThemeVars = PropType<Record<string, Numeric>>;
const configProviderProps = {
export const configProviderProps = {
tag: makeStringProp<keyof HTMLElementTagNameMap>('div'),
theme: makeStringProp<ConfigProviderTheme>('light'),
zIndex: Number,

View File

@ -3,6 +3,7 @@ import _ConfigProvider from './ConfigProvider';
export const ConfigProvider = withInstall(_ConfigProvider);
export default ConfigProvider;
export { configProviderProps } from './ConfigProvider';
export type {
ConfigProviderProps,
ConfigProviderTheme,

View File

@ -6,7 +6,7 @@ const [name, bem, t] = createNamespace('contact-card');
export type ContactCardType = 'add' | 'edit';
const contactCardProps = {
export const contactCardProps = {
tel: String,
name: String,
type: makeStringProp<ContactCardType>('add'),

View File

@ -3,6 +3,7 @@ import _ContactCard from './ContactCard';
export const ContactCard = withInstall(_ContactCard);
export default ContactCard;
export { contactCardProps } from './ContactCard';
export type { ContactCardType, ContactCardProps } from './ContactCard';
declare module 'vue' {

View File

@ -29,7 +29,7 @@ const DEFAULT_CONTACT: ContactEditInfo = {
name: '',
};
const contactEditProps = {
export const contactEditProps = {
isEdit: Boolean,
isSaving: Boolean,
isDeleting: Boolean,

View File

@ -3,6 +3,7 @@ import _ContactEdit from './ContactEdit';
export const ContactEdit = withInstall(_ContactEdit);
export default ContactEdit;
export { contactEditProps } from './ContactEdit';
export type { ContactEditInfo, ContactEditProps } from './ContactEdit';
declare module 'vue' {

View File

@ -20,7 +20,7 @@ export type ContactListItem = {
isDefault?: boolean;
};
const contactListProps = {
export const contactListProps = {
list: Array as PropType<ContactListItem[]>,
addText: String,
modelValue: unknownProp,

View File

@ -3,6 +3,7 @@ import _ContactList from './ContactList';
export const ContactList = withInstall(_ContactList);
export default ContactList;
export { contactListProps } from './ContactList';
export type { ContactListItem, ContactListProps } from './ContactList';
declare module 'vue' {

View File

@ -15,7 +15,7 @@ import { useExpose } from '../composables/use-expose';
const [name, bem] = createNamespace('count-down');
const countDownProps = {
export const countDownProps = {
time: makeNumericProp(0),
format: makeStringProp('HH:mm:ss'),
autoStart: truthProp,

View File

@ -3,6 +3,7 @@ import _CountDown from './CountDown';
export const CountDown = withInstall(_CountDown);
export default CountDown;
export { countDownProps } from './CountDown';
export type { CountDownProps } from './CountDown';
export type { CountDownInstance, CountDownCurrentTime } from './types';

View File

@ -18,7 +18,7 @@ import type { CouponInfo } from '../coupon';
const [name, bem, t] = createNamespace('coupon-cell');
const couponCellProps = {
export const couponCellProps = {
title: String,
border: truthProp,
editable: truthProp,

View File

@ -3,6 +3,7 @@ import _CouponCell from './CouponCell';
export const CouponCell = withInstall(_CouponCell);
export default CouponCell;
export { couponCellProps } from './CouponCell';
export type { CouponCellProps } from './CouponCell';
declare module 'vue' {

View File

@ -31,7 +31,7 @@ import { Coupon, CouponInfo } from '../coupon';
import { useRect } from '@vant/use';
const [name, bem, t] = createNamespace('coupon-list');
const couponListProps = {
export const couponListProps = {
code: makeStringProp(''),
coupons: makeArrayProp<CouponInfo>(),
currency: makeStringProp('¥'),

View File

@ -3,6 +3,7 @@ import _CouponList from './CouponList';
export const CouponList = withInstall(_CouponList);
export default CouponList;
export { couponListProps } from './CouponList';
export type { CouponListProps } from './CouponList';
declare module 'vue' {

View File

@ -24,7 +24,7 @@ const [name] = createNamespace('date-picker');
export type DatePickerColumnType = 'year' | 'month' | 'day';
const datePickerProps = extend({}, sharedProps, {
export const datePickerProps = extend({}, sharedProps, {
columnsType: {
type: Array as PropType<DatePickerColumnType[]>,
default: () => ['year', 'month', 'day'],
@ -65,7 +65,10 @@ export default defineComponent({
);
};
const isMinYear = (year: number) => year === props.minDate.getFullYear();
const isMaxYear = (year: number) => year === props.maxDate.getFullYear();
const isMinMonth = (month: number) =>
month === props.minDate.getMonth() + 1;
const isMaxMonth = (month: number) =>
month === props.maxDate.getMonth() + 1;
@ -88,28 +91,30 @@ export default defineComponent({
};
const genMonthOptions = () => {
if (isMaxYear(getValue('year'))) {
return genOptions(
1,
props.maxDate.getMonth() + 1,
'month',
props.formatter,
props.filter
);
}
return genOptions(1, 12, 'month', props.formatter, props.filter);
const year = getValue('year');
const minMonth = isMinYear(year) ? props.minDate.getMonth() + 1 : 1;
const maxMonth = isMaxYear(year) ? props.maxDate.getMonth() + 1 : 12;
return genOptions(
minMonth,
maxMonth,
'month',
props.formatter,
props.filter
);
};
const genDayOptions = () => {
const year = getValue('year');
const month = getValue('month');
const minDate =
isMinYear(year) && isMinMonth(month) ? props.minDate.getDate() : 1;
const maxDate =
isMaxYear(year) && isMaxMonth(month)
? props.maxDate.getDate()
: getMonthEndDay(year, month);
let maxDate = getMonthEndDay(year, month);
if (isMaxYear(year) && isMaxMonth(month)) {
maxDate = props.maxDate.getDate();
}
return genOptions(1, maxDate, 'day', props.formatter, props.filter);
return genOptions(minDate, maxDate, 'day', props.formatter, props.filter);
};
const columns = computed(() =>
@ -130,7 +135,7 @@ export default defineComponent({
);
watch(currentValues, (newValues) => {
if (isSameValue(newValues, props.modelValue)) {
if (!isSameValue(newValues, props.modelValue)) {
emit('update:modelValue', newValues);
}
});

View File

@ -21,7 +21,12 @@ app.use(DatePicker);
### Basic Usage
```html
<van-date-picker v-model="currentDate" title="Choose Date" />
<van-date-picker
v-model="currentDate"
title="Choose Date"
:min-date="minDate"
:max-date="maxDate"
/>
```
```js
@ -191,7 +196,7 @@ export default {
| Name | Description | SlotProps |
| -------------- | ---------------------------- | ---------------------- |
| default | Custom toolbar content | - |
| toolbar | Custom toolbar content | - |
| title | Custom title | - |
| confirm | Custom confirm button text | - |
| cancel | Custom cancel button text | - |

View File

@ -23,7 +23,12 @@ app.use(DatePicker);
通过 `v-model` 绑定当前选中的日期,通过 `min-date``max-date` 属性来设定可选的时间范围。
```html
<van-date-picker v-model="currentDate" title="选择日期" />
<van-date-picker
v-model="currentDate"
title="选择日期"
:min-date="minDate"
:max-date="maxDate"
/>
```
```js
@ -197,7 +202,7 @@ export default {
| 名称 | 说明 | 参数 |
| -------------- | ---------------------- | ---------------------- |
| default | 自定义整个顶部栏的内容 | - |
| toolbar | 自定义整个顶部栏的内容 | - |
| title | 自定义标题内容 | - |
| confirm | 自定义确认按钮内容 | - |
| cancel | 自定义取消按钮内容 | - |

View File

@ -3,6 +3,7 @@ import _DatePicker, { DatePickerProps } from './DatePicker';
export const DatePicker = withInstall(_DatePicker);
export default DatePicker;
export { datePickerProps } from './DatePicker';
export type { DatePickerProps };
export type { DatePickerColumnType } from './DatePicker';

View File

@ -42,7 +42,7 @@ import type {
const [name, bem, t] = createNamespace('dialog');
const dialogProps = extend({}, popupSharedProps, {
export const dialogProps = extend({}, popupSharedProps, {
title: String,
theme: String as PropType<DialogTheme>,
width: numericProp,

View File

@ -104,9 +104,9 @@ showConfirmDialog({
});
```
### Advanced Usage
### Use Dialog Component
If you need to render vue components within a dialog, you can use dialog component.
If you need to render Vue components within a Dialog, you can use the Dialog component.
```html
<van-dialog v-model:show="show" title="Title" show-cancel-button>
@ -129,6 +129,8 @@ export default {
### Methods
Vant exports following Dialog utility functions:
| Name | Description | Attribute | Return value |
| --- | --- | --- | --- |
| showDialog | Show dialog | _options: DialogOptions_ | `Promise<void>` |
@ -174,7 +176,7 @@ export default {
| title | Title | _string_ | - |
| width | Width | _number \| string_ | `320px` |
| message | Message | _string \| () => JSX.ELement_ | - |
| message-align | Message align, can be set to `left` `right` | _string_ | `center` |
| message-align | Message align, can be set to `left` `right` `justify` | _string_ | `center` |
| theme | Theme style, can be set to `round-button` | _string_ | `default` |
| show-confirm-button | Whether to show confirm button | _boolean_ | `true` |
| show-cancel-button | Whether to show cancel button | _boolean_ | `false` |

View File

@ -121,9 +121,9 @@ showConfirmDialog({
});
```
### 组件调用
### 使用 Dialog 组件
如果需要在弹窗内嵌入组件或其他自定义内容,可以使用组件调用的方式
如果需要在 Dialog 内嵌入组件或其他自定义内容,可以直接使用 Dialog 组件,并使用默认插槽进行定制。使用前需要通过 `app.use` 等方式注册组件
```html
<van-dialog v-model:show="show" title="标题" show-cancel-button>
@ -146,6 +146,8 @@ export default {
### 方法
Vant 中导出了以下 Dialog 相关的辅助函数:
| 方法名 | 说明 | 参数 | 返回值 |
| --- | --- | --- | --- |
| showDialog | 展示弹窗 | _options: DialogOptions_ | `Promise<void>` |
@ -156,7 +158,7 @@ export default {
### DialogOptions
通过函数调用 `Dialog` 时,支持传入以下选项:
调用 `showDialog` 等方法时,支持传入以下选项:
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
@ -195,7 +197,7 @@ export default {
| title | 标题 | _string_ | - |
| width | 弹窗宽度,默认单位为 `px` | _number \| string_ | `320px` |
| message | 文本内容,支持通过 `\n` 换行 | _string \| () => JSX.Element_ | - |
| message-align | 内容水平对齐方式,可选值为 `left` `right` | _string_ | `center` |
| message-align | 内容水平对齐方式,可选值为 `left` `right` `justify` | _string_ | `center` |
| theme | 样式风格,可选值为 `round-button` | _string_ | `default` |
| show-confirm-button | 是否展示确认按钮 | _boolean_ | `true` |
| show-cancel-button | 是否展示取消按钮 | _boolean_ | `false` |

View File

@ -17,7 +17,7 @@ const t = useTranslate({
'如果解决方法是丑陋的,那就肯定还有更好的解决方法,只是还没有发现而已。',
beforeClose: '异步关闭',
roundButton: '圆角按钮样式',
componentCall: '组件调用',
useComponent: '使用 Dialog 组件',
},
'en-US': {
title: 'Title',
@ -29,7 +29,7 @@ const t = useTranslate({
content3: 'Content',
beforeClose: 'Before Close',
roundButton: 'Round Button Style',
componentCall: 'Component Call',
useComponent: 'Use Dialog Component',
},
});
@ -101,8 +101,8 @@ const onClickBeforeClose = () => {
<van-cell is-link :title="t('beforeClose')" @click="onClickBeforeClose" />
</demo-block>
<demo-block card :title="t('componentCall')">
<van-cell is-link :title="t('componentCall')" @click="show = true" />
<demo-block card :title="t('useComponent')">
<van-cell is-link :title="t('useComponent')" @click="show = true" />
<van-dialog
v-model:show="show"
:title="t('title')"

View File

@ -82,6 +82,10 @@ body {
&--right {
text-align: right;
}
&--justify {
text-align: justify;
}
}
&__footer {

View File

@ -3,6 +3,7 @@ import _Dialog from './Dialog';
export const Dialog = withInstall(_Dialog);
export default Dialog;
export { dialogProps } from './Dialog';
export {
showDialog,
closeDialog,

View File

@ -86,7 +86,7 @@ exports[`should render demo and match snapshot 1`] = `
>
<div class="van-cell__title">
<span>
Component Call
Use Dialog Component
</span>
</div>
<i class="van-badge__wrapper van-icon van-icon-arrow van-cell__right-icon">

View File

@ -4,7 +4,7 @@ import type { Interceptor, Numeric } from '../utils';
export type DialogTheme = 'default' | 'round-button';
export type DialogAction = 'confirm' | 'cancel';
export type DialogMessage = string | (() => JSX.Element);
export type DialogMessageAlign = 'left' | 'center' | 'right';
export type DialogMessageAlign = 'left' | 'center' | 'right' | 'justify';
export type DialogOptions = {
title?: string;

View File

@ -5,7 +5,7 @@ const [name, bem] = createNamespace('divider');
export type DividerContentPosition = 'left' | 'center' | 'right';
const dividerProps = {
export const dividerProps = {
dashed: Boolean,
hairline: truthProp,
contentPosition: makeStringProp<DividerContentPosition>('center'),

View File

@ -3,6 +3,7 @@ import _Divider from './Divider';
export const Divider = withInstall(_Divider);
export default Divider;
export { dividerProps } from './Divider';
export type { DividerProps, DividerContentPosition } from './Divider';
declare module 'vue' {

View File

@ -32,7 +32,7 @@ import type { DropdownItemOption } from './types';
const [name, bem] = createNamespace('dropdown-item');
const dropdownItemProps = {
export const dropdownItemProps = {
title: String,
options: makeArrayProp<DropdownItemOption>(),
disabled: Boolean,

View File

@ -3,6 +3,7 @@ import _DropdownItem, { DropdownItemProps } from './DropdownItem';
export const DropdownItem = withInstall(_DropdownItem);
export default DropdownItem;
export { dropdownItemProps } from './DropdownItem';
export type { DropdownItemProps };
export type { DropdownItemInstance, DropdownItemOption } from './types';

View File

@ -35,7 +35,7 @@ import type { DropdownMenuProvide, DropdownMenuDirection } from './types';
const [name, bem] = createNamespace('dropdown-menu');
const dropdownMenuProps = {
export const dropdownMenuProps = {
overlay: truthProp,
zIndex: numericProp,
duration: makeNumericProp(0.2),

View File

@ -3,6 +3,7 @@ import _DropdownMenu, { DropdownMenuProps } from './DropdownMenu';
export const DropdownMenu = withInstall(_DropdownMenu);
export default DropdownMenu;
export { dropdownMenuProps } from './DropdownMenu';
export type { DropdownMenuProps };
export type { DropdownMenuDirection } from './types';

View File

@ -9,7 +9,7 @@ import {
const [name, bem] = createNamespace('empty');
const emptyProps = {
export const emptyProps = {
image: makeStringProp('default'),
imageSize: [Number, String, Array] as PropType<Numeric | [Numeric, Numeric]>,
description: String,

View File

@ -3,6 +3,7 @@ import _Empty from './Empty';
export const Empty = withInstall(_Empty);
export default Empty;
export { emptyProps } from './Empty';
export type { EmptyProps } from './Empty';
declare module 'vue' {

Some files were not shown because too many files have changed in this diff Show More