Compare commits

...

10 Commits

Author SHA1 Message Date
neverland
da75691371
docs(changelog): 4.0.0 (#11317) 2022-11-26 23:03:05 +08:00
chenjiahan
05968e953d release: 4.0.0 2022-11-26 22:55:46 +08:00
neverland
7858537434
docs: adjust v4 site deploy config (#11316) 2022-11-26 22:54:23 +08:00
neverland
13512ca25b
docs: add maintenance status table (#11315) 2022-11-26 22:50:02 +08:00
neverland
4105da6796
feat(BackTop): allow using css var to custom position (#11312) 2022-11-26 21:34:49 +08:00
neverland
1b876d85d1
feat(BackTop): allow dynamically set target prop (#11311) 2022-11-26 21:15:41 +08:00
neverland
41f35b2735
chore(BackTop): only print error msg in development (#11310) 2022-11-26 21:06:20 +08:00
neverland
a318807eb5
fix(BackTop): rename visibility-height prop to offset (#11309) 2022-11-26 21:01:59 +08:00
neverland
7042d1c06e
fix(Field): keep selection position after updating value (#11308) 2022-11-26 20:17:51 +08:00
neverland
d227429fdc
feat(List): add disabled prop (#11307) 2022-11-26 20:05:33 +08:00
18 changed files with 129 additions and 50 deletions

View File

@ -36,7 +36,7 @@ jobs:
with:
branch: gh-pages
folder: packages/vant/site-dist
target-folder: v4
clean: false
- name: Deploy for GitHub 🚀
uses: JamesIves/github-pages-deploy-action@v4.4.0
@ -45,4 +45,5 @@ jobs:
folder: packages/vant/site-dist
token: ${{ secrets.VANT_UI_TOKEN }}
repository-name: vant-ui/vant-ui.github.io
target-folder: vant/v4
target-folder: vant
clean: false

View File

@ -37,7 +37,7 @@
- 🍭 Support Tree Shaking
- 🍭 Support Custom Theme
- 🍭 Support Accessibility (still improving)
- 🍭 Support Dark Mode (Requires upgrade to [Vant 4](https://vant-contrib.gitee.io/vant/v4/#/en-US/config-provider))
- 🍭 Support Dark Mode
- 🍭 Support SSR
- 🌍 Support i18n, built-in 20+ languages

View File

@ -41,7 +41,7 @@ Vant 是一个**轻量、可靠的移动端组件库**,于 2017 年开源。
- 🍭 支持主题定制,内置 700+ 个主题变量
- 🍭 支持按需引入和 Tree Shaking
- 🍭 支持无障碍访问(持续改进中)
- 🍭 支持深色模式(从 [Vant 4](https://vant-contrib.gitee.io/vant/v4/#/zh-CN/config-provider) 开始支持)
- 🍭 支持深色模式
- 🍭 支持服务器端渲染
- 🌍 支持国际化,内置 20+ 种语言包

View File

@ -19,6 +19,21 @@ Vant follows [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
## Details
### [v4.0.0](https://github.com/vant-ui/vant/compare/v4.0.0-rc.9...v4.0.0)
`2022-11-26`
**Feature**
- List: add disabled prop [#11307](https://github.com/vant-ui/vant/issues/11307)
- BackTop: allow dynamically set target prop [#11311](https://github.com/vant-ui/vant/issues/11311)
- BackTop: allow using css var to custom position [#11312](https://github.com/vant-ui/vant/issues/11312)
- BackTop: rename visibility-height prop to offset [#11309](https://github.com/vant-ui/vant/issues/11309)
**Bug Fixes**
- Field: keep selection position after updating value [#11308](https://github.com/vant-ui/vant/issues/11308)
### [v4.0.0-rc.9](https://github.com/vant-ui/vant/compare/v4.0.0-rc.8...v4.0.0-rc.9)
`2022-11-24`

View File

@ -19,6 +19,23 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
## 更新内容
### [v4.0.0](https://github.com/vant-ui/vant/compare/v4.0.0-rc.9...v4.0.0)
`2022-11-26`
> Vant 4.0 的完整更新日志正在整理中,请先阅读 [「从 v3 升级到 v4」](#/zh-CN/migrate-from-v3) 进行升级。
**Feature**
- List: 新增 disabled 属性 [#11307](https://github.com/vant-ui/vant/issues/11307)
- BackTop: 支持动态设置 target 属性 [#11311](https://github.com/vant-ui/vant/issues/11311)
- BackTop: 支持通过 CSS 变量修改组件位置 [#11312](https://github.com/vant-ui/vant/issues/11312)
- BackTop: 重命名 visibility-height 属性为 offset [#11309](https://github.com/vant-ui/vant/issues/11309)
**Bug Fixes**
- Field: 修复格式化值后,光标位置错误的问题 [#11308](https://github.com/vant-ui/vant/issues/11308)
### [v4.0.0-rc.9](https://github.com/vant-ui/vant/compare/v4.0.0-rc.8...v4.0.0-rc.9)
`2022-11-24`

View File

@ -19,7 +19,7 @@
- 🍭 Support Tree Shaking
- 🍭 Support Custom Theme
- 🍭 Support Accessibility (still improving)
- 🍭 Support Dark Mode (Requires upgrade to [Vant 4](https://vant-contrib.gitee.io/vant/v4/#/en-US/config-provider))
- 🍭 Support Dark Mode
- 🍭 Support SSR
- 🌍 Support i18n, built-in 20+ languages
@ -33,6 +33,17 @@ Vant 2 supports modern browsers and Android >= 4.0、iOS >= 8.0.
Vant 3/4 supports modern browsers and Chrome >= 51、iOS >= 10.0 (same as Vue 3).
### Maintenance Status
The current maintenance status of each version of Vant is as follows:
| Name | Framework | Release | Latest Version | Status |
| --- | --- | --- | --- | --- |
| Vant 4 | Vue 3 | `2022.11` | ![](https://img.shields.io/npm/v/vant/latest?style=flat-square) | Under active development |
| Vant 3 | Vue 3 | `2020.12` | ![](https://img.shields.io/npm/v/vant/latest-v3?style=flat-square) | Bugfix only |
| Vant 2 | Vue 2 | `2019.06` | ![](https://img.shields.io/npm/v/vant/latest-v2?style=flat-square) | Bugfix only |
| Vant 1 | Vue 2 | `2018.03` | ![](https://img.shields.io/npm/v/vant/latest-v1?style=flat-square) | End of life |
## Links
### Official Ecosystem

View File

@ -25,7 +25,7 @@ Vant 是一个**轻量、可靠的移动端组件库**,于 2017 年开源。
- 🍭 支持主题定制,内置 700+ 个主题变量
- 🍭 支持按需引入和 Tree Shaking
- 🍭 支持无障碍访问(持续改进中)
- 🍭 支持深色模式(从 [Vant 4](https://vant-contrib.gitee.io/vant/v4/#/zh-CN/config-provider) 开始支持)
- 🍭 支持深色模式
- 🍭 支持服务器端渲染
- 🌍 支持国际化,内置 20+ 种语言包
@ -43,6 +43,17 @@ Vant 2 支持现代浏览器以及 Android >= 4.0、iOS >= 8.0。
Vant 3/4 支持现代浏览器以及 Chrome >= 51、iOS >= 10.0(与 Vue 3 一致)。
### 维护状态
目前 Vant 各个版本的维护状态如下:
| 名称 | 框架 | 发布时间 | 最新版 | 维护状态 |
| --- | --- | --- | --- | --- |
| Vant 4 | Vue 3 | `2022.11` | ![](https://img.shields.io/npm/v/vant/latest?style=flat-square) | 持续迭代新功能 |
| Vant 3 | Vue 3 | `2020.12` | ![](https://img.shields.io/npm/v/vant/latest-v3?style=flat-square) | 停止迭代新功能bug 会被处理和修复 |
| Vant 2 | Vue 2 | `2019.06` | ![](https://img.shields.io/npm/v/vant/latest-v2?style=flat-square) | 停止迭代新功能,重要 bug 会被处理和修复 |
| Vant 1 | Vue 2 | `2018.03` | ![](https://img.shields.io/npm/v/vant/latest-v1?style=flat-square) | 停止维护,不再接受 PR |
## 链接
### 官方生态

View File

@ -1,6 +1,6 @@
{
"name": "vant",
"version": "4.0.0-rc.9",
"version": "4.0.0",
"description": "Mobile UI Components built on Vue",
"main": "lib/vant.cjs.js",
"module": "es/index.mjs",
@ -8,9 +8,6 @@
"typings": "lib/index.d.ts",
"unpkg": "lib/vant.min.js",
"jsdelivr": "lib/vant.min.js",
"npm": {
"tag": "next"
},
"files": [
"es",
"lib"

View File

@ -1,5 +1,6 @@
import {
ref,
watch,
computed,
Teleport,
nextTick,
@ -13,8 +14,8 @@ import {
// Utils
import {
addUnit,
isObject,
inBrowser,
numericProp,
getScrollTop,
createNamespace,
makeNumericProp,
@ -30,10 +31,10 @@ import { Icon } from '../icon';
const [name, bem] = createNamespace('back-top');
export const backTopProps = {
right: makeNumericProp(30),
bottom: makeNumericProp(40),
right: numericProp,
bottom: numericProp,
target: [String, Object] as PropType<TeleportProps['to']>,
visibilityHeight: makeNumericProp(200),
offset: makeNumericProp(200),
teleport: {
type: [String, Object] as PropType<TeleportProps['to']>,
default: 'body',
@ -53,10 +54,8 @@ export default defineComponent({
setup(props, { emit, slots, attrs }) {
const show = ref(false);
const scrollParent = ref<Window | HTMLElement>();
const root = ref<HTMLElement | null>(null);
let target: Window | HTMLElement;
const root = ref<HTMLElement>();
const scrollParent = ref<Window | Element>();
const style = computed(() => ({
right: addUnit(props.right),
@ -65,48 +64,53 @@ export default defineComponent({
const onClick = (event: MouseEvent) => {
emit('click', event);
target.scrollTo({
scrollParent.value?.scrollTo({
top: 0,
behavior: 'smooth',
});
};
const scroll = () => {
show.value = getScrollTop(target) >= props.visibilityHeight;
show.value = scrollParent.value
? getScrollTop(scrollParent.value) >= props.offset
: false;
};
const getTarget = () => {
const { target } = props;
if (typeof target === 'string') {
const el = document.querySelector(props.target as string);
if (!el) {
throw Error('[Vant] BackTop: target element is not found.');
const el = document.querySelector(target);
if (el) {
return el;
}
return el as HTMLElement;
}
if (isObject(target)) {
return target;
if (process.env.NODE_ENV !== 'production') {
console.error(
`[Vant] BackTop: target element "${target}" was not found, the BackTop component will not be rendered.`
);
}
} else {
return target as Element;
}
throw Error(
'[Vant] BackTop: type of prop "target" should be a selector or an element object'
);
};
useEventListener('scroll', throttle(scroll, 300), { target: scrollParent });
const updateTarget = () => {
if (inBrowser) {
nextTick(() => {
scrollParent.value = props.target
? getTarget()
: getScrollParent(root.value!);
scroll();
});
}
};
onMounted(() => {
nextTick(() => {
if (inBrowser) {
target = props.target
? (getTarget() as typeof target)
: (getScrollParent(root.value!) as typeof target);
scrollParent.value = target;
}
});
});
useEventListener('scroll', throttle(scroll, 100), { target: scrollParent });
onMounted(updateTarget);
watch(() => props.target, updateTarget);
return () => {
const Content = (

View File

@ -110,10 +110,10 @@ export default {
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| target | Can be a `selector` or `HTMLElement` | _string \| HTMLElement_ | - |
| target | Can be a selector or a DOM ELement | _string \| HTMLElement_ | - |
| right | Right distance of the page, the default unit is px | _number \| string_ | `30` |
| bottom | Bottom distance of the page, the default unit is px | _number \| string_ | `40` |
| visibility-height | The button will not show until the scroll height reaches this value | _number_ | `200` |
| offset | The component will not display until the scroll offset reaches this value | _number_ | `200` |
| teleport | Specifies a target element where BackTop will be mounted | _string \| Element_ | `body` |
### Slots

View File

@ -112,10 +112,10 @@ export default {
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| target | 触发滚动的目标对象,支持传入选择器或 `HTMLElement` | _string \| HTMLElement_ | - |
| target | 触发滚动的目标对象,支持传入选择器或 DOM 元素 | _string \| HTMLElement_ | - |
| right | 距离页面右侧的距离,默认单位为 `px` | _number \| string_ | `30` |
| bottom | 距离页面底部的距离,默认单位为 `px` | _number \| string_ | `40` |
| visibility-height | 滚动高度达到此参数值才显示 | _number_ | `200` |
| offset | 滚动高度达到此参数值时才显示组件 | _number_ | `200` |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://v3.cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | `body` |
### Slots
@ -142,5 +142,7 @@ import type { BackTopProps, BackTopThemeVars } from 'vant';
| ------------------------- | ----------------- | ---- |
| --van-back-top-size | _40px_ | - |
| --van-back-top-icon-size | _20px_ | - |
| --van-back-top-right | _30px_ | - |
| --van-back-top-bottom | _40px_ | - |
| --van-back-top-text-color | _#fff_ | - |
| --van-back-top-background | _var(--van-blue)_ | - |

View File

@ -1,5 +1,7 @@
:root {
--van-back-top-size: 40px;
--van-back-top-right: 30px;
--van-back-top-bottom: 40px;
--van-back-top-icon-size: 20px;
--van-back-top-text-color: #fff;
--van-back-top-background: var(--van-blue);
@ -12,12 +14,14 @@
justify-content: center;
width: var(--van-back-top-size);
height: var(--van-back-top-size);
right: var(--van-back-top-right);
bottom: var(--van-back-top-bottom);
cursor: pointer;
color: var(--van-back-top-text-color);
border-radius: var(--van-radius-max);
box-shadow: 0 2px 8px 0px rgba(0, 0, 0, 0.12);
transform: scale(0);
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
transition: var(--van-duration-base) cubic-bezier(0.25, 0.8, 0.5, 1);
background-color: var(--van-back-top-background);
&:active {

View File

@ -307,7 +307,9 @@ export default defineComponent({
}
if (inputRef.value && inputRef.value.value !== value) {
const { selectionStart, selectionEnd } = inputRef.value;
inputRef.value.value = value;
inputRef.value.setSelectionRange(selectionStart, selectionEnd);
}
if (value !== props.modelValue) {

View File

@ -34,6 +34,7 @@ export const listProps = {
error: Boolean,
offset: makeNumericProp(300),
loading: Boolean,
disabled: Boolean,
finished: Boolean,
errorText: String,
direction: makeStringProp<ListDirection>('down'),
@ -64,6 +65,7 @@ export default defineComponent({
if (
loading.value ||
props.finished ||
props.disabled ||
props.error ||
// skip check when inside an inactive tab
tabStatus?.value === false
@ -129,7 +131,7 @@ export default defineComponent({
};
const renderLoading = () => {
if (loading.value && !props.finished) {
if (loading.value && !props.finished && !props.disabled) {
return (
<div class={bem('loading')}>
{slots.loading ? (

View File

@ -175,6 +175,7 @@ export default {
| finished-text | Finished text | _string_ | - |
| error-text | Error loaded text | _string_ | - |
| immediate-check | Whether to check loading position immediately after mounted | _boolean_ | `true` |
| disabled | Whether to disable the load event | _boolean_ | `false` |
| direction | Scroll direction, can be set to `up` | _string_ | `down` |
### Events

View File

@ -190,6 +190,7 @@ export default {
| finished-text | 加载完成后的提示文案 | _string_ | - |
| error-text | 加载失败后的提示文案 | _string_ | - |
| immediate-check | 是否在初始化时立即执行滚动位置检查 | _boolean_ | `true` |
| disabled | 是否禁用滚动加载 | _boolean_ | `false` |
| direction | 滚动触发加载的方向,可选值为 `up` | _string_ | `down` |
### Events

View File

@ -12,6 +12,18 @@ test('should emit load event when reaching bottom', async () => {
wrapper.unmount();
});
test('should not emit load event when disabled', async () => {
const wrapper = mount(List, {
props: {
disabled: true,
},
});
await later();
expect(wrapper.emitted('load')).toBeFalsy();
expect(wrapper.emitted('update:loading')).toBeFalsy();
});
test('should reload after clicking the error text', async () => {
const wrapper = mount(List, {
props: {

View File

@ -11,8 +11,7 @@ export default {
},
site: {
publicPath:
(typeof window === 'undefined' && process.env.PUBLIC_PATH) ||
'/vant/v4',
(typeof window === 'undefined' && process.env.PUBLIC_PATH) || '/vant/',
},
vetur: {
tagPrefix: 'van-',