Compare commits

..

3 Commits

Author SHA1 Message Date
tangjinzhou 8d3c9c9bde chore: update pkg 2024-08-19 21:21:30 +08:00
tangjinzhou d5eaae9721 chore: update pkg 2024-08-19 20:39:05 +08:00
tangjinzhou f037857789 chore: update pkg 2024-08-19 20:38:53 +08:00
92 changed files with 488 additions and 8244 deletions

View File

@ -1,4 +1,4 @@
blank_issues_enabled: true blank_issues_enabled: false
contact_links: contact_links:
- name: Create new issue - name: Create new issue
url: https://vuecomponent.github.io/issue-helper/ url: https://vuecomponent.github.io/issue-helper/
@ -12,3 +12,6 @@ contact_links:
- name: Paypal - name: Paypal
url: https://www.paypal.me/tangjinzhou url: https://www.paypal.me/tangjinzhou
about: Love Ant Design Vue? Please consider supporting us via Paypal. about: Love Ant Design Vue? Please consider supporting us via Paypal.
- name: 支付宝/微信 赞助
url: https://aliyuncdn.antdv.com/alipay-and-wechat.png
about: Ant Design Vue 的健康持续发展需要您的支持,🙏

View File

@ -1,63 +0,0 @@
name: Build and Deploy to Cloudflare
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
name: Build Application
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install --force
- name: Build application
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-files
path: site/dist/
retention-days: 1
deploy:
runs-on: ubuntu-latest
name: Deploy to Cloudflare
needs: build
permissions:
contents: read
deployments: write
steps:
- name: Checkout (for config files)
uses: actions/checkout@v5
with:
sparse-checkout: |
wrangler.jsonc
sparse-checkout-cone-mode: false
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-files
path: site/dist/
- name: Deploy (Workers + Static Assets)
uses: cloudflare/wrangler-action@v3.14.1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --config wrangler.jsonc
gitHubToken: ${{ secrets.GITHUB_TOKEN }}

View File

@ -10,7 +10,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: cache package-lock.json - name: cache package-lock.json
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
@ -27,7 +27,7 @@ jobs:
- name: cache node_modules - name: cache node_modules
id: node_modules_cache_id id: node_modules_cache_id
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
@ -52,13 +52,13 @@ jobs:
# submodules: true # submodules: true
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
- name: restore cache from node_modules - name: restore cache from node_modules
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}

View File

@ -10,7 +10,7 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: cache package-lock.json - name: cache package-lock.json
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
@ -27,7 +27,7 @@ jobs:
- name: cache node_modules - name: cache node_modules
id: node_modules_cache_id id: node_modules_cache_id
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
@ -43,25 +43,25 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
- name: restore cache from node_modules - name: restore cache from node_modules
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
- name: cache lib - name: cache lib
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: lib path: lib
key: lib-${{ github.sha }} key: lib-${{ github.sha }}
- name: cache es - name: cache es
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: es path: es
key: es-${{ github.sha }} key: es-${{ github.sha }}
@ -77,13 +77,13 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
- name: restore cache from node_modules - name: restore cache from node_modules
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
@ -99,13 +99,13 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: package-temp-dir path: package-temp-dir
key: lock-${{ github.sha }} key: lock-${{ github.sha }}
- name: restore cache from node_modules - name: restore cache from node_modules
uses: actions/cache@v4 uses: actions/cache@v2
with: with:
path: node_modules path: node_modules
key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}

View File

@ -10,22 +10,6 @@
--- ---
## 4.2.6
- 🐞 Fix Modal component aria-hidden error problem under chrome [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823)
- 🐞 Fix the problem that the built-in input method of Safari automatically fills in the decimal point when inputting Chinese [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918)
- 🐞 Fix InputNumber component disabled style problem [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776)
- 🐞 Fix Select cannot lose focus problem [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819)
## 4.2.5
- 🐞 Fix Empty component memory leak problem
- 🐞 Fix Image width & height property not working problem
## 4.2.4
- 🐞 Fix Wave memory leak problem
## 4.2.3 ## 4.2.3
- 🌟 TourStep custom Button, support function children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628) - 🌟 TourStep custom Button, support function children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628)

View File

@ -10,22 +10,6 @@
--- ---
## 4.2.6
- 🐞 修复 Modal 组件在 chrome 下aria-hidden 报错问题 [#7823](https://github.com/vueComponent/ant-design-vue/issues/7823)
- 🐞 修复 Safari 下自带输入法 input 组件输入中文时,自动填写小数点问题 [#7918](https://github.com/vueComponent/ant-design-vue/issues/7918)
- 🐞 修复 InputNumber 组件 disabled 样式问题 [#7776](https://github.com/vueComponent/ant-design-vue/issues/7776)
- 🐞 修复 Select 无法失焦问题 [#7819](https://github.com/vueComponent/ant-design-vue/issues/7819)
## 4.2.5
- 🐞 修复 Empty 组件内存泄漏问题
- 🐞 修复 Image width & height 属性不生效问题
## 4.2.4
- 🐞 修复 Wave 内存泄漏问题
## 4.2.3 ## 4.2.3
- 🌟 TourStep 自定义 Button支持函数 children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628) - 🌟 TourStep 自定义 Button支持函数 children [#7628](https://github.com/vueComponent/ant-design-vue/pull/7628)

View File

@ -1,3 +1,9 @@
<p align="center">
<a href="https://www.antdv.com/">
<img width="200" src="https://aliyuncdn.antdv.com/logo.png">
</a>
</p>
<h1 align="center"> <h1 align="center">
<a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a> <a href="https://www.antdv.com/" target="_blank">Ant Design Vue</a>
</h1> </h1>
@ -12,14 +18,6 @@
[![](https://cdn-images-1.medium.com/max/2000/1*NIlj0-TdLMbo_hzSBP8tmg.png)](https://www.antdv.com/) [![](https://cdn-images-1.medium.com/max/2000/1*NIlj0-TdLMbo_hzSBP8tmg.png)](https://www.antdv.com/)
<div align="center">
<sup><strong>赞助商</strong></sup>
<br>
<a href="https://mentorbook.ai/" target="_blank">
<img src="/site/public/mentorbook_banner_zh.svg" alt="Mentorbook.AI - 你的 AI 导师,你的学习之旅" />
</a>
</div>
[English](./README.md) | 简体中文 [English](./README.md) | 简体中文
## 特性 ## 特性
@ -75,7 +73,6 @@ $ yarn add ant-design-vue
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | 在 DOM 模板中,您可以使用 ant-design-vue 组件的自定义事件camelCase | | [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | 在 DOM 模板中,您可以使用 ant-design-vue 组件的自定义事件camelCase |
| [@formily/antdv](https://github.com/formilyjs/antdv) | 这是一个结合了 Formily 和 ant-design-vue 的组件库 | | [@formily/antdv](https://github.com/formilyjs/antdv) | 这是一个结合了 Formily 和 ant-design-vue 的组件库 |
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | ant-design-vue 的 nuxt 模块扩展 | | [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | ant-design-vue 的 nuxt 模块扩展 |
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | 基于 Ant Design X 设计规范的 Vue AI 界面解决方案 |
## 问答 ## 问答
@ -90,13 +87,14 @@ ant-design-vue 是 MIT 协议的开源项目。为了项目能够更好的持续
- [Patreon](https://www.patreon.com/tangjinzhou) - [Patreon](https://www.patreon.com/tangjinzhou)
- [opencollective](https://opencollective.com/ant-design-vue) - [opencollective](https://opencollective.com/ant-design-vue)
- [paypal](https://www.paypal.me/tangjinzhou) - [paypal](https://www.paypal.me/tangjinzhou)
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2 - ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
## 赞助商 ## 赞助商
成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)] 成为赞助商,并在 Github 上的自述文件上获得您的徽标,并链接到您的网站。 [[成为赞助商](https://opencollective.com/ant-design-vue#sponsor)]
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a> <a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
## 支持者 ## 支持者

View File

@ -1,6 +1,6 @@
<p align="center"> <p align="center">
<a href="https://www.antdv.com/"> <a href="https://www.antdv.com/">
<img width="200" src="https://www.antdv.com/logo.png"> <img width="200" src="https://aliyuncdn.antdv.com/logo.png">
</a> </a>
</p> </p>
@ -18,14 +18,6 @@ An enterprise-class UI components based on Ant Design and Vue.
[![](https://cdn-images-1.medium.com/max/2000/1*NIlj0-TdLMbo_hzSBP8tmg.png)](https://www.antdv.com/) [![](https://cdn-images-1.medium.com/max/2000/1*NIlj0-TdLMbo_hzSBP8tmg.png)](https://www.antdv.com/)
<div align="center">
<sup><strong>Sponsored by</strong></sup>
<br>
<a href="https://mentorbook.ai/" target="_blank">
<img src="/site/public/mentorbook_banner_en.svg" alt="Mentorbook.AI - Your AI Mentor, Your Learning Journey" />
</a>
</div>
English | [简体中文](./README-zh_CN.md) English | [简体中文](./README-zh_CN.md)
## Features ## Features
@ -81,7 +73,6 @@ If you are in a bad network environment, you can try other registries and tools
| [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | The library function, implemented in the DOM template, can use the custom event of the ant-design-vue component (camelCase) | | [vue-dash-event](https://github.com/vueComponent/vue-dash-event) | The library function, implemented in the DOM template, can use the custom event of the ant-design-vue component (camelCase) |
| [@formily/antdv](https://github.com/formilyjs/antdv) | The Library with Formily and ant-design-vue | | [@formily/antdv](https://github.com/formilyjs/antdv) | The Library with Formily and ant-design-vue |
| [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | A nuxt module for ant-design-vue | | [@ant-design-vue/nuxt](https://github.com/vueComponent/ant-design-vue-nuxt) | A nuxt module for ant-design-vue |
| [ant-design-x-vue](https://github.com/wzc520pyfm/ant-design-x-vue) | A Vue AI interface solutions base on the Ant Design X design specification |
## Donation ## Donation
@ -90,13 +81,14 @@ ant-design-vue is an MIT-licensed open source project. In order to achieve bette
- [Patreon](https://www.patreon.com/tangjinzhou) - [Patreon](https://www.patreon.com/tangjinzhou)
- [opencollective](https://opencollective.com/ant-design-vue) - [opencollective](https://opencollective.com/ant-design-vue)
- [paypal](https://www.paypal.me/tangjinzhou) - [paypal](https://www.paypal.me/tangjinzhou)
- [支付宝或微信](https://aliyuncdn.antdv.com/alipay-and-wechat.png)
- ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2 - ETH: 0x30cc48515d8ae9fefa20ab87226ad7e8ab9c3bc2
## Sponsors ## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)] Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a> <a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/10/avatar.svg"></a>
## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md) ## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md)

View File

@ -159,12 +159,6 @@ function showWaveEffect(node: HTMLElement, className: string) {
node?.insertBefore(holder, node?.firstChild); node?.insertBefore(holder, node?.firstChild);
render(<WaveEffect target={node} className={className} />, holder); render(<WaveEffect target={node} className={className} />, holder);
return () => {
render(null, holder);
if (holder.parentElement) {
holder.parentElement.removeChild(holder);
}
};
} }
export default showWaveEffect; export default showWaveEffect;

View File

@ -33,12 +33,13 @@ export default defineComponent({
// =============================== Wave =============================== // =============================== Wave ===============================
const showWave = useWave( const showWave = useWave(
instance,
computed(() => classNames(prefixCls.value, hashId.value)), computed(() => classNames(prefixCls.value, hashId.value)),
wave, wave,
); );
let onClick: (e: MouseEvent) => void; let onClick: (e: MouseEvent) => void;
const clear = () => { const clear = () => {
const node = findDOMNode(instance) as HTMLElement; const node = findDOMNode(instance);
node.removeEventListener('click', onClick, true); node.removeEventListener('click', onClick, true);
}; };
onMounted(() => { onMounted(() => {

View File

@ -1,25 +1,21 @@
import type { ComputedRef, Ref } from 'vue'; import type { ComponentInternalInstance, ComputedRef, Ref } from 'vue';
import { onBeforeUnmount, getCurrentInstance } from 'vue';
import { findDOMNode } from '../props-util'; import { findDOMNode } from '../props-util';
import showWaveEffect from './WaveEffect'; import showWaveEffect from './WaveEffect';
export default function useWave( export default function useWave(
instance: ComponentInternalInstance | null,
className: Ref<string>, className: Ref<string>,
wave?: ComputedRef<{ disabled?: boolean }>, wave?: ComputedRef<{ disabled?: boolean }>,
): VoidFunction { ): VoidFunction {
const instance = getCurrentInstance();
let stopWave: () => void;
function showWave() { function showWave() {
const node = findDOMNode(instance); const node = findDOMNode(instance);
stopWave?.();
if (wave?.value?.disabled || !node) { if (wave?.value?.disabled || !node) {
return; return;
} }
stopWave = showWaveEffect(node, className.value);
showWaveEffect(node, className.value);
} }
onBeforeUnmount(() => {
stopWave?.();
});
return showWave; return showWave;
} }

View File

@ -21,7 +21,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
<template> <template>
<a-space direction="vertical"> <a-space direction="vertical">
<a-space wrap> <a-space warp>
<a-tooltip title="search"> <a-tooltip title="search">
<a-button type="primary" shape="circle" :icon="h(SearchOutlined)" /> <a-button type="primary" shape="circle" :icon="h(SearchOutlined)" />
</a-tooltip> </a-tooltip>
@ -32,7 +32,7 @@ If you want specific control over the positioning and placement of the `Icon`, t
</a-tooltip> </a-tooltip>
<a-button :icon="h(SearchOutlined)">Search</a-button> <a-button :icon="h(SearchOutlined)">Search</a-button>
</a-space> </a-space>
<a-space wrap> <a-space warp>
<a-tooltip title="search"> <a-tooltip title="search">
<a-button shape="circle" :icon="h(SearchOutlined)" /> <a-button shape="circle" :icon="h(SearchOutlined)" />
</a-tooltip> </a-tooltip>

View File

@ -1,4 +1,4 @@
import { defineComponent, h } from 'vue'; import { defineComponent } from 'vue';
import type { CSSProperties, ExtractPropTypes } from 'vue'; import type { CSSProperties, ExtractPropTypes } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
@ -11,6 +11,9 @@ import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style'; import useStyle from './style';
const defaultEmptyImg = <DefaultEmptyImg />;
const simpleEmptyImg = <SimpleEmptyImg />;
interface Locale { interface Locale {
description?: string; description?: string;
} }
@ -37,16 +40,13 @@ const Empty = defineComponent({
return () => { return () => {
const prefixCls = prefixClsRef.value; const prefixCls = prefixClsRef.value;
const { const {
image: mergedImage = slots.image?.() || h(DefaultEmptyImg), image = slots.image?.() || defaultEmptyImg,
description = slots.description?.() || undefined, description = slots.description?.() || undefined,
imageStyle, imageStyle,
class: className = '', class: className = '',
...restProps ...restProps
} = { ...props, ...attrs }; } = { ...props, ...attrs };
const image =
typeof mergedImage === 'function' ? (mergedImage as () => VueNode)() : mergedImage;
const isNormal =
typeof image === 'object' && 'type' in image && (image.type as any).PRESENTED_IMAGE_SIMPLE;
return wrapSSR( return wrapSSR(
<LocaleReceiver <LocaleReceiver
componentName="Empty" componentName="Empty"
@ -64,7 +64,7 @@ const Empty = defineComponent({
return ( return (
<div <div
class={classNames(prefixCls, className, hashId.value, { class={classNames(prefixCls, className, hashId.value, {
[`${prefixCls}-normal`]: isNormal, [`${prefixCls}-normal`]: image === simpleEmptyImg,
[`${prefixCls}-rtl`]: direction.value === 'rtl', [`${prefixCls}-rtl`]: direction.value === 'rtl',
})} })}
{...restProps} {...restProps}
@ -85,7 +85,7 @@ const Empty = defineComponent({
}, },
}); });
Empty.PRESENTED_IMAGE_DEFAULT = () => h(DefaultEmptyImg); Empty.PRESENTED_IMAGE_DEFAULT = defaultEmptyImg;
Empty.PRESENTED_IMAGE_SIMPLE = () => h(SimpleEmptyImg); Empty.PRESENTED_IMAGE_SIMPLE = simpleEmptyImg;
export default withInstall(Empty); export default withInstall(Empty);

View File

@ -33,11 +33,11 @@ tag: New
| target | 相当于 a 标签的 target 属性href 存在时生效 | string | - | | | target | 相当于 a 标签的 target 属性href 存在时生效 | string | - | |
| badge | 带徽标数字的悬浮按钮(不支持 status 以及相关属性) | [BadgeProps](/components/badge-cn#api) | - | | | badge | 带徽标数字的悬浮按钮(不支持 status 以及相关属性) | [BadgeProps](/components/badge-cn#api) | - | |
### 共同的事件 ### common events
| 事件名称 | 说明 | 回调参数 | 版本 | | 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | ----------------------------- | ----------------- | ---- | | -------- | --------------------------------------- | ----------------- | ---- |
| click | 设置处理 `click` 事件的处理器 | `(event) => void` | - | | click | Set the handler to handle `click` event | `(event) => void` | - |
### FloatButton.Group ### FloatButton.Group
@ -47,7 +47,7 @@ tag: New
| trigger | 触发方式(有触发方式为菜单模式) | `click` \| `hover` | - | | | trigger | 触发方式(有触发方式为菜单模式) | `click` \| `hover` | - | |
| open(v-model) | 受控展开 | boolean | - | | | open(v-model) | 受控展开 | boolean | - | |
### FloatButton.Group 事件 ### FloatButton.Group Events
| 事件名称 | 说明 | 回调参数 | 版本 | | 事件名称 | 说明 | 回调参数 | 版本 |
| ---------- | ---------------- | ----------------------- | ---- | | ---------- | ---------------- | ----------------------- | ---- |

View File

@ -122,8 +122,6 @@ See [iconfont.cn documents](http://iconfont.cn/help/detail?spm=a313x.7781069.199
### Custom SVG Icon ### Custom SVG Icon
#### vue cli 3
You can import SVG icon as an vue component by using `vue cli 3` and [`vue-svg-loader`](https://www.npmjs.com/package/vue-svg-loader). `vue-svg-loader`'s `options` [reference](https://github.com/visualfanatic/vue-svg-loader). You can import SVG icon as an vue component by using `vue cli 3` and [`vue-svg-loader`](https://www.npmjs.com/package/vue-svg-loader). `vue-svg-loader`'s `options` [reference](https://github.com/visualfanatic/vue-svg-loader).
```js ```js
@ -151,84 +149,6 @@ export default defineComponent({
}); });
``` ```
#### Rsbuild
Rsbuild is a new generation of build tool, official website https://rsbuild.dev/
Create your own `vue-svg-loader.js` file, which allows you to customize and beautify SVG, and then configure it in `rsbuild.config.ts`
```js
// vue-svg-loader.js
/* eslint-disable */
const { optimize } = require('svgo');
const { version } = require('vue');
const semverMajor = require('semver/functions/major');
module.exports = async function (svg) {
const callback = this.async();
try {
({ data: svg } = await optimize(svg, {
path: this.resourcePath,
js2svg: {
indent: 2,
pretty: true,
},
plugins: [
'convertStyleToAttrs',
'removeDoctype',
'removeXMLProcInst',
'removeComments',
'removeMetadata',
'removeTitle',
'removeDesc',
'removeStyleElement',
'removeXMLNS',
'removeXMLProcInst',
],
}));
} catch (error) {
callback(error);
return;
}
if (semverMajor(version) === 2) {
svg = svg.replace('<svg', '<svg v-on="$listeners"');
}
callback(null, `<template>${svg}</template>`);
};
```
```js
// rsbuild.config.ts
/* eslint-disable */
import { defineConfig } from '@rsbuild/core';
import { pluginVue } from '@rsbuild/plugin-vue';
export default defineConfig({
tools: {
bundlerChain(chain, { CHAIN_ID }) {
chain.module.rule(CHAIN_ID.RULE.SVG).exclude.add(/\.svg$/);
},
rspack: {
module: {
rules: [
{
test: /\.svg$/,
use: ['vue-loader', 'vue-svg-loader'],
},
],
},
resolveLoader: {
alias: {
'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'),
},
},
},
},
});
```
The following properties are available for the component: The following properties are available for the component:
| Property | Description | Type | Default | | Property | Description | Type | Default |

View File

@ -119,9 +119,7 @@ export default defineComponent({
### 自定义 SVG 图标 ### 自定义 SVG 图标
#### vue cli 3 如果使用 `vue cli 3`,可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。
可以通过配置 [vue-svg-loader](https://www.npmjs.com/package/vue-svg-loader) 来将 `svg` 图标作为 `Vue` 组件导入。更多`vue-svg-loader` 的使用方式请参阅 [文档](https://github.com/visualfanatic/vue-svg-loader)。
```js ```js
// vue.config.js // vue.config.js
@ -148,88 +146,6 @@ export default defineComponent({
}); });
``` ```
#### Rsbuild
Rsbuild 是新一代构建工具,官网 https://rsbuild.dev/
自己实现一个 `vue-svg-loader.js` 文件,好处是可以自定义美化 svg然后在 `rsbuild.config.ts` 中配置:
```js
// vue-svg-loader.js
/* eslint-disable */
const { optimize } = require('svgo');
const { version } = require('vue');
const semverMajor = require('semver/functions/major');
module.exports = async function (svg) {
const callback = this.async();
try {
({ data: svg } = await optimize(svg, {
path: this.resourcePath,
js2svg: {
indent: 2,
pretty: true,
},
plugins: [
'convertStyleToAttrs',
'removeDoctype',
'removeXMLProcInst',
'removeComments',
'removeMetadata',
'removeTitle',
'removeDesc',
'removeStyleElement',
'removeXMLNS',
'removeXMLProcInst',
],
}));
} catch (error) {
callback(error);
return;
}
if (semverMajor(version) === 2) {
svg = svg.replace('<svg', '<svg v-on="$listeners"');
}
callback(null, `<template>${svg}</template>`);
};
```
```js
// rsbuild.config.ts
/* eslint-disable */
import { defineConfig } from '@rsbuild/core';
import { pluginVue } from '@rsbuild/plugin-vue';
export default defineConfig({
tools: {
bundlerChain(chain, { CHAIN_ID }) {
chain.module
// 先给svg排除默认的规则方便下面自定义loader
.rule(CHAIN_ID.RULE.SVG)
.exclude.add(/\.svg$/);
},
rspack: {
module: {
rules: [
{
test: /\.svg$/,
use: ['vue-loader', 'vue-svg-loader'],
},
],
},
resolveLoader: {
alias: {
'vue-svg-loader': require('path').join(__dirname, './vue-svg-loader.js'),
},
},
},
},
});
```
`Icon` 中的 `component` 组件的接受的属性如下: `Icon` 中的 `component` 组件的接受的属性如下:
| 字段 | 说明 | 类型 | 只读值 | | 字段 | 说明 | 类型 | 只读值 |

View File

@ -58,13 +58,13 @@ exports[`renders ./components/image/demo/placeholder.vue correctly 1`] = `
`; `;
exports[`renders ./components/image/demo/preview-group.vue correctly 1`] = ` exports[`renders ./components/image/demo/preview-group.vue correctly 1`] = `
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/vue.png"> <div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/vue.png">
<!----> <!---->
<div class="ant-image-mask"> <div class="ant-image-mask">
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div> <div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
</div> </div>
</div> </div>
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png"> <div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
<!----> <!---->
<div class="ant-image-mask"> <div class="ant-image-mask">
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div> <div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>
@ -106,7 +106,7 @@ exports[`renders ./components/image/demo/preview-group-visible.vue correctly 1`]
`; `;
exports[`renders ./components/image/demo/preview-src.vue correctly 1`] = ` exports[`renders ./components/image/demo/preview-src.vue correctly 1`] = `
<div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://www.antdv.com/logo.png"> <div class="ant-image" style="width: 200px;"><img width="200" class="ant-image-img" src="https://aliyuncdn.antdv.com/logo.png">
<!----> <!---->
<div class="ant-image-mask"> <div class="ant-image-mask">
<div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div> <div class="ant-image-mask-info"><span role="img" aria-label="eye" class="anticon anticon-eye"><svg focusable="false" class="" data-icon="eye" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg></span>Preview</div>

View File

@ -18,7 +18,7 @@ Click the left and right switch buttons to preview multiple images.
<template> <template>
<a-image-preview-group> <a-image-preview-group>
<a-image :width="200" src="https://www.antdv.com/vue.png" /> <a-image :width="200" src="https://aliyuncdn.antdv.com/vue.png" />
<a-image :width="200" src="https://www.antdv.com/logo.png" /> <a-image :width="200" src="https://aliyuncdn.antdv.com/logo.png" />
</a-image-preview-group> </a-image-preview-group>
</template> </template>

View File

@ -19,7 +19,7 @@ You can set different preview image.
<template> <template>
<a-image <a-image
:width="200" :width="200"
src="https://www.antdv.com/logo.png" src="https://aliyuncdn.antdv.com/logo.png"
:preview="{ :preview="{
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}" }"

View File

@ -13,10 +13,10 @@ export type ImageProps = Partial<
ExtractPropTypes<ReturnType<typeof imageProps>> & ExtractPropTypes<ReturnType<typeof imageProps>> &
Omit<ImgHTMLAttributes, 'placeholder' | 'onClick'> Omit<ImgHTMLAttributes, 'placeholder' | 'onClick'>
>; >;
const Image = defineComponent({ const Image = defineComponent<ImageProps>({
name: 'AImage', name: 'AImage',
inheritAttrs: false, inheritAttrs: false,
props: imageProps(), props: imageProps() as any,
setup(props, { slots, attrs }) { setup(props, { slots, attrs }) {
const { prefixCls, rootPrefixCls, configProvider } = useConfigInject('image', props); const { prefixCls, rootPrefixCls, configProvider } = useConfigInject('image', props);
// Style // Style

View File

@ -395,11 +395,6 @@ export default defineComponent({
} }
}; };
// Solve the issue of the event triggering sequence when entering numbers in chinese input (Safari)
const onBeforeInput = () => {
userTypingRef.value = true;
};
const onKeyDown: KeyboardEventHandler = event => { const onKeyDown: KeyboardEventHandler = event => {
const { which } = event; const { which } = event;
userTypingRef.value = true; userTypingRef.value = true;
@ -582,7 +577,6 @@ export default defineComponent({
onBlur={onBlur} onBlur={onBlur}
onCompositionstart={onCompositionStart} onCompositionstart={onCompositionStart}
onCompositionend={onCompositionEnd} onCompositionend={onCompositionEnd}
onBeforeinput={onBeforeInput}
/> />
</div> </div>
</div> </div>

View File

@ -263,10 +263,6 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
[`${componentCls}-handler-wrap`]: { [`${componentCls}-handler-wrap`]: {
display: 'none', display: 'none',
}, },
[`${componentCls}-input`]: {
color: 'inherit',
},
}, },
[` [`

View File

@ -179,7 +179,7 @@ const value15 = ref<string>('Sign Up');
const value16 = ref<string>(''); const value16 = ref<string>('');
const value17 = ref<string>('Home'); const value17 = ref<string>('Home');
const value18 = ref<string[]>([]); const value18 = ref<string[]>([]);
const value19 = ref<string>('https://surelyvue.com'); const value19 = ref<string>('https://surely.cool');
const value20 = ref<string>('https://antdv.com'); const value20 = ref<string>('https://antdv.com');
</script> </script>
<style scoped> <style scoped>

View File

@ -29,7 +29,7 @@ A basic widget for getting the user input is a text field. Keyboard and mouse ca
| id | The ID for input | string | | | | id | The ID for input | string | | |
| maxlength | max length | number | | 1.5.0 | | maxlength | max length | number | | 1.5.0 |
| prefix | The prefix icon for the Input. | string\|slot | | | | prefix | The prefix icon for the Input. | string\|slot | | |
| showCount | Whether show text count | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string | false | 3.0 | | showCount | Whether show text count | boolean | false | 3.0 |
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 | | status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
| size | The size of the input box. Note: in the context of a form, the `middle` size is used. Available: `large` `middle` `small` | string | - | | | size | The size of the input box. Note: in the context of a form, the `middle` size is used. Available: `large` `middle` `small` | string | - | |
| suffix | The suffix icon for the Input. | string\|slot | | | | suffix | The suffix icon for the Input. | string\|slot | | |
@ -52,7 +52,7 @@ A basic widget for getting the user input is a text field. Keyboard and mouse ca
| allowClear | allow to remove input content with clear icon | boolean | | 1.5.0 | | | allowClear | allow to remove input content with clear icon | boolean | | 1.5.0 | |
| autosize | Height autosize feature, can be set to `true | false`or an object`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | | | autosize | Height autosize feature, can be set to `true | false`or an object`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
| defaultValue | The initial input content | string | | | | | defaultValue | The initial input content | string | | | |
| showCount | Whether show text count | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string | false | | | | showCount | Whether show text count | boolean | false | | |
| value(v-model) | The input content value | string | | | | | value(v-model) | The input content value | string | | | |
### TextArea Events ### TextArea Events

View File

@ -30,7 +30,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sBqqTatJ-AkAAA
| id | 输入框的 id | string | | | | id | 输入框的 id | string | | |
| maxlength | 最大长度 | number | | 1.5.0 | | maxlength | 最大长度 | number | | 1.5.0 |
| prefix | 带有前缀图标的 input | string\|slot | | | | prefix | 带有前缀图标的 input | string\|slot | | |
| showCount | 是否展示字数 | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string } | false | 3.0 | | showCount | 是否展示字数 | boolean | false | 3.0 |
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 | | status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
| size | 控件大小。注:标准表单内的输入框大小限制为 `middle`。可选 `large` `middle` `small` | string | - | | | size | 控件大小。注:标准表单内的输入框大小限制为 `middle`。可选 `large` `middle` `small` | string | - | |
| suffix | 带有后缀图标的 input | string\|slot | | | | suffix | 带有后缀图标的 input | string\|slot | | |
@ -53,7 +53,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sBqqTatJ-AkAAA
| allowClear | 可以点击清除图标删除内容 | boolean | | 1.5.0 | | | allowClear | 可以点击清除图标删除内容 | boolean | | 1.5.0 | |
| autosize | 自适应内容高度,可设置为 `true | false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | | | autosize | 自适应内容高度,可设置为 `true | false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
| defaultValue | 输入框默认内容 | string | | | | | defaultValue | 输入框默认内容 | string | | | |
_| showCount | 是否展示字数 | boolean \| { formatter: (info: { value: string, count: number, maxLength?: number }) => string } | false | | |_ | showCount | 是否展示字数 | boolean | false | | |
| value(v-model) | 输入框内容 | string | | | | | value(v-model) | 输入框内容 | string | | | |
### TextArea 事件 ### TextArea 事件

View File

@ -3,7 +3,7 @@
order: 4 order: 4
title: title:
zh-CN: 向上展开 zh-CN: 向上展开
en-US: Placement en-US: Placemen
--- ---
## zh-CN ## zh-CN

View File

@ -47,9 +47,7 @@ const Holder = defineComponent({
'rtl', 'rtl',
'transitionName', 'transitionName',
'onAllRemoved', 'onAllRemoved',
'animation', ] as any,
'staticGetContainer',
],
setup(props, { expose }) { setup(props, { expose }) {
const { getPrefixCls, getPopupContainer } = useConfigInject('message', props); const { getPrefixCls, getPopupContainer } = useConfigInject('message', props);

View File

@ -105,7 +105,7 @@ exports[`renders ./components/qrcode/demo/icon.vue correctly 1`] = `
</div> </div>
`; `;
exports[`renders ./components/qrcode/demo/popover.vue correctly 1`] = `<img width="100" height="100" src="https://www.antdv.com/logo.png">`; exports[`renders ./components/qrcode/demo/popover.vue correctly 1`] = `<img width="100" height="100" src="https://aliyuncdn.antdv.com/logo.png">`;
exports[`renders ./components/qrcode/demo/status.vue correctly 1`] = ` exports[`renders ./components/qrcode/demo/status.vue correctly 1`] = `
<div class="ant-space ant-space-horizontal ant-space-align-center"> <div class="ant-space ant-space-horizontal ant-space-align-center">

View File

@ -19,6 +19,6 @@ With Popover.
<template #content> <template #content>
<a-qrcode value="http://www.antdv.com" :bordered="false" /> <a-qrcode value="http://www.antdv.com" :bordered="false" />
</template> </template>
<img width="100" height="100" src="https://www.antdv.com/logo.png" /> <img width="100" height="100" src="https://aliyuncdn.antdv.com/logo.png" />
</a-popover> </a-popover>
</template> </template>

View File

@ -159,52 +159,6 @@ describe('Select', () => {
}, 500); }, 500);
}); });
it('The select trigger should be blur when the panel is closed.', async () => {
const wrapper = mount(
{
render() {
return (
<Select
dropdownRender={() => {
return <input id="dropdownRenderInput" />;
}}
/>
);
},
},
{
sync: false,
attachTo: 'body',
},
);
await asyncExpect(async () => {
await wrapper.find('.ant-select-selector').trigger('mousedown');
await wrapper.find('.ant-select-selection-search-input').trigger('focus');
});
await asyncExpect(async () => {
const el = wrapper.find('.ant-select');
expect(el.classes()).toContain('ant-select-focused');
$$('#dropdownRenderInput')[0].focus();
expect(el.classes()).toContain('ant-select-focused');
document.body.dispatchEvent(
new MouseEvent('mousedown', {
bubbles: true,
cancelable: true,
view: window,
}),
);
}, 100);
await asyncExpect(async () => {
const el = wrapper.find('.ant-select');
expect(el.classes()).not.toContain('ant-select-focused');
}, 200);
});
describe('Select Custom Icons', () => { describe('Select Custom Icons', () => {
it('should support customized icons', () => { it('should support customized icons', () => {
const wrapper = mount({ const wrapper = mount({

View File

@ -63,7 +63,7 @@ Select component to select value from options.
| searchValue | The current input "search" text | string | - | | | searchValue | The current input "search" text | string | - | |
| showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | | | showArrow | Whether to show the drop-down arrow | boolean | single:true, multiple:false | |
| showSearch | Whether select is searchable | boolean | single:false, multiple:true | | | showSearch | Whether select is searchable | boolean | single:false, multiple:true | |
| size | Size of Select input. `middle` `large` `small` | string | middle | | | size | Size of Select input. `default` `large` `small` | string | default | |
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 | | status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
| suffixIcon | The custom suffix icon | VNode \| slot | - | | | suffixIcon | The custom suffix icon | VNode \| slot | - | |
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | | | tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | |

View File

@ -63,7 +63,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*5oPiTqPxGAUAAA
| searchValue | 控制搜索文本 | string | - | | | searchValue | 控制搜索文本 | string | - | |
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | | | showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | | | showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
| size | 选择框大小,可选 `middle` `large` `small` | string | middle | | | size | 选择框大小,可选 `large` `small` | string | default | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 | | status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | | | suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | |
| tagRender | 自定义 tag 内容 render仅在 `mode``multiple``tags` 时生效 | slot \| (props) => any | - | 3.0 | | tagRender | 自定义 tag 内容 render仅在 `mode``multiple``tags` 时生效 | slot \| (props) => any | - | 3.0 |

View File

@ -213,7 +213,7 @@ export default function genMultipleStyle(token: SelectToken): CSSInterpolation {
[`${componentCls}-multiple${componentCls}-sm`]: { [`${componentCls}-multiple${componentCls}-sm`]: {
[`${componentCls}-selection-placeholder`]: { [`${componentCls}-selection-placeholder`]: {
insetInlineStart: token.controlPaddingHorizontalSM - token.lineWidth, insetInlineStart: token.controlPaddingHorizontalSM - token.lineWidth,
insetInlineEnd: token.controlPaddingHorizontalSM - token.lineWidth, insetInlineEnd: 'auto',
}, },
// https://github.com/ant-design/ant-design/issues/29559 // https://github.com/ant-design/ant-design/issues/29559

View File

@ -17,8 +17,8 @@ The `onChange` callback function will fire when the user changes the slider's va
<template> <template>
<div class="code-box-demo"> <div class="code-box-demo">
<a-slider v-model:value="value1" @change="onChange" @afterChange="onAfterChange" /> <a-slider v-model:value="value1" @afterChange="onAfterChange" />
<a-slider v-model:value="value2" range :step="10" @change="onChange" @afterChange="onAfterChange" /> <a-slider v-model:value="value2" range :step="10" @afterChange="onAfterChange" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -26,10 +26,6 @@ import { ref } from 'vue';
const value1 = ref<number>(30); const value1 = ref<number>(30);
const value2 = ref<[number, number]>([20, 50]); const value2 = ref<[number, number]>([20, 50]);
const onChange = (value: number) => {
console.log('onChange: ', value);
};
const onAfterChange = (value: number) => { const onAfterChange = (value: number) => {
console.log('afterChange: ', value); console.log('afterChange: ', value);
}; };

View File

@ -182,7 +182,6 @@ const genBaseStyle: GenerateStyle<SliderToken> = token => {
borderRadius: '50%', borderRadius: '50%',
cursor: 'pointer', cursor: 'pointer',
transition: `border-color ${token.motionDurationSlow}`, transition: `border-color ${token.motionDurationSlow}`,
pointerEvents: 'auto',
'&-active': { '&-active': {
borderColor: token.colorPrimaryBorder, borderColor: token.colorPrimaryBorder,

View File

@ -127,7 +127,7 @@ exports[`renders ./components/table/demo/basic.vue correctly 1`] = `
`; `;
exports[`renders ./components/table/demo/big-data.vue correctly 1`] = ` exports[`renders ./components/table/demo/big-data.vue correctly 1`] = `
<iframe src="https://www.surelyvue.com/for-ant-demo" height="400"></iframe> <iframe src="https://www.surely.cool/for-ant-demo" height="400"></iframe>
<!--v-if--> <!--v-if-->
`; `;

View File

@ -79,9 +79,8 @@ type APIResult = {
}[]; }[];
}; };
const queryData = async (params: APIParams) => { const queryData = (params: APIParams) => {
const res = await axios.get<APIResult>('https://randomuser.me/api?noinfo', { params }) return axios.get<APIResult>('https://randomuser.me/api?noinfo', { params });
return res.data.results;
}; };
const { const {
@ -91,6 +90,7 @@ const {
current, current,
pageSize, pageSize,
} = usePagination(queryData, { } = usePagination(queryData, {
formatResult: res => res.data.results,
pagination: { pagination: {
currentKey: 'page', currentKey: 'page',
pageSizeKey: 'results', pageSizeKey: 'results',

View File

@ -8,21 +8,21 @@ title:
## zh-CN ## zh-CN
该示例使用高级组件 [Surely Vue](https://www.surelyvue.com) Surely Vue Ant Design Vue 该示例使用高级组件 [Surely Vue](https://www.surely.cool) Surely Vue Ant Design Vue
该组件致力于解决大数据渲染图表集成等复杂高频问题 使用该组件可以流畅滚动 10 万行10 万列的数据你不必担心页面卡顿造成用户投诉进而影响业务进展 该组件致力于解决大数据渲染图表集成等复杂高频问题 使用该组件可以流畅滚动 10 万行10 万列的数据你不必担心页面卡顿造成用户投诉进而影响业务进展
## en-US ## en-US
This example uses advanced components [Surely Vue](https://www.surelyvue.com) for development. This example uses advanced components [Surely Vue](https://www.surely.cool) for development.
This component is dedicated to solving complex high-frequency issues such as big data rendering and chart integration. This component is dedicated to solving complex high-frequency issues such as big data rendering and chart integration.
Using this component, you can smoothly scroll through 100,000 rows and 100,000 columns of data. Using this component, you can smoothly scroll through 100,000 rows and 100,000 columns of data.
</docs> </docs>
<template> <template>
<iframe src="https://www.surelyvue.com/for-ant-demo" height="400"></iframe> <iframe src="https://www.surely.cool/for-ant-demo" height="400"></iframe>
<div v-if="false"> <div v-if="false">
you can visit you can visit
<a href="https://www.surelyvue.com"></a> <a href="https://www.surely.cool"></a>
get more info get more info
</div> </div>
</template> </template>

View File

@ -24,7 +24,6 @@ Ant Design has 3 types of Tabs for different situations.
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| activeKey(v-model) | Current TabPane's key | string | - | | | activeKey(v-model) | Current TabPane's key | string | - | |
| animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | | | animated | Whether to change tabs with animation. Only works while tabPosition=`"top"` \| `"bottom"` | boolean \| {inkBar:boolean, tabPane:boolean} | `true`, `false` when `type="card"` | |
| centered | Whether to display the labels in the center | boolean | false | 3.0 |
| destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | | | destroyInactiveTabPane | Whether destroy inactive TabPane when change tab | boolean | false | |
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } | | hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | } |
| size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | | | size | preset tab bar size | `large` \| `middle` \| `small` | `middle` | |

View File

@ -74,7 +74,7 @@ Almost anything can be represented in a tree structure. Examples include directo
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | | | disableCheckbox | Disables the checkbox of the treeNode | boolean | false | |
| disabled | Disables the treeNode | boolean | false | | | disabled | Disables the treeNode | boolean | false | |
| icon | customize icon. When you pass component, whose render will receive full TreeNode props as component props | slot\|slot-scope | - | | | icon | customize icon. When you pass component, whose render will receive full TreeNode props as component props | slot\|slot-scope | - | |
| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | - | | | isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | false | |
| key | Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. P.S.: It must be unique in all of treeNodes of the tree! | string \| number | internal calculated position of treeNode | | | key | Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. P.S.: It must be unique in all of treeNodes of the tree! | string \| number | internal calculated position of treeNode | |
| selectable | Set whether the treeNode can be selected | boolean | true | | | selectable | Set whether the treeNode can be selected | boolean | true | |
| style | style | string\|object | - | | | style | style | string\|object | - | |

View File

@ -75,7 +75,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*1GeUQJPTGUYAAA
| disableCheckbox | 禁掉 checkbox | boolean | false | | | disableCheckbox | 禁掉 checkbox | boolean | false | |
| disabled | 禁掉响应 | boolean | false | | | disabled | 禁掉响应 | boolean | false | |
| icon | 自定义图标。可接收组件props 为当前节点 props | slot\|slot-scope | - | | | icon | 自定义图标。可接收组件props 为当前节点 props | slot\|slot-scope | - | |
| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | - | | | isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | false | |
| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | | | key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | |
| selectable | 设置节点是否可被选中 | boolean | true | | | selectable | 设置节点是否可被选中 | boolean | true | |
| style | 节点的 style | string\|object | - | | | style | 节点的 style | string\|object | - | |

View File

@ -72,11 +72,11 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| copyableIcon | 自定义拷贝图标 | `{ copied: boolean }` | `copied ? <CheckOutlined /> : <CopyOutlined />` | | | copyableIcon | 自定义拷贝图标 | `{ copied: boolean }` | `copied ? <CheckOutlined /> : <CopyOutlined />` | |
| copyableTooltip | 自定义提示文案,当 `copyable.tooltip = false` 时关闭 | `{ copied: boolean }` | `copied ? '复制成功' : '复制'` | | | copyableTooltip | 自定义提示文案,当 `copyable.tooltip = false` 时关闭 | `{ copied: boolean }` | `copied ? '复制成功' : '复制'` | |
| editableEnterIcon | 在编辑段中自定义“enter”图标 | `{className: string}` | `<EnterOutlined />` | 3.0 |
| editableIcon | 自定义编辑图标 | - | &lt;EditOutlined /> | | | editableIcon | 自定义编辑图标 | - | &lt;EditOutlined /> | |
| editableTooltip | 自定义提示文本,当 `editable.tooltip = false` 时关闭 | - | `编辑` | | | editableTooltip | 自定义提示文本,当 `editable.tooltip = false` 时关闭 | - | `编辑` | |
| ellipsisSymbol | 自定义展开描述文案 | - | - | | | ellipsisSymbol | 自定义展开描述文案 | - | - | |
| ellipsisTooltip | 省略时,展示提示信息 | - | - | | | ellipsisTooltip | 省略时,展示提示信息 | - | - | |
| enterEnterIcon | 在编辑段中自定义“enter”图标 | `{className: string}` | `<EnterOutlined />` | 3.0 |
### copyable ### copyable

View File

@ -5,7 +5,7 @@ import { getTransitionProps } from '../_util/transition';
import dialogPropTypes from './IDialogPropTypes'; import dialogPropTypes from './IDialogPropTypes';
import { offset } from './util'; import { offset } from './util';
const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' }; const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' };
const entityStyle = { outline: 'none' };
export type ContentRef = { export type ContentRef = {
focus: () => void; focus: () => void;
changeActive: (next: boolean) => void; changeActive: (next: boolean) => void;
@ -28,14 +28,14 @@ export default defineComponent({
const dialogRef = ref<HTMLDivElement>(); const dialogRef = ref<HTMLDivElement>();
expose({ expose({
focus: () => { focus: () => {
sentinelStartRef.value?.focus({ preventScroll: true }); sentinelStartRef.value?.focus();
}, },
changeActive: next => { changeActive: next => {
const { activeElement } = document; const { activeElement } = document;
if (next && activeElement === sentinelEndRef.value) { if (next && activeElement === sentinelEndRef.value) {
sentinelStartRef.value.focus({ preventScroll: true }); sentinelStartRef.value.focus();
} else if (!next && activeElement === sentinelStartRef.value) { } else if (!next && activeElement === sentinelStartRef.value) {
sentinelEndRef.value.focus({ preventScroll: true }); sentinelEndRef.value.focus();
} }
}, },
}); });
@ -143,10 +143,9 @@ export default defineComponent({
onMousedown={onMousedown} onMousedown={onMousedown}
onMouseup={onMouseup} onMouseup={onMouseup}
> >
<div tabindex={0} ref={sentinelStartRef} style={entityStyle}> <div tabindex={0} ref={sentinelStartRef} style={sentinelStyle} aria-hidden="true" />
{modalRender ? modalRender({ originVNode: content }) : content} {modalRender ? modalRender({ originVNode: content }) : content}
</div> <div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} aria-hidden="true" />
<div tabindex={0} ref={sentinelEndRef} style={sentinelStyle} />
</div> </div>
) : null} ) : null}
</Transition> </Transition>

View File

@ -1,4 +1,4 @@
import type { CSSProperties, PropType } from 'vue'; import type { ImgHTMLAttributes, CSSProperties, PropType } from 'vue';
import { ref, watch, defineComponent, computed, onMounted, onUnmounted } from 'vue'; import { ref, watch, defineComponent, computed, onMounted, onUnmounted } from 'vue';
import isNumber from 'lodash-es/isNumber'; import isNumber from 'lodash-es/isNumber';
import cn from '../../_util/classNames'; import cn from '../../_util/classNames';
@ -32,8 +32,6 @@ export const imageProps = () => ({
rootClassName: String, rootClassName: String,
prefixCls: String, prefixCls: String,
previewPrefixCls: String, previewPrefixCls: String,
width: [Number, String],
height: [Number, String],
previewMask: { previewMask: {
type: [Boolean, Function] as PropType<false | (() => any)>, type: [Boolean, Function] as PropType<false | (() => any)>,
default: undefined, default: undefined,
@ -203,6 +201,8 @@ const ImageInternal = defineComponent({
placeholder, placeholder,
wrapperStyle, wrapperStyle,
rootClassName, rootClassName,
} = props;
const {
width, width,
height, height,
crossorigin, crossorigin,
@ -213,7 +213,7 @@ const ImageInternal = defineComponent({
usemap, usemap,
class: cls, class: cls,
style, style,
} = { ...props, ...attrs } as any; } = attrs as ImgHTMLAttributes;
const { icons, maskClassName, ...dialogProps } = preview.value; const { icons, maskClassName, ...dialogProps } = preview.value;
const wrappperClass = cn(prefixCls, wrapperClassName, rootClassName, { const wrappperClass = cn(prefixCls, wrapperClassName, rootClassName, {

View File

@ -2,7 +2,6 @@ import { getTransitionGroupProps } from '../_util/transition';
import type { Key, VueNode } from '../_util/type'; import type { Key, VueNode } from '../_util/type';
import type { CSSProperties } from 'vue'; import type { CSSProperties } from 'vue';
import { import {
toRaw,
shallowRef, shallowRef,
createVNode, createVNode,
computed, computed,
@ -73,10 +72,10 @@ type NotificationState = {
holderCallback?: HolderReadyCallback; holderCallback?: HolderReadyCallback;
}[]; }[];
const Notification = defineComponent({ const Notification = defineComponent<NotificationProps>({
name: 'Notification', name: 'Notification',
inheritAttrs: false, inheritAttrs: false,
props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'], props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'] as any,
setup(props, { attrs, expose, slots }) { setup(props, { attrs, expose, slots }) {
const hookRefs = new Map<Key, HTMLDivElement>(); const hookRefs = new Map<Key, HTMLDivElement>();
const notices = ref<NotificationState>([]); const notices = ref<NotificationState>([]);
@ -126,7 +125,7 @@ const Notification = defineComponent({
}; };
const remove = (removeKey: Key) => { const remove = (removeKey: Key) => {
notices.value = toRaw(notices.value as any).filter(({ notice: { key, userPassKey } }) => { notices.value = notices.value.filter(({ notice: { key, userPassKey } }) => {
const mergedKey = userPassKey || key; const mergedKey = userPassKey || key;
return mergedKey !== removeKey; return mergedKey !== removeKey;
}); });

View File

@ -39,15 +39,14 @@ const overflowProps = () => {
/** When set to `full`, ssr will render full items by default and remove at client side */ /** When set to `full`, ssr will render full items by default and remove at client side */
ssr: String as PropType<'full'>, ssr: String as PropType<'full'>,
onMousedown: Function as PropType<MouseEventHandler>, onMousedown: Function as PropType<MouseEventHandler>,
role: String,
}; };
}; };
type InterOverflowProps = Partial<ExtractPropTypes<ReturnType<typeof overflowProps>>>; type InterOverflowProps = Partial<ExtractPropTypes<ReturnType<typeof overflowProps>>>;
export type OverflowProps = HTMLAttributes & InterOverflowProps; export type OverflowProps = HTMLAttributes & InterOverflowProps;
const Overflow = defineComponent({ const Overflow = defineComponent<OverflowProps>({
name: 'Overflow', name: 'Overflow',
inheritAttrs: false, inheritAttrs: false,
props: overflowProps(), props: overflowProps() as any,
emits: ['visibleChange'], emits: ['visibleChange'],
setup(props, { attrs, emit, slots }) { setup(props, { attrs, emit, slots }) {
const fullySSR = computed(() => props.ssr === 'full'); const fullySSR = computed(() => props.ssr === 'full');
@ -332,7 +331,6 @@ const Overflow = defineComponent({
class={classNames(!invalidate.value && prefixCls, className)} class={classNames(!invalidate.value && prefixCls, className)}
style={style} style={style}
onMousedown={onMousedown} onMousedown={onMousedown}
role={props.role}
{...restAttrs} {...restAttrs}
> >
{mergedData.value.map(internalRenderItemNode)} {mergedData.value.map(internalRenderItemNode)}

View File

@ -18,9 +18,9 @@ export type TimeUnitColumnProps = {
onSelect?: (value: number) => void; onSelect?: (value: number) => void;
}; };
export default defineComponent({ export default defineComponent<TimeUnitColumnProps>({
name: 'TimeUnitColumn', name: 'TimeUnitColumn',
props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'], props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'] as any,
setup(props) { setup(props) {
const { open } = useInjectPanel(); const { open } = useInjectPanel();

View File

@ -343,14 +343,6 @@ export default defineComponent({
if (mergedOpen.value !== nextOpen && !props.disabled) { if (mergedOpen.value !== nextOpen && !props.disabled) {
setInnerOpen(nextOpen); setInnerOpen(nextOpen);
props.onDropdownVisibleChange && props.onDropdownVisibleChange(nextOpen); props.onDropdownVisibleChange && props.onDropdownVisibleChange(nextOpen);
if (!nextOpen && popupFocused.value) {
popupFocused.value = false;
setMockFocused(false, () => {
focusRef.value = false;
blurRef.value = false;
});
}
} }
}; };
@ -840,7 +832,6 @@ export default defineComponent({
customizeRawInputElement, customizeRawInputElement,
{ {
ref: selectorDomRef, ref: selectorDomRef,
tabindex: 0,
}, },
false, false,
true, true,
@ -878,11 +869,7 @@ export default defineComponent({
// Render raw // Render raw
if (customizeRawInputElement) { if (customizeRawInputElement) {
renderNode = ( renderNode = selectorNode;
<div onKeydown={onInternalKeyDown} onKeyup={onInternalKeyUp}>
{selectorNode}
</div>
);
} else { } else {
renderNode = ( renderNode = (
<div <div

View File

@ -151,7 +151,7 @@ const SelectSelector = defineComponent<SelectorProps>({
) { ) {
const onMouseDown = (e: MouseEvent) => { const onMouseDown = (e: MouseEvent) => {
onPreventMouseDown(e); onPreventMouseDown(e);
props.onToggleOpen(!props.open); props.onToggleOpen(!open);
}; };
let originData = option; let originData = option;
// For TreeSelect // For TreeSelect

View File

@ -2,13 +2,11 @@ import type { BaseOptionType, DefaultOptionType, RawValueType, FieldNames } from
import { warning } from '../../vc-util/warning'; import { warning } from '../../vc-util/warning';
import type { FlattenOptionData } from '../interface'; import type { FlattenOptionData } from '../interface';
function getKey(data: BaseOptionType, index: number, fieldNames?: FieldNames) { function getKey(data: BaseOptionType, index: number) {
const { key } = data; const { key } = data;
let value: RawValueType; let value: RawValueType;
if (fieldNames && fieldNames.value && data[fieldNames.value] !== undefined) { if ('value' in data) {
({ [fieldNames.value]: value } = data);
} else if ('value' in data) {
({ value } = data); ({ value } = data);
} }
@ -56,7 +54,7 @@ export function flattenOptions<OptionType extends BaseOptionType = DefaultOption
const value = data[fieldValue]; const value = data[fieldValue];
// Option // Option
flattenList.push({ flattenList.push({
key: getKey(data, flattenList.length, fieldNames), key: getKey(data, flattenList.length),
groupOption: isGroupOption, groupOption: isGroupOption,
data, data,
label, label,
@ -69,7 +67,7 @@ export function flattenOptions<OptionType extends BaseOptionType = DefaultOption
} }
// Option Group // Option Group
flattenList.push({ flattenList.push({
key: getKey(data, flattenList.length, fieldNames), key: getKey(data, flattenList.length),
group: true, group: true,
data, data,
label: grpLabel, label: grpLabel,

View File

@ -7,7 +7,7 @@ const Track = (_, { attrs }) => {
length = Math.abs(length); length = Math.abs(length);
offset = 100 - offset; offset = 100 - offset;
} }
const positionStyle = vertical const positonStyle = vertical
? { ? {
[reverse ? 'top' : 'bottom']: `${offset}%`, [reverse ? 'top' : 'bottom']: `${offset}%`,
[reverse ? 'bottom' : 'top']: 'auto', [reverse ? 'bottom' : 'top']: 'auto',
@ -21,7 +21,7 @@ const Track = (_, { attrs }) => {
const elStyle = { const elStyle = {
...style, ...style,
...positionStyle, ...positonStyle,
}; };
return included ? <div class={className} style={elStyle} /> : null; return included ? <div class={className} style={elStyle} /> : null;
}; };

View File

@ -77,7 +77,7 @@ export interface CellProps<RecordType = DefaultRecordType> {
transformCellText?: TransformCellText<RecordType>; transformCellText?: TransformCellText<RecordType>;
} }
export default defineComponent({ export default defineComponent<CellProps>({
name: 'Cell', name: 'Cell',
props: [ props: [
'prefixCls', 'prefixCls',
@ -104,7 +104,7 @@ export default defineComponent({
'column', 'column',
'cellType', 'cellType',
'transformCellText', 'transformCellText',
], ] as any,
setup(props, { slots }) { setup(props, { slots }) {
const contextSlots = useInjectSlots(); const contextSlots = useInjectSlots();
const { onHover, startRow, endRow } = useInjectHover(); const { onHover, startRow, endRow } = useInjectHover();
@ -318,7 +318,7 @@ export default defineComponent({
// ====================== Render ====================== // ====================== Render ======================
let title: string; let title: string;
const ellipsisConfig = ellipsis === true ? { showTitle: true } : ellipsis; const ellipsisConfig: CellEllipsisType = ellipsis === true ? { showTitle: true } : ellipsis;
if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) { if (ellipsisConfig && (ellipsisConfig.showTitle || rowType === 'header')) {
if (typeof childNode === 'string' || typeof childNode === 'number') { if (typeof childNode === 'string' || typeof childNode === 'number') {
title = childNode.toString(); title = childNode.toString();

View File

@ -12,9 +12,9 @@ export interface SummaryCellProps {
align?: AlignType; align?: AlignType;
} }
export default defineComponent({ export default defineComponent<SummaryCellProps>({
name: 'ATableSummaryCell', name: 'ATableSummaryCell',
props: ['index', 'colSpan', 'rowSpan', 'align'], props: ['index', 'colSpan', 'rowSpan', 'align'] as any,
setup(props, { attrs, slots }) { setup(props, { attrs, slots }) {
const tableContext = useInjectTable(); const tableContext = useInjectTable();
const summaryContext = useInjectSummary(); const summaryContext = useInjectSummary();

View File

@ -149,7 +149,7 @@ export interface TableProps<RecordType = DefaultRecordType> {
transformCellText?: TransformCellText<RecordType>; transformCellText?: TransformCellText<RecordType>;
} }
export default defineComponent({ export default defineComponent<TableProps<DefaultRecordType>>({
name: 'VcTable', name: 'VcTable',
inheritAttrs: false, inheritAttrs: false,
props: [ props: [
@ -191,7 +191,7 @@ export default defineComponent({
'canExpandable', 'canExpandable',
'onUpdateInternalRefs', 'onUpdateInternalRefs',
'transformCellText', 'transformCellText',
], ] as any,
emits: ['expand', 'expandedRowsChange', 'updateInternalRefs', 'update:expandedRowKeys'], emits: ['expand', 'expandedRowsChange', 'updateInternalRefs', 'update:expandedRowKeys'],
setup(props, { attrs, slots, emit }) { setup(props, { attrs, slots, emit }) {
const mergedData = computed(() => props.data || EMPTY_DATA); const mergedData = computed(() => props.data || EMPTY_DATA);
@ -271,7 +271,7 @@ export default defineComponent({
// defalutXxxx // defalutXxxx
stop(); stop();
const mergedExpandedKeys = computed<Set<Key>>( const mergedExpandedKeys = computed(
() => new Set(props.expandedRowKeys || innerExpandedKeys.value || []), () => new Set(props.expandedRowKeys || innerExpandedKeys.value || []),
); );
@ -282,9 +282,9 @@ export default defineComponent({
const hasKey = mergedExpandedKeys.value.has(key); const hasKey = mergedExpandedKeys.value.has(key);
if (hasKey) { if (hasKey) {
mergedExpandedKeys.value.delete(key); mergedExpandedKeys.value.delete(key);
newExpandedKeys = [...(mergedExpandedKeys.value as any)]; newExpandedKeys = [...mergedExpandedKeys.value];
} else { } else {
newExpandedKeys = [...(mergedExpandedKeys.value as any), key]; newExpandedKeys = [...mergedExpandedKeys.value, key];
} }
innerExpandedKeys.value = newExpandedKeys; innerExpandedKeys.value = newExpandedKeys;

View File

@ -108,7 +108,7 @@ function useColumns<RecordType>(
prefixCls?: Ref<string>; prefixCls?: Ref<string>;
columns?: Ref<ColumnsType<RecordType>>; columns?: Ref<ColumnsType<RecordType>>;
expandable: Ref<boolean>; expandable: Ref<boolean>;
expandedKeys: ComputedRef<Set<Key>>; expandedKeys: Ref<Set<Key>>;
getRowKey: Ref<GetRowKey<RecordType>>; getRowKey: Ref<GetRowKey<RecordType>>;
onTriggerExpand: TriggerEventHandler<RecordType>; onTriggerExpand: TriggerEventHandler<RecordType>;
expandIcon?: Ref<RenderExpandIcon<RecordType>>; expandIcon?: Ref<RenderExpandIcon<RecordType>>;

View File

@ -30,7 +30,7 @@ export default function Mask(props: MaskProps) {
return ( return (
<Transition appear {...motion}> <Transition appear {...motion}>
<div v-show={visible} style={{ zIndex }} class={`${prefixCls}-mask`} /> <div v-if={visible} style={{ zIndex }} class={`${prefixCls}-mask`} />
</Transition> </Transition>
); );
} }

View File

@ -196,7 +196,7 @@ export default defineComponent({
ref={alignRef} ref={alignRef}
monitorWindowResize monitorWindowResize
disabled={alignDisabled.value} disabled={alignDisabled.value}
align={align as any} align={align}
onAlign={onInternalAlign} onAlign={onInternalAlign}
v-slots={{ v-slots={{
default: () => ( default: () => (
@ -204,11 +204,11 @@ export default defineComponent({
class={mergedClassName} class={mergedClassName}
onMouseenter={onMouseenter} onMouseenter={onMouseenter}
onMouseleave={onMouseleave} onMouseleave={onMouseleave}
onMousedown={withModifiers(onMousedown, ['capture'] as any)} onMousedown={withModifiers(onMousedown, ['capture'])}
{...{ {...{
[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: withModifiers( [supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: withModifiers(
onTouchstart, onTouchstart,
['capture'] as any, ['capture'],
), ),
}} }}
style={mergedStyle} style={mergedStyle}

View File

@ -1,6 +1,6 @@
{ {
"name": "ant-design-vue", "name": "ant-design-vue",
"version": "4.2.6", "version": "4.2.3",
"title": "Ant Design Vue", "title": "Ant Design Vue",
"description": "An enterprise-class UI design language and Vue-based implementation", "description": "An enterprise-class UI design language and Vue-based implementation",
"keywords": [ "keywords": [
@ -36,7 +36,7 @@
"precompile": "npm run version & npm run collect-token-statistic & npm run token-meta", "precompile": "npm run version & npm run collect-token-statistic & npm run token-meta",
"pretest": "npm run version", "pretest": "npm run version",
"predist": "npm run version", "predist": "npm run version",
"prebuild": "npm run version & npm run routes & npm run collect-token-statistic & npm run token-meta", "presite": "npm run version & npm run routes & npm run collect-token-statistic & npm run token-meta",
"dev": "npm run routes && vite serve site", "dev": "npm run routes && vite serve site",
"fast-dev": "npm run routes && vite serve site", "fast-dev": "npm run routes && vite serve site",
"test": "cross-env NODE_ENV=test jest --config .jest.js", "test": "cross-env NODE_ENV=test jest --config .jest.js",
@ -60,7 +60,8 @@
"routes": "node site/scripts/genrateRoutes.js", "routes": "node site/scripts/genrateRoutes.js",
"tsc": "tsc --noEmit", "tsc": "tsc --noEmit",
"vue-tsc": "vue-tsc --noEmit", "vue-tsc": "vue-tsc --noEmit",
"build": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site --base=/", "site": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site --base=https://next.antdv.com/",
"build-site": "npm run presite && node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build site",
"pub:site": "npm run site && node site/scripts/pushToOSS.js", "pub:site": "npm run site && node site/scripts/pushToOSS.js",
"prepare": "husky install", "prepare": "husky install",
"version": "node ./scripts/generate-version", "version": "node ./scripts/generate-version",
@ -128,7 +129,6 @@
"@vitejs/plugin-vue": "^3.0.0", "@vitejs/plugin-vue": "^3.0.0",
"@vitejs/plugin-vue-jsx": "^2.0.0", "@vitejs/plugin-vue-jsx": "^2.0.0",
"@vue/babel-plugin-jsx": "^1.0.0", "@vue/babel-plugin-jsx": "^1.0.0",
"@vue/cli-plugin-eslint": "^5.0.0",
"@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^11.0.0", "@vue/eslint-config-typescript": "^11.0.0",
"@vue/test-utils": "^2.0.2", "@vue/test-utils": "^2.0.2",
@ -148,6 +148,7 @@
"babel-plugin-transform-require-context": "^0.1.1", "babel-plugin-transform-require-context": "^0.1.1",
"case-sensitive-paths-webpack-plugin": "^2.1.2", "case-sensitive-paths-webpack-plugin": "^2.1.2",
"chalk": "^4.1.1", "chalk": "^4.1.1",
"cheerio": "^1.0.0-rc.2",
"codecov": "^3.0.0", "codecov": "^3.0.0",
"codesandbox": "^2.2.3", "codesandbox": "^2.2.3",
"colorful": "^2.1.0", "colorful": "^2.1.0",
@ -172,7 +173,7 @@
"eslint-plugin-jest": "^26.0.0", "eslint-plugin-jest": "^26.0.0",
"eslint-plugin-markdown": "^2.0.0", "eslint-plugin-markdown": "^2.0.0",
"eslint-plugin-no-explicit-type-exports": "^0.12.0", "eslint-plugin-no-explicit-type-exports": "^0.12.0",
"eslint-plugin-prettier": "^3.1.0", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.17.0", "eslint-plugin-vue": "^9.17.0",
"fast-glob": "^3.2.7", "fast-glob": "^3.2.7",
"fetch-jsonp": "^1.1.3", "fetch-jsonp": "^1.1.3",
@ -217,8 +218,8 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"postcss": "^8.2.12", "postcss": "^8.2.12",
"postcss-loader": "^6.0.0", "postcss-loader": "^6.0.0",
"prettier": "^2.2.0", "prettier": "^3.3.0",
"pretty-quick": "^3.0.0", "pretty-quick": "^4.0.0",
"prismjs": "^1.23.0", "prismjs": "^1.23.0",
"progress": "^2.0.3", "progress": "^2.0.3",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
@ -261,7 +262,7 @@
"vue-i18n": "^9.1.7", "vue-i18n": "^9.1.7",
"vue-infinite-scroll": "^2.0.2", "vue-infinite-scroll": "^2.0.2",
"vue-loader": "^17.0.0", "vue-loader": "^17.0.0",
"vue-request": "^2.0.4", "vue-request": "^1.0.2",
"vue-router": "^4.0.0", "vue-router": "^4.0.0",
"vue-style-loader": "^4.1.2", "vue-style-loader": "^4.1.2",
"vue-tsc": "^1.0.6", "vue-tsc": "^1.0.6",

View File

@ -12,7 +12,7 @@
content="An enterprise-class UI components based on Ant Design and Vue" content="An enterprise-class UI components based on Ant Design and Vue"
/> />
<title>Ant Design Vue</title> <title>Ant Design Vue</title>
<link rel="icon" type="image/x-icon" href="//www.antdv.com/favicon.ico" /> <link rel="icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
<style id="nprogress-style"> <style id="nprogress-style">
#page-404 { #page-404 {
background-image: url('https://os.alipayobjects.com/rmsportal/NOAjOBbnYCrNzrW.jpg'); background-image: url('https://os.alipayobjects.com/rmsportal/NOAjOBbnYCrNzrW.jpg');

View File

@ -16,7 +16,7 @@
name="keywords" name="keywords"
content="ant design vue,ant-design-vue,ant-design-vue admin,ant design pro,vue ant design,vue ant design pro,vue ant design admin,ant design vue官网,ant design vue中文文档,ant design vue文档" content="ant design vue,ant-design-vue,ant-design-vue admin,ant design pro,vue ant design,vue ant design pro,vue ant design admin,ant design vue官网,ant design vue中文文档,ant design vue文档"
/> />
<link rel="shortcut icon" type="image/x-icon" href="//www.antdv.com/favicon.ico" /> <link rel="shortcut icon" type="image/x-icon" href="//aliyuncdn.antdv.com/favicon.ico" />
<style id="nprogress-style"> <style id="nprogress-style">
#nprogress { #nprogress {
display: none; display: none;
@ -45,7 +45,7 @@
<body> <body>
<div id="app"></div> <div id="app"></div>
<script src="https://www.antdv.com/docsearch.min_2.6.3.js"></script> <script src="https://aliyuncdn.antdv.com/common/docsearch.min_2.6.3.js"></script>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics --> <!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-151755889-1"></script> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-151755889-1"></script>
@ -59,5 +59,23 @@
gtag('config', 'UA-151755889-1'); gtag('config', 'UA-151755889-1');
</script> </script>
<script type="text/javascript" src="https://cdn.wwads.cn/js/makemoney.js" async></script> <script type="text/javascript" src="https://cdn.wwads.cn/js/makemoney.js" async></script>
<!-- <div
class="surveybyantdv"
data-sf-id="63ad5912f3e10066"
data-sf-mode="popover"
data-sf-button-color="#3a3939"
data-sf-text-color="#ffffff"
data-sf-button-radius="50"
data-sf-button-icon="form-outlined"
data-sf-default-open="false"
data-sf-allow-repeat-submit="true"
data-sf-close-after-submit="false"
data-sf-hide-after-submit="false"
data-sf-delay-visible="false"
data-sf-preload="true"
data-sf-width="368px"
data-sf-height="407px"
></div>
<script async src="https://aliyuncdn.antdv.com/form/static/embed/runtime.js"></script> -->
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

View File

@ -1,31 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="280" viewBox="0 0 1200 280">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0B1021" />
<stop offset="100%" stop-color="#182A4A" />
</linearGradient>
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
<circle cx="2" cy="2" r="2" fill="#7FB3FF" opacity="0.12"/>
</pattern>
</defs>
<!-- background -->
<rect width="1200" height="280" fill="url(#g)"/>
<rect width="1200" height="280" fill="url(#dots)"/>
<!-- decorative braces -->
<text x="80" y="140.0" text-anchor="start" font-size="140" font-family="monospace" fill="#5DF2A3" opacity="0.08">{</text>
<text x="1120" y="140.0" text-anchor="end" font-size="140" font-family="monospace" fill="#5DF2A3" opacity="0.08">}</text>
<!-- brand name -->
<text x="600.0" y="120.0" text-anchor="middle"
font-family="Inter, system-ui" font-weight="800" font-size="72" fill="#5DF2A3">Mentorbook.AI</text>
<!-- main slogan -->
<text x="600.0" y="175.0" text-anchor="middle"
font-family="Inter, system-ui" font-weight="700" font-size="42" fill="#EAF2FF">Your AI Mentor, Your Learning Journey</text>
<!-- value props -->
<text x="600.0" y="225.0" text-anchor="middle"
font-family="Inter, system-ui" font-weight="500" font-size="24" fill="#7FB3FF">✨ Personalized Courses · Instant Feedback · 100+ Subjects</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,33 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="280" viewBox="0 0 1200 280">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0B1021" />
<stop offset="100%" stop-color="#182A4A" />
</linearGradient>
<pattern id="dots" width="28" height="28" patternUnits="userSpaceOnUse">
<circle cx="2" cy="2" r="2" fill="#7FB3FF" opacity="0.12" />
</pattern>
</defs>
<!-- background -->
<rect width="1200" height="280" fill="url(#g)" />
<rect width="1200" height="280" fill="url(#dots)" />
<!-- decorative braces -->
<text x="80" y="140.0" text-anchor="start" font-size="140" font-family="monospace" fill="#5DF2A3"
opacity="0.08">{</text>
<text x="1120" y="140.0" text-anchor="end" font-size="140" font-family="monospace" fill="#5DF2A3"
opacity="0.08">}</text>
<!-- brand name -->
<text x="600.0" y="120.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="800" font-size="72"
fill="#5DF2A3">Mentorbook.AI</text>
<!-- main slogan -->
<text x="600.0" y="175.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="700" font-size="42"
fill="#EAF2FF">你的 AI 导师,你的学习助手</text>
<!-- value props -->
<text x="600.0" y="225.0" text-anchor="middle" font-family="Inter, system-ui" font-weight="500" font-size="24"
fill="#7FB3FF">✨ 个性化课程 · 即时反馈 · 100+ 学科领域</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -10,6 +10,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, provide, watch, ref } from 'vue'; import { computed, defineComponent, provide, watch, ref } from 'vue';
import type { Ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import useMediaQuery from './hooks/useMediaQuery'; import useMediaQuery from './hooks/useMediaQuery';
@ -20,11 +21,16 @@ import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
import { theme as antdTheme } from 'ant-design-vue'; import { theme as antdTheme } from 'ant-design-vue';
import SiteToken from './SiteToken.vue'; import SiteToken from './SiteToken.vue';
import type { GlobalConfig } from './type';
function isZhCN(name: string) { function isZhCN(name: string) {
return /-cn\/?$/.test(name); return /-cn\/?$/.test(name);
} }
export interface GlobalConfig {
isMobile: Ref<boolean>;
lang: Ref<'zh-CN' | 'en-US'>;
isZhCN: Ref<boolean>;
responsive: Ref<null | 'narrow' | 'crowded'>;
blocked: Ref<boolean>;
}
export type ThemeName = '' | 'light' | 'dark' | 'compact'; export type ThemeName = '' | 'light' | 'dark' | 'compact';
const getAlgorithm = (themes: ThemeName[] = []) => const getAlgorithm = (themes: ThemeName[] = []) =>
themes themes

View File

@ -103,7 +103,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../type'; import type { GlobalConfig } from '../App.vue';
import { GLOBAL_CONFIG } from '../SymbolKey'; import { GLOBAL_CONFIG } from '../SymbolKey';
import { computed, defineComponent, inject, onMounted, ref } from 'vue'; import { computed, defineComponent, inject, onMounted, ref } from 'vue';
import { CheckOutlined, SnippetsOutlined, CodeSandboxOutlined } from '@ant-design/icons-vue'; import { CheckOutlined, SnippetsOutlined, CodeSandboxOutlined } from '@ant-design/icons-vue';

View File

@ -2,11 +2,10 @@ import type { InputProps } from 'ant-design-vue';
import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue'; import { ConfigProvider, Input, InputNumber, Select, theme } from 'ant-design-vue';
import classNames from 'ant-design-vue/es/_util/classNames'; import classNames from 'ant-design-vue/es/_util/classNames';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent, watchEffect, computed, toRefs, ref } from 'vue'; import { defineComponent, watchEffect, watch, computed, toRefs, ref } from 'vue';
import { HexColorPicker, RgbaColorPicker } from '../vue-colorful'; import { HexColorPicker, RgbaColorPicker } from '../vue-colorful';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import makeStyle from './utils/makeStyle'; import makeStyle from './utils/makeStyle';
import type { ValueType } from 'ant-design-vue/es/input-number/src/utils/MiniDecimal';
const { useToken } = theme; const { useToken } = theme;
@ -169,42 +168,24 @@ const RgbColorInput = defineComponent({
setup(props) { setup(props) {
const { value, alpha } = toRefs(props); const { value, alpha } = toRefs(props);
const handleChange = (val: ValueType, key: 'r' | 'g' | 'b' | 'a') => { watch(value, val => {
value.value[key] = val; props.onChange(val);
props.onChange(value.value); });
};
return () => { return () => {
return ( return (
<div class="color-panel-rgba-input"> <div class="color-panel-rgba-input">
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}> <ConfigProvider theme={{ components: { InputNumber: { handleWidth: 12 } } }}>
<div class="color-panel-rgba-input-part"> <div class="color-panel-rgba-input-part">
<InputNumber <InputNumber min={0} max={255} size="small" v-model={[value.value.r, 'value']} />
min={0}
max={255}
size="small"
value={value.value.r}
onChange={val => handleChange(val, 'r')}
/>
<div class="color-panel-mode-title">R</div> <div class="color-panel-mode-title">R</div>
</div> </div>
<div class="color-panel-rgba-input-part"> <div class="color-panel-rgba-input-part">
<InputNumber <InputNumber min={0} max={255} size="small" v-model={[value.value.g, 'value']} />
min={0}
max={255}
size="small"
value={value.value.g}
onChange={val => handleChange(val, 'g')}
/>
<div class="color-panel-mode-title">G</div> <div class="color-panel-mode-title">G</div>
</div> </div>
<div class="color-panel-rgba-input-part"> <div class="color-panel-rgba-input-part">
<InputNumber <InputNumber min={0} max={255} size="small" v-model={[value.value.b, 'value']} />
min={0}
max={255}
size="small"
value={value.value.b}
onChange={val => handleChange(val, 'b')}
/>
<div class="color-panel-mode-title">B</div> <div class="color-panel-mode-title">B</div>
</div> </div>
{alpha.value && ( {alpha.value && (
@ -214,8 +195,7 @@ const RgbColorInput = defineComponent({
max={1} max={1}
step={0.01} step={0.01}
size="small" size="small"
value={value.value.a} v-model={[value.value.a, 'value']}
onChange={val => handleChange(val, 'a')}
/> />
<div class="color-panel-mode-title">A</div> <div class="color-panel-mode-title">A</div>
</div> </div>

View File

@ -0,0 +1,45 @@
<template>
<div v-show="visible" id="geektime">
<a
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
target="_blank"
>
<img width="150" alt="Vue 实战教程" src="https://aliyuncdn.antdv.com/geektime-vue.jpeg" />
</a>
<div class="close" @click="visible = false">
<close-outlined />
</div>
</div>
</template>
<script>
import { CloseOutlined } from '@ant-design/icons-vue';
export default {
components: {
CloseOutlined,
},
props: ['isMobile'],
data() {
return {
visible: true,
};
},
};
</script>
<style lang="less" scoped>
#geektime {
position: fixed;
bottom: 10px;
right: 10px;
.close {
position: absolute;
text-align: center;
top: -8px;
right: -8px;
font-size: 16px;
padding: 15px;
color: #6e3041;
}
}
</style>

View File

@ -0,0 +1,64 @@
<template>
<div
v-if="isEffective(effectiveTime)"
id="geektime-ads"
:class="isMobile ? 'geektime-ads-mobile' : ''"
>
<a
href="https://time.geekbang.org/column/intro/154?utm_term=zeusGZFFE&utm_source=app&utm_medium=tangjinzhou"
target="_blank"
>
<img height="100" alt="重学前端" src="https://aliyuncdn.antdv.com/chongxueqianduan.jpg" />
</a>
</div>
</template>
<script lang="ts">
import dayjs from 'dayjs';
import isBetween from 'dayjs/plugin/isBetween';
import { defineComponent } from 'vue';
dayjs.extend(isBetween);
export default defineComponent({
props: {
isMobile: Boolean,
},
setup() {
return {
visible: true,
effectiveTime: {
start: '2019-08-05 17:00:00',
end: '2019-09-05 17:00:00',
},
isEffective({ start, end }) {
return dayjs().isBetween(start, end);
},
};
},
});
</script>
<style lang="less" scoped>
#geektime-ads {
width: 266px;
position: fixed;
left: 0;
bottom: 0px;
padding: 0;
overflow: hidden;
z-index: 9;
background-color: #fff;
border-radius: 3px;
font-size: 13px;
background: #f5f5f5;
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
}
#geektime-ads.geektime-ads-mobile {
width: 100%;
position: relative;
right: 0;
bottom: 0;
padding: 0;
margin-bottom: 15px;
}
</style>

View File

@ -26,7 +26,20 @@ export default {
isEffective, isEffective,
visible: true, visible: true,
v: dayjs().date(), v: dayjs().date(),
ads: [], ads: [
{
alt: 'geektime',
img: 'https://aliyuncdn.antdv.com/geektime-web-small.jpg',
href: 'http://gk.link/a/10l8O',
visible: isEffective('2020-09-03 10:00:00', '2020-10-04 10:00:00'),
},
{
alt: 'powerproject',
img: 'https://aliyuncdn.antdv.com/powerproject.jpeg?v=20200327',
href: 'http://www.powerproject.com.cn',
visible: isEffective('2020-03-27 17:00:00', '2020-09-28 17:00:00'),
},
],
}; };
}, },
}; };

View File

@ -10,6 +10,11 @@
<img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" /> <img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" />
</a> </a>
</li> --> </li> -->
<li v-if="isCN && isEffective(effectiveTime.kkb)" class="sponsorsItem">
<a href="https://datayi.cn/w/Y9J3M2vR" target="_blank">
<img height="66" src="https://aliyuncdn.antdv.com/kaikeba_ssr.jpeg" alt="kaikeba" />
</a>
</li>
<li class="sponsorsItem" style="padding: 10px 0"> <li class="sponsorsItem" style="padding: 10px 0">
<a-button type="primary" ghost style="font-size: 12px" @click="handleClick"> <a-button type="primary" ghost style="font-size: 12px" @click="handleClick">
{{ isCN ? '成为赞助商' : 'Become a Sponsor' }} {{ isCN ? '成为赞助商' : 'Become a Sponsor' }}

View File

@ -1,241 +1,64 @@
<template> <template>
<div class="top-rice"> <div v-if="show">
<!-- Mentorbook banner --> <template v-if="ads.length">
<div v-if="showMentorbook" class="mentorbook-banner"> <a-carousel autoplay>
<a href="https://mentorbook.ai/" target="_blank" class="banner-content"> <template v-for="ad in ads" :key="ad.href">
<div class="brand-name">Mentorbook.AI</div> <a :href="ad.href" target="_blank">
<div class="main-slogan"> <img style="width: 100%; max-width: 1200px" :alt="ad.alt || ''" :src="ad.img" />
{{ isCN ? '你的 AI 导师,你的学习助手' : 'Your AI Mentor, Your Learning Journey' }}
</div>
<div class="value-props">
{{
isCN
? '✨ 个性化课程 · 即时反馈 · 100+ 学科领域'
: '✨ Personalized Courses · Instant Feedback · 100+ Subjects'
}}
</div>
</a> </a>
<a href="https://mentorbook.ai/" target="_blank" class="start-button"> </template>
{{ isCN ? '免费开始' : 'Get Started Free' }} </a-carousel>
</a> </template>
</div> <template v-else-if="showGoogleAd">
<!-- <template v-if="isCN">
<WWAds :key="`WWAds_${$route.path}`" />
</template> -->
<google-ads-top :key="`GoogleAdsTop_${$route.path}`" />
</template>
</div> </div>
</template> </template>
<script> <script>
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import isBetween from 'dayjs/plugin/isBetween'; import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(isBetween); dayjs.extend(isBetween);
import GoogleAdsTop from './GoogleAdsTop.vue';
// import WWAds from './WWAds.vue'; // import WWAds from './WWAds.vue';
const isEffective = (start, end) => { const isEffective = (start, end) => {
return dayjs().isBetween(start, end); return dayjs().isBetween(start, end);
}; };
export default { export default {
components: { components: {
GoogleAdsTop,
// WWAds, // WWAds,
}, },
props: ['isCN', 'isMobile'], props: ['isCN', 'isMobile'],
data() { data() {
return { return {
show: true, show: true,
showMentorbook: true, showGoogleAd: location.host.indexOf('antdv.com') > -1,
cnAds: [ cnAds: [
{ {
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`, img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`,
href: 'https://yidengfe.com/launches/01/yd.html', href: 'https://yidengfe.com/launches/01/yd.html',
visible: true, visible: isEffective('2020-09-11 17:00:00', '2021-03-11 17:00:00'),
}, },
].filter(ad => ad.visible), ].filter(ad => ad.visible),
enAds: [ enAds: [
{ {
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`, img: 'https://aliyuncdn.antdv.com/TheBigRichGroup.png',
href: 'https://yidengfe.com/launches/01/yd.html', href: 'https://thebigrichgroup.com/',
visible: true, visible: isEffective('2020-09-18 17:00:00', '2021-07-09 17:00:00'),
}, },
].filter(ad => ad.visible), ].filter(ad => ad.visible),
}; };
}, },
computed: { computed: {
otherAds() { ads() {
return this.isCN ? this.cnAds : this.enAds; return this.isCN ? this.cnAds : this.enAds;
}, },
}, },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped></style>
.top-rice {
width: 100%;
margin-bottom: 16px;
.mentorbook-banner {
display: flex;
width: 100%;
background: linear-gradient(135deg, #0b1021 0%, #182a4a 100%);
position: relative;
overflow: hidden;
padding: 0 16px;
height: 48px;
box-sizing: border-box;
align-items: center;
justify-content: space-between;
// Dots pattern background
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: radial-gradient(circle, rgba(127, 179, 255, 0.12) 2px, transparent 2px);
background-size: 28px 28px;
background-position: 0 0;
pointer-events: none;
z-index: 0;
}
// Left brace
&::after {
content: '{';
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 32px;
font-family: monospace;
color: #5df2a3;
opacity: 0.08;
pointer-events: none;
z-index: 0;
}
.banner-content {
position: relative;
z-index: 1;
flex: 1;
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 12px;
text-decoration: none;
transition: opacity 0.3s;
&:hover {
opacity: 0.9;
}
}
.start-button {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
height: 32px;
padding: 0 16px;
background: #5df2a3;
color: #0b1021;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-weight: 600;
font-size: 14px;
text-decoration: none;
border-radius: 6px;
white-space: nowrap;
transition: all 0.3s;
margin-left: 16px;
&:hover {
background: #4dd893;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(93, 242, 163, 0.3);
}
&:active {
transform: translateY(0);
}
@media (max-width: 768px) {
font-size: 12px;
padding: 0 12px;
height: 28px;
}
@media (max-width: 480px) {
font-size: 11px;
padding: 0 10px;
height: 26px;
margin-left: 8px;
}
}
.brand-name {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-weight: 800;
font-size: 20px;
color: #5df2a3;
line-height: 48px;
white-space: nowrap;
@media (max-width: 768px) {
font-size: 18px;
}
@media (max-width: 480px) {
font-size: 16px;
}
}
.main-slogan {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-weight: 600;
font-size: 16px;
color: #eaf2ff;
line-height: 48px;
white-space: nowrap;
@media (max-width: 768px) {
font-size: 14px;
}
@media (max-width: 480px) {
display: none;
}
}
.value-props {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-weight: 500;
font-size: 14px;
color: #7fb3ff;
line-height: 48px;
white-space: nowrap;
@media (max-width: 1024px) {
display: none;
}
}
}
.ad-link {
display: block;
width: 100%;
text-decoration: none;
transition: opacity 0.3s;
margin-top: 16px;
&:hover {
opacity: 0.9;
}
}
.ad-image {
width: 100%;
max-width: 1200px;
height: auto;
display: block;
margin: 0 auto;
}
}
</style>

View File

@ -1,10 +1,25 @@
<template> <template>
<div class="container"> <div class="container">
<a-carousel autoplay> <a-carousel autoplay>
<a style="display: inline-block" href="https://www.surelyvue.com/" target="_blank"> <a style="display: inline-block" href="https://form.antdv.com/" target="_blank">
<div :class="cls"> <div :class="cls">
<div class="logo"> <div class="logo">
<img height="80" src="https://www.surelyvue.com/surely-vue-logo.png" alt="" /> <img height="80" src="https://aliyuncdn.antdv.com/form/static/logo-blue.png" alt="" />
</div>
<div class="desc">
<!-- <div class="title">Surely Form</div> -->
<div class="sub-title">
<strong>雪梨表单为您定制</strong>
<br />
专属的调研投票NPS报名等系统
</div>
</div>
</div>
</a>
<a style="display: inline-block" href="https://www.surely.cool/" target="_blank">
<div :class="cls">
<div class="logo">
<img height="80" src="https://www.surely.cool/surely-vue-logo.png" alt="" />
</div> </div>
<div class="desc"> <div class="desc">
<div class="title">Surely Table</div> <div class="title">Surely Table</div>

View File

@ -60,9 +60,12 @@
</div> </div>
</div> </div>
</a-col> </a-col>
<!-- <a-col :md="6" :sm="24" :xs="24"> <a-col :md="6" :sm="24" :xs="24">
<div class="footer-center"> <div class="footer-center">
<h2>{{ isCN ? '友情链接' : 'Links' }}</h2> <h2>{{ isCN ? '友情链接' : 'Links' }}</h2>
<div v-if="showJeecg">
<a href="http://www.jeecg.com/" target="_blank">Jeecg</a>
</div>
<div> <div>
<a href="https://cn.vuejs.org/" target="_blank">Vue</a> <a href="https://cn.vuejs.org/" target="_blank">Vue</a>
</div> </div>
@ -76,8 +79,8 @@
<a href="https://antdv.formilyjs.org/" target="_blank">@formily/antdv</a> <a href="https://antdv.formilyjs.org/" target="_blank">@formily/antdv</a>
</div> </div>
</div> </div>
</a-col> --> </a-col>
<a-col :md="12" :sm="24" :xs="24"> <a-col :md="6" :sm="24" :xs="24">
<div class="footer-center"> <div class="footer-center">
<h2> <h2>
<img <img
@ -85,17 +88,28 @@
class="title-icon" class="title-icon"
src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg" src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg"
/> />
<span>{{ isCN ? '友情链接' : 'Links' }}</span> <span>{{ isCN ? '更多产品' : 'More Products' }}</span>
</h2> </h2>
<div> <div>
<a href="https://www.demoget.com?atp=tangjinzhou" target="_blank">DemoGet</a> <a href="https://antv.alipay.com/" rel="noopener noreferrer" target="_blank">AntV</a>
<span>-</span> <span>-</span>
<span>{{ isCN ? '好看好用的录屏工具' : 'Beautiful Screen Recordings' }}</span> <span>{{ isCN ? '数据可视化' : 'Data Visualization' }}</span>
</div>
<div>
<a href="https://eggjs.org/" rel="noopener noreferrer" target="_blank">Egg</a>
<span>-</span>
<span>{{ isCN ? '企业级 Node 开发框架' : 'Enterprise Node Framework' }}</span>
</div> </div>
</div> </div>
</a-col> </a-col>
</a-row> </a-row>
</div> </div>
<div style="padding: 10px 144px">
备案号
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">浙ICP备19034671号</a>
&nbsp;&nbsp;&nbsp; 增值电信业务经营许可证
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">浙B2-20220161</a>
</div>
</footer> </footer>
</template> </template>
<script> <script>

View File

@ -15,7 +15,7 @@
<a-menu-item-group v-if="isZhCN" key="advanced" title="高级组件"> <a-menu-item-group v-if="isZhCN" key="advanced" title="高级组件">
<a-menu-item key="surely-table"> <a-menu-item key="surely-table">
<a <a
href="https://www.surelyvue.com" href="https://www.surely.cool"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
style="position: relative" style="position: relative"
@ -23,6 +23,17 @@
Surely Table Surely Table
</a> </a>
</a-menu-item> </a-menu-item>
<a-menu-item key="surely-form">
<a
href="https://form.antdv.com"
target="_blank"
rel="noopener noreferrer"
style="position: relative"
>
Surely Form
<a-badge color="red" style="position: absolute; top: -18px; right: -15px" />
</a>
</a-menu-item>
</a-menu-item-group> </a-menu-item-group>
<template v-for="m in menus"> <template v-for="m in menus">
<template v-if="m.children"> <template v-if="m.children">

View File

@ -23,6 +23,19 @@
<a-menu-item key="awesome"> <a-menu-item key="awesome">
<a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">Awesome</a> <a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">Awesome</a>
</a-menu-item> </a-menu-item>
<a-menu-item key="wechat">
<a-popover placement="right">
<a>{{ isZhCN ? '微信' : 'WeChat' }}</a>
<template #content>
<img
width="160"
height="160"
alt="wechat"
src="https://aliyuncdn.antdv.com/wechat.jpeg"
/>
</template>
</a-popover>
</a-menu-item>
<a-menu-item key="qq1"> <a-menu-item key="qq1">
<a>QQ 1(217490093) 已满</a> <a>QQ 1(217490093) 已满</a>
</a-menu-item> </a-menu-item>
@ -37,7 +50,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject } from 'vue'; import { computed, defineComponent, inject } from 'vue';
import type { GlobalConfig } from '../../type'; import type { GlobalConfig } from '../../App.vue';
import { GLOBAL_CONFIG } from '../../SymbolKey'; import { GLOBAL_CONFIG } from '../../SymbolKey';
import { getLocalizedPathname } from '../../utils/util'; import { getLocalizedPathname } from '../../utils/util';

View File

@ -8,7 +8,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../../type'; import type { GlobalConfig } from '../../App.vue';
import { GLOBAL_CONFIG } from '../../SymbolKey'; import { GLOBAL_CONFIG } from '../../SymbolKey';
import { defineComponent, inject } from 'vue'; import { defineComponent, inject } from 'vue';
import logo from '../../assets/logo.svg'; import logo from '../../assets/logo.svg';

View File

@ -18,7 +18,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject } from 'vue'; import { computed, defineComponent, inject } from 'vue';
import { DownOutlined } from '@ant-design/icons-vue'; import { DownOutlined } from '@ant-design/icons-vue';
import type { GlobalConfig } from '../../type'; import type { GlobalConfig } from '../../App.vue';
import { GLOBAL_CONFIG } from '../../SymbolKey'; import { GLOBAL_CONFIG } from '../../SymbolKey';
import { getLocalizedPathname } from '../../utils/util'; import { getLocalizedPathname } from '../../utils/util';
import Ecosystem from './Ecosystem.vue'; import Ecosystem from './Ecosystem.vue';

View File

@ -25,7 +25,7 @@
</template> </template>
<a-menu-item key="surely-table"> <a-menu-item key="surely-table">
<a <a
href="https://www.surelyvue.com" href="https://www.surely.cool"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
style="position: relative" style="position: relative"
@ -33,6 +33,17 @@
Surely Table Surely Table
</a> </a>
</a-menu-item> </a-menu-item>
<a-menu-item key="surely-form">
<a
href="https://form.antdv.com"
target="_blank"
rel="noopener noreferrer"
style="position: relative"
>
Surely Form
<a-badge color="red" style="position: absolute; top: -18px; right: -15px" />
</a>
</a-menu-item>
</a-sub-menu> </a-sub-menu>
<a-menu-item key="store"> <a-menu-item key="store">
<a <a
@ -73,7 +84,7 @@
</a-menu> </a-menu>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../../type'; import type { GlobalConfig } from '../../App.vue';
import { GLOBAL_CONFIG } from '../../SymbolKey'; import { GLOBAL_CONFIG } from '../../SymbolKey';
import { getLocalizedPathname } from '../../utils/util'; import { getLocalizedPathname } from '../../utils/util';
import { computed, defineComponent, inject, ref, watch } from 'vue'; import { computed, defineComponent, inject, ref, watch } from 'vue';

View File

@ -1,5 +1,25 @@
<template> <template>
<header id="header" :class="headerClassName"> <header id="header" :class="headerClassName">
<!-- <div v-if="visibleAdblockBanner" class="adblock-banner">
<template v-if="isZhCN">
我们检测到你可能使用了 AdBlock Adblock
Plus它会影响到正常功能的使用如复制展开代码等
<br />
你可以将 Ant Design Vue 加入白名单以便我们更好地提供服务
</template>
<template v-else>
We have detected that you may use AdBlock or Adblock Plus, which will affect the use of
normal functions (such as copying, expanding code, etc.)
<br />
You can add Ant Design Vue to the whitelist so that we can provide better services.
</template>
<CloseOutlined class="close-icon" @click="visibleAdblockBanner = false" />
</div> -->
<div class="alert-banner">
Surely Form AI 助手内测开放申请 &nbsp;&nbsp;
<a target="_blank" href="https://form.antdv.com">立即申请</a>
</div>
<a-row :style="{ flexFlow: 'nowrap', height: 64, position: 'relative' }"> <a-row :style="{ flexFlow: 'nowrap', height: 64, position: 'relative' }">
<a-col v-bind="colProps[0]"> <a-col v-bind="colProps[0]">
<Logo /> <Logo />
@ -37,10 +57,15 @@
<strong>Ant Design Vue 4</strong> <strong>Ant Design Vue 4</strong>
五大新组件全新 Design Token 五大新组件全新 Design Token
</li> </li>
<li class="alert-list-item">
<strong>Surely Form</strong>
全新主题编辑 AI 问卷开放内测申请
<a target="_blank" href="https://form.antdv.com">立即体验</a>
</li>
<li class="alert-list-item"> <li class="alert-list-item">
<strong>Surely Table</strong> <strong>Surely Table</strong>
支持高性能编辑模式了 支持高性能编辑模式了
<a target="_blank" href="https://www.surelyvue.com/">立即体验</a> <a target="_blank" href="https://www.surely.cool/">立即体验</a>
</li> </li>
<li class="alert-list-item"> <li class="alert-list-item">
<strong>Admin Pro</strong> <strong>Admin Pro</strong>
@ -52,7 +77,7 @@
</header> </header>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../../type'; import type { GlobalConfig } from '../../App.vue';
import { GLOBAL_CONFIG } from '../../SymbolKey'; import { GLOBAL_CONFIG } from '../../SymbolKey';
import { getLocalizedPathname } from '../../utils/util'; import { getLocalizedPathname } from '../../utils/util';
import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue'; import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue';
@ -61,6 +86,7 @@ import Logo from './Logo.vue';
import Menu from './Menu.vue'; import Menu from './Menu.vue';
import { UnorderedListOutlined } from '@ant-design/icons-vue'; import { UnorderedListOutlined } from '@ant-design/icons-vue';
import SearchBox from './SearchBox.vue'; import SearchBox from './SearchBox.vue';
import { version } from 'ant-design-vue';
export default defineComponent({ export default defineComponent({
components: { components: {
Logo, Logo,
@ -131,13 +157,13 @@ export default defineComponent({
watch(globalConfig?.blocked, val => { watch(globalConfig?.blocked, val => {
visibleAdblockBanner.value = val; visibleAdblockBanner.value = val;
}); });
// const alertKey = 'ant-design-vue-4-alert'; const alertKey = 'ant-design-vue-4-alert';
const visibleAlertBanner = ref(false); const visibleAlertBanner = ref(!localStorage.getItem(alertKey));
// watch(visibleAlertBanner, () => { watch(visibleAlertBanner, () => {
// if (!visibleAlertBanner.value) { if (!visibleAlertBanner.value) {
// localStorage.setItem(alertKey, version); localStorage.setItem(alertKey, version);
// } }
// }); });
return { return {
isZhCN: globalConfig.isZhCN, isZhCN: globalConfig.isZhCN,
isMobile: globalConfig.isMobile, isMobile: globalConfig.isMobile,

View File

@ -1,5 +1,4 @@
<template> <template>
<TopAd :is-c-n="isZhCN" />
<Header /> <Header />
<div v-if="headers.length" class="toc-affix" :style="y > 102 ? 'position:fixed; top: 16px;' : ''"> <div v-if="headers.length" class="toc-affix" :style="y > 102 ? 'position:fixed; top: 16px;' : ''">
<a-anchor style="width: 160px" :items="headers"> <a-anchor style="width: 160px" :items="headers">
@ -44,6 +43,8 @@
</template> </template>
<a-col :xxxl="20" :xxl="20" :xl="19" :lg="18" :md="18" :sm="24" :xs="24"> <a-col :xxxl="20" :xxl="20" :xl="19" :lg="18" :md="18" :sm="24" :xs="24">
<section :class="mainContainerClass"> <section :class="mainContainerClass">
<WWAdsVue v-if="isZhCN" />
<TopAd v-else />
<Demo v-if="isDemo" :page-data="pageData" :is-zh-c-n="isZhCN"> <Demo v-if="isDemo" :page-data="pageData" :is-zh-c-n="isZhCN">
<component :is="matchCom" /> <component :is="matchCom" />
</Demo> </Demo>
@ -84,6 +85,22 @@
</template> </template>
</a-float-button> </a-float-button>
</a-float-button-group> </a-float-button-group>
<!-- <div class="fixed-widgets" :style="isZhCN ? { bottom: '175px' } : {}">
<a-dropdown placement="top">
<template #overlay>
<a-menu
:selected-keys="[themeMode.theme.value]"
@click="({ key }) => themeMode.changeTheme(key)"
>
<a-menu-item key="default">{{ $t('app.theme.switch.default') }}</a-menu-item>
<a-menu-item key="dark">{{ $t('app.theme.switch.dark') }}</a-menu-item>
</a-menu>
</template>
<a-avatar class="fixed-widgets-avatar" :size="44">
<template #icon><ThemeIcon /></template>
</a-avatar>
</a-dropdown>
</div> -->
<PrevAndNext :menus="menus" :current-menu-index="currentMenuIndex" :is-zh-c-n="isZhCN" /> <PrevAndNext :menus="menus" :current-menu-index="currentMenuIndex" :is-zh-c-n="isZhCN" />
<Footer /> <Footer />
</a-col> </a-col>
@ -91,6 +108,7 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../App.vue';
import { GLOBAL_CONFIG } from '../SymbolKey'; import { GLOBAL_CONFIG } from '../SymbolKey';
import { defineComponent, inject, computed, ref, provide, watch } from 'vue'; import { defineComponent, inject, computed, ref, provide, watch } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
@ -111,7 +129,6 @@ import CompactIcon from './icons/Compact';
import surelyVueVue from '../components/surelyVue.vue'; import surelyVueVue from '../components/surelyVue.vue';
import WWAdsVue from '../components/rice/WWAds.vue'; import WWAdsVue from '../components/rice/WWAds.vue';
import { useWindowScroll } from '@vueuse/core'; import { useWindowScroll } from '@vueuse/core';
import type { GlobalConfig } from '../type';
const rControl = /[\u0000-\u001f]/g; const rControl = /[\u0000-\u001f]/g;
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g; const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
@ -210,25 +227,25 @@ export default defineComponent({
{ {
title: '大数据渲染', title: '大数据渲染',
enTitle: 'Virtualized Table', enTitle: 'Virtualized Table',
href: 'https://surelyvue.com/doc/performance', href: 'https://surely.cool/doc/performance',
target: '_blank', target: '_blank',
}, },
{ {
title: '行拖拽排序', title: '行拖拽排序',
enTitle: 'Row Drag Sort', enTitle: 'Row Drag Sort',
href: 'https://surelyvue.com/doc/dragable#drag-row', href: 'https://surely.cool/doc/dragable#drag-row',
target: '_blank', target: '_blank',
}, },
{ {
title: '列拖拽排序', title: '列拖拽排序',
enTitle: 'Column Drag Sort', enTitle: 'Column Drag Sort',
href: 'https://surelyvue.com/doc/dragable#drag-column', href: 'https://surely.cool/doc/dragable#drag-column',
target: '_blank', target: '_blank',
}, },
{ {
title: '更多高性能示例', title: '更多高性能示例',
enTitle: 'More high-performance examples ', enTitle: 'More high-performance examples ',
href: 'https://surelyvue.com', href: 'https://surely.cool',
target: '_blank', target: '_blank',
}, },
], ],

View File

@ -2,6 +2,7 @@ html {
&.rtl { &.rtl {
direction: rtl; direction: rtl;
} }
scroll-behavior: smooth;
} }
body { body {

View File

@ -1,8 +0,0 @@
import type { Ref } from 'vue';
export interface GlobalConfig {
isMobile: Ref<boolean>;
lang: Ref<'zh-CN' | 'en-US'>;
isZhCN: Ref<boolean>;
responsive: Ref<null | 'narrow' | 'crowded'>;
blocked: Ref<boolean>;
}

View File

@ -74,7 +74,7 @@
</section> </section>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { GlobalConfig } from '../type'; import type { GlobalConfig } from '../App.vue';
import { computed, defineComponent, inject, onMounted, ref } from 'vue'; import { computed, defineComponent, inject, onMounted, ref } from 'vue';
import { SearchOutlined } from '@ant-design/icons-vue'; import { SearchOutlined } from '@ant-design/icons-vue';
import { GLOBAL_CONFIG } from '../SymbolKey'; import { GLOBAL_CONFIG } from '../SymbolKey';
@ -107,12 +107,24 @@ export default defineComponent({
cols: 1, cols: 1,
cover: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg', cover: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg',
coverDark: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg', coverDark: 'https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg',
path: 'https://surelyvue.com/', path: 'https://surely.cool/',
subtitle: '更强大的表格', subtitle: '更强大的表格',
title: 'Surely Table', title: 'Surely Table',
type: 'Advanced And Powerful', type: 'Advanced And Powerful',
target: '_blank', target: '_blank',
}, },
{
category: 'Components',
cols: 1,
cover: 'https://aliyuncdn.antdv.com/form/static/assets/landing-config.4f9d5425.png',
coverDark:
'https://aliyuncdn.antdv.com/form/static/assets/landing-config.4f9d5425.png',
path: 'https://form.antdv.com/',
subtitle: '在线表单',
title: 'Surely Form',
type: 'Advanced And Powerful',
target: '_blank',
},
], ],
enTitle: 'Advanced And Powerful', enTitle: 'Advanced And Powerful',
title: '更强大', title: '更强大',

View File

@ -5,7 +5,7 @@ Following the Ant Design specification, we developed a Vue UI library `antd` tha
<div class="pic-plus"> <div class="pic-plus">
<img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" /> <img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
<span>+</span> <span>+</span>
<img width="160" src="https://www.antdv.com/vue.png" /> <img width="160" src="https://aliyuncdn.antdv.com/vue.png" />
</div> </div>
<style> <style>

View File

@ -5,7 +5,7 @@
<div class="pic-plus"> <div class="pic-plus">
<img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" /> <img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
<span>+</span> <span>+</span>
<img width="160" src="https://www.antdv.com/vue.png" /> <img width="160" src="https://aliyuncdn.antdv.com/vue.png" />
</div> </div>
<style> <style>

View File

@ -8,6 +8,8 @@ We accept donations through these channels:
<div> <div>
<a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a> <a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a>
<br/>
<a href="https://aliyuncdn.antdv.com/alipay-and-wechat.png" target="_blank">Alipay or WeChat</a>
</div> </div>
## Recurring Pledges ## Recurring Pledges
@ -31,7 +33,7 @@ You can consult me by email [antdv@foxmail.com](antdv@foxmail.com).
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)] Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
<div> <div>
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a>

View File

@ -8,6 +8,8 @@ ant-design-vue 是采用 MIT 许可的开源项目,使用完全免费。 但
<div> <div>
<a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a> <a href="https://www.paypal.me/tangjinzhou" target="_blank">PayPal</a>
<br/>
<a href="https://aliyuncdn.antdv.com/alipay-and-wechat.png" target="_blank">支付宝或微信</a>
</div> </div>
## 购买贴纸 ## 购买贴纸
@ -35,7 +37,7 @@ ant-design-vue 是采用 MIT 许可的开源项目,使用完全免费。 但
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)] Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ant-design-vue#sponsor)]
<div> <div>
<a href="http://www.jeecg.com/" target="_blank"><img src="https://www.antdv.com/jeecg-logo.png" height="64"></a> <a href="http://www.jeecg.com/" target="_blank"><img src="https://aliyuncdn.antdv.com/jeecg-logo.png" height="64"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/sponsor/2/avatar.svg"></a>

View File

@ -1,18 +0,0 @@
{
"name": "antdv-v4",
"compatibility_date": "2025-09-18",
"assets": {
"directory": "./site/dist",
"not_found_handling": "single-page-application"
},
"routes": [
{
"pattern": "antdv.com/*",
"zone_name": "antdv.com"
},
{
"pattern": "www.antdv.com/*",
"zone_name": "antdv.com"
}
]
}