Compare commits

...

120 Commits
main ... 1.x

Author SHA1 Message Date
tangjinzhou 19b005867f refactor: remove Google Ads components from API and layout 2025-09-20 14:52:21 +08:00
tangjinzhou e8a1a4a217 docs: update image URLs and remove Alipay/WeChat sponsorship links 2025-09-20 14:51:42 +08:00
tangjinzhou 69d5aa795a chore: update package.json scripts 2025-09-19 19:16:17 +08:00
tangjinzhou bda27eb39b refactor: remove surely form references 2025-09-19 17:27:39 +08:00
tangjinzhou 4136b3b62a docs: update doc url 2023-03-15 16:58:06 +08:00
tangjinzhou 43a48ed422 docs: update bottom banner 2023-03-15 14:08:56 +08:00
tangjinzhou 2afccac35e docs: add qq number & form 2023-03-15 12:26:21 +08:00
tangjinzhou dac22759db docs: add jeecg sponsor 2022-09-02 14:44:59 +08:00
tangjinzhou 3a85220a57 doc: update ad 2022-03-19 16:46:03 +08:00
tangjinzhou acaad27135 docs: update surelyvue 2022-01-27 15:47:36 +08:00
zkwolf 80da77aee0 doc: copy icon #4389 (#4911) 2022-01-27 15:47:36 +08:00
tangjinzhou 773ca392d8 doc: update footer 2022-01-27 15:47:36 +08:00
zkwolf 24ce72ef83 fix: directory-tree title slot #4795 (#4807)
close #4795
2022-01-27 15:47:36 +08:00
tangjinzhou 2c81ccc6f0 doc: update 2022-01-27 15:47:36 +08:00
tangjinzhou 7eb0422f79 doc: update doc 2022-01-27 15:47:36 +08:00
tangjinzhou 11e0994012 doc: update v3 & qrcode 2022-01-27 15:47:36 +08:00
WangYang 233ef9f2cf feat(dropdown): add dropdown destroyPopupOnHide type (#4768)
Co-authored-by: WangYang <yang.wang@cue.group>
2022-01-27 15:47:36 +08:00
Jeminas 441024b993
docs:table demo optimize (#5142) 2022-01-11 16:14:31 +08:00
zhouxinyong 115ca4d8ec
docs: add @formily/antdv link (#5093) 2021-12-28 22:00:03 +08:00
ajuner e70738137e
fix(range-picker): separator error (#5059) 2021-12-21 16:38:59 +08:00
ajuner ef7d0cf0d2
fix(input): allowClear in ie11 (#4699)
close #4679
2021-09-27 09:45:50 +08:00
twobrushes 911ea488bd
perf(table): checkbox performance (#4673)
Co-authored-by: linzhangyu <gebi.lzy@raycloud.com>
2021-09-22 08:31:49 +08:00
tangjinzhou 7779c0469c docs: update doc 2021-08-27 14:07:09 +08:00
tangjinzhou 2b1b81b6ff release 1.7.8 2021-08-27 10:24:13 +08:00
BeADre 7b317a2765
fix(icon): fix the warning of not export default at webpack5 (#4579) 2021-08-27 10:04:33 +08:00
tangjinzhou 74133d18af fix: remove transfer warning #4574 2021-08-26 09:57:37 +08:00
CandyTong f1488e1545
fix(auto-complete): cannot use configProvider prefixCls #4566 (#4568)
Co-authored-by: candychuang <candychuang@tencent.com>

close #4566
2021-08-24 23:01:20 +08:00
tangjinzhou 72b1312209 release 1.7.7 2021-08-07 15:26:34 +08:00
tangjinzhou e99e382ce6 docs: update publicPath 2021-08-07 15:17:38 +08:00
BeADre 89c134a7b7
fix(icon): ensure icon data is valid (#4460)
close #2745
2021-08-04 23:02:56 +08:00
zkwolf b0d226d33e
feat(table): support expandIcon slot (#4448)
close #4444
2021-08-02 17:09:22 +08:00
John 4c559c86ab
docs(space): update `space` document layout #4426 (#4454) 2021-07-31 11:10:50 +08:00
青沛 66219e2b86
docs(update): update documents (#4453)
Co-authored-by: zhangxuelin@xd.com <zhangxuelin@xd.com>
2021-07-31 07:40:55 +08:00
John 6953698385
fix(empty): cannot get `prefixCls` in `configProvider` #4446 (#4447)
close #4446
2021-07-30 16:12:27 +08:00
Darma1106 a4ce890dd6
perf(tabs): active tab color(#4241) (#4417) 2021-07-30 16:05:20 +08:00
tangjinzhou 74007fbb16 Merge branch '1.x' of github.com:vueComponent/ant-design-vue into 1.x 2021-07-14 11:36:35 +08:00
tangjinzhou 833cd47955 docs: update doc 2021-07-14 11:36:25 +08:00
zkwolf 72ca67b103
feat: tree-select support showArrow (#4360) 2021-07-14 10:32:49 +08:00
tangjinzhou 9b5a36186b docs: update anchor feature 2021-07-11 14:54:56 +08:00
zkwolf 4eb26eaec3
feat(input-password): accept global prefixCls (#4280)
* fix(input-password): accept global prefixCls

* fix(input-password): suffix icon style
2021-07-08 09:51:37 +08:00
zkwolf 5c8b82ccf4
feat(tree): support global title slot (#4299)
* feat: global tree title slot

* docs: add context menu demo

* test: update snapshot
2021-07-01 15:21:48 +08:00
tangjinzhou 56991e5488 doc: update table resize demo #4285 2021-06-28 21:09:05 +08:00
undefined e1ac8ce6f0 release 1.7.6 2021-06-26 21:01:17 +08:00
undefined e218afd787 test: update snap 2021-06-26 21:00:58 +08:00
undefined d0c7c0b128 fix: table expanded error #4223 2021-06-26 20:35:53 +08:00
John fb94e7c119
docs(popover): update style #4167 (#4196) 2021-06-10 22:19:19 +08:00
Ken 2f1eb4bbb7
fix: TimePicker input should be readonly like DatePicker. fix #4084 (#4085) 2021-05-23 20:17:24 +08:00
vuthanhbayit 9bb90e78d1
fix: input-number type not work (#4049) 2021-05-10 10:41:32 +08:00
Archer03 23ab83c533
fix: set false as default to validateOnRuleChange in FormModel (#4040) 2021-05-09 20:48:26 +08:00
tangjinzhou 23fb9fae7c release 1.7.5 2021-05-09 15:00:33 +08:00
tangjinzhou f4d8db07fa docs: add ad link 2021-05-09 14:18:09 +08:00
donley 45c7163b58
fix: mode='month' a-date-picker disabledDate prop is invalid (#3988)
* fix: mode='month' a-date-picker disabledDate prop is invalid

* chore: code-factory errors

* chore: remove example codes

* fix: the date-picker disabledDate is invalid when mode is year
2021-05-08 15:09:19 +08:00
Michael Long 3e617bd4d2
docs(table): require `Column.key` in certain cases (#4019)
Prop `Column.key` is required if using template style api (#2501)
2021-05-07 13:38:54 +08:00
zkwolf c0c3b93f0f
chore: remove ci token (#3992)
* chore: remove ci token

* test: update snapshot

* test: update snapshot
2021-04-26 22:17:32 +08:00
John 958e5e488e
fix: input-number ready not work #2971 (#3968) 2021-04-21 15:10:27 +08:00
John bb56898edc
test: update table test case (#3967) 2021-04-21 14:53:25 +08:00
John cc257200e5
fix(1.x/radio): replace 'outline' with 'box-shadow' (#3954)
* fix(radio): replace 'outline' with 'box-shadow'

Closes #3671

* style: remove comment
2021-04-17 08:02:59 +08:00
tangjinzhou 5cec702e0c fix: menu flash #3951 2021-04-17 07:53:08 +08:00
John c2449f568e
docs: keep current path when switching versions (#3927) 2021-04-12 12:33:10 +08:00
John 96709926e8
fix(input): `v-model` modifiers not work (#3817)
* fix(input): `v-model` modifiers not work

* refactor: update
2021-04-11 08:27:39 +08:00
Mr小刘 e95eb61bcb
feat(tbale): 分组表头支持固定-1.x (#3896)
* feat(table): 分组表头支持固定

* docs(table): 增加分组表头固定的英文文档
2021-04-10 21:22:08 +08:00
代娃~ 663aa34d84
docs(table): change rowSelection.selections's default value in chinese docs (#3908) 2021-04-08 11:21:45 +08:00
viruscamp 3761eddb4b
feat: add event update:filterDropdownVisible for Table.Column (#3893)
It's same as event filterDropdownVisibleChange, but can be used with prop as ':filterDropdownVisible.sync="filterDropdownVisible"' for short.
It's the base of other props in Table.Column to add event update:prop to use ':prop.sync' shorthand.
Next events for other props will be update:filteredValue and update:sortDirections.
2021-04-05 10:37:04 +08:00
viruscamp 6fca13fb2c
feat: add event update:expandedRowKeys for Table (#3892)
It's same as event expandedRowsChange, but can be used with prop as ':expandedRowKeys.sync="expandedRowKeys"' for short.
2021-04-04 22:20:34 +08:00
zkwolf 61fa2cfdf6
fix: select trigger disabled option (#3867) 2021-03-28 20:29:45 +08:00
Young 8fc617a4d7
fix:upload component method props not work (#3843)
Co-authored-by: zhenyangliu <liuzhenyang@cfilmcloud.com>
2021-03-27 22:14:57 +08:00
ajuner e0967d9d7e
fix: Microsoft input triggers onchange twice (#3825) 2021-03-20 14:29:23 +08:00
Ken cdde89b17e
fix 'ABackTop visible issue under KeepAlive' (#3802) 2021-03-15 18:17:33 +08:00
tanjinzhou 7c1a14bb5e chore: opensource v1-doc 2021-03-12 15:48:30 +08:00
tanjinzhou 28325c0507 chore: opensource v1-doc 2021-03-12 15:47:29 +08:00
zkwolf 5e139a13e8
fix: revert the default ttab size of card (#3788) 2021-03-12 14:54:07 +08:00
John 976b0b409c
feat: add `dialogStyle` prop (#3794) 2021-03-12 14:52:35 +08:00
zkwolf dfcdf92f7a
fix: drawer esc keydown #3148 (#3790) 2021-03-12 14:51:06 +08:00
Kaworus dced59c65c
feat: add prop tab-size for card (#3762)
* feat: add param tab-size for card

* feat: add param tab-size for card
2021-03-09 15:52:18 +08:00
tangjinzhou 48181af9d6 release 1.7.4 2021-02-28 23:50:22 +08:00
tangjinzhou e427ca15bf perf: table 2021-02-28 23:34:04 +08:00
tangjinzhou 7f4eba3e93 docs: udpate changelog 2021-02-16 16:35:30 +08:00
tangjinzhou 961524b0a7 release 1.7.3 2021-02-16 16:07:12 +08:00
tangjinzhou 391309aad7 style: format code & update snap 2021-02-16 16:05:22 +08:00
tangjinzhou 5e063ba9a3 chore: remove colorpicker 2021-02-16 15:41:00 +08:00
tangjinzhou 22dccf46c5 fix: transformFile not work #3636 2021-02-15 16:07:22 +08:00
pengandpeng 1031e46926
fix: table scroll.x throw error when use expandedRowRender (#3626)
表头固定与展开行不存在冲突,结合使用时不应该报错
2021-02-06 13:46:43 +08:00
zkwolf 76d8408045
fix: closeable icon support in modal method (#3642) 2021-02-06 13:42:04 +08:00
Ken 48bf9ff1b5
fix: menu forceSubMenuRender not work #3615 (#3616) 2021-01-29 21:16:03 +08:00
zkwolf 96e5e836b7
fix: disabled tabPane can be actived #3575 (#3604) 2021-01-27 23:16:47 +08:00
Hyphon e179dedb4a
fix(date-picker): fix props(decade) problem for 1.x (#3536)
Co-authored-by: 李艺珅 <l>
2021-01-14 10:05:18 +08:00
Luka Jeran 1e2814608d
refactor: move ConfigConsumerProps to own file (#3524) 2021-01-14 10:03:43 +08:00
ajuner 0f467695e2
fix: add opacity transition (#3510) 2021-01-09 22:09:34 +08:00
John60676 6175fdbb0c
fix: slider accuracy problems 1.x (#3386)
* fix: slider accuracy problems

* refactor: order of operations
2020-12-17 16:28:30 +08:00
言肆 ec064fe8c2
fix(d.ts): space.d.ts #2923 typeScript definition update (#3340)
* fix(d.ts): space.d.ts  #2923

* fix: add Space ts export
2020-12-15 17:03:00 +08:00
tanjinzhou c74c621e7f fix: table sorter not work #3327 2020-12-09 17:32:38 +08:00
zkwolf 8ba75419b6
fix: checkbox can't trigger change (#3285)
* fix: checkbox can't trigger change

* test: add unit test

* chore: update vc-checkbox
2020-12-04 14:01:51 +08:00
John60676 1581ff3057
fix(button): dropdown inside ButtonGroup in the wrong position (#3036) 2020-11-23 13:55:06 +08:00
tanjinzhou 6ecbaaa547 fix: alert close icon style error on safari #3184 2020-11-16 13:03:21 +08:00
Emmanuel Pastor 388ed15e82
Update ValidationRule message type (#3163) 2020-11-13 11:08:27 +08:00
xrkffgg d552a41e96
fix: auto-complete disabled bg (#3143) 2020-11-12 15:53:19 +08:00
tangjinzhou c57df7db0c bump 1.7.2 2020-11-06 22:19:21 +08:00
tangjinzhou bb8bf0e0f8 test: update snap 2020-11-06 22:13:45 +08:00
tangjinzhou 1d2b93c871 fix: textarea height not correct #2974 2020-11-06 21:25:45 +08:00
tanjinzhou ee0470c280 revert: menu to 1.6.5 #3112 2020-11-06 16:44:30 +08:00
tangjinzhou aa1c9b237e fix: tree-select throw error #3126 2020-11-05 22:49:14 +08:00
tangjinzhou 1aca897b97 bump 1.7.1 2020-10-28 23:16:59 +08:00
tangjinzhou 5eb57fb1a9 fix: Menu component, wrong display Tooltip prompt problem 2020-10-28 23:16:41 +08:00
tanjinzhou a60ba677c2 bump 1.7.0 2020-10-28 13:27:32 +08:00
dogrod f194973151
fix(Table): Fix checkbox does not work when Table Filter value is number type (#3052) 2020-10-28 11:36:06 +08:00
tanjinzhou ef9797d337 style: prettier code 2020-10-28 11:32:38 +08:00
tanjinzhou ce1148838b feat: menu support nest component 2020-10-28 11:31:32 +08:00
tanjinzhou dae751368b fix: table ellipsis not work at fixed column #2916 #3021 2020-10-27 16:13:13 +08:00
tanjinzhou 5597ec0a91 fix: auto-complete select tab focus logic #1438 #3015 2020-10-27 14:57:47 +08:00
tanjinzhou f26c0218d5 feat: support webpack5 2020-10-27 14:03:43 +08:00
tanjinzhou aed1ff0660 perf: update some less 2020-10-27 14:03:25 +08:00
tanjinzhou a43b128262 feat: add ga_IE locale 2020-10-27 14:02:40 +08:00
John60676 6c521620b6
fix(modal): title props support render function (#3030) 2020-10-24 23:33:24 +08:00
Sun 4a3e310db7
fix: space can not inherit attrs (#2902) 2020-09-29 18:28:24 +08:00
tanjinzhou 5c8b77957c fix: upload method not work #2837 2020-09-23 14:21:10 +08:00
tanjinzhou 346a5ce2ba fix: modal types error #2790 2020-09-23 14:20:12 +08:00
Fei Teng 4851d10f60
fix bug tree select custom slot cann't use custom name (#2827) 2020-09-17 16:33:47 +08:00
Emmanuel Akhigbe 6e35cec375
Update dropdown.d.ts (#2757)
Correct typo; 'ontainer' to 'container'
2020-08-27 14:46:02 +08:00
tanjinzhou b690b38b7e test: update snap 2020-08-25 16:34:50 +08:00
tanjinzhou ab7bb9068b release 1.6.5 2020-08-25 16:11:18 +08:00
1051 changed files with 51596 additions and 2020 deletions

1
.github/FUNDING.yml vendored
View File

@ -8,6 +8,5 @@ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/
custom: custom:
[ [
"https://www.paypal.me/tangjinzhou", "https://www.paypal.me/tangjinzhou",
"https://qn.antdv.com/alipay-and-wechat.png",
"https://www.buymeacoffee.com/antdv" "https://www.buymeacoffee.com/antdv"
] ]

View File

@ -12,6 +12,3 @@ 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://qn.antdv.com/alipay-and-wechat.png
about: Ant Design Vue 的健康持续发展需要您的支持,🙏

68
.github/workflows/cloudflare.yml vendored Normal file
View File

@ -0,0 +1,68 @@
name: Build and Deploy to Cloudflare
on:
push:
branches: [ 1.x ]
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 root dependencies
run: npm install --force
- name: Install antdv-demo dependencies
working-directory: antdv-demo
run: npm install --force
- name: Build application
working-directory: antdv-demo
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-files
path: antdv-demo/_site/
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: antdv-demo/_site/
- 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

@ -44,14 +44,6 @@ jobs:
with: with:
token: ${{ secrets.ACCESS_TOKEN }} token: ${{ secrets.ACCESS_TOKEN }}
- name: Checkout submodules
uses: actions/checkout@v2
with:
repository: tangjinzhou/antdv-demo
token: ${{ secrets.ACCESS_TOKEN }}
path: antdv-demo
submodules: true
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v1 uses: actions/cache@v1
with: with:

View File

@ -97,16 +97,6 @@ jobs:
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
token: ${{ secrets.ACCESS_TOKEN }}
- name: Checkout submodules
uses: actions/checkout@v2
with:
repository: tangjinzhou/antdv-demo
token: ${{ secrets.ACCESS_TOKEN }}
path: antdv-demo
submodules: true
- name: restore cache from package-lock.json - name: restore cache from package-lock.json
uses: actions/cache@v1 uses: actions/cache@v1

2
.gitignore vendored
View File

@ -72,3 +72,5 @@ package-lock.json
list.txt list.txt
site/dev.js site/dev.js
v2-doc/
vetur/

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "antdv-demo"]
path = antdv-demo
url = git@github.com:tangjinzhou/antdv-demo.git

View File

@ -10,6 +10,113 @@
--- ---
## 1.7.8
`2021-08-27`
- 🐞 Fix `AutoComplete` using configProvider global configuration prefixCls does not take effect [#4566](https://github.com/vueComponent/ant-design-vue/issues/4566)
- 🐞 Remove Transfer custom key warning issue [#4574](https://github.com/vueComponent/ant-design-vue/issues/4574)
- 🐞 Fix `Icon` reporting error under webpack 5 [#4579](https://github.com/vueComponent/ant-design-vue/issues/4579)
## 1.7.7
`2021-08-07`
- 🌟 `Tree` supports global setting of title via slot [#4299](https://github.com/vueComponent/ant-design-vue/issues/4299)
- 🌟 `InputPassword` supports global setting prefixCls [#4280](https://github.com/vueComponent/ant-design-vue/issues/4280)
- 🌟 `TreeSelect` supports showArrow [#4360](https://github.com/vueComponent/ant-design-vue/issues/4360)
- 🌟 Optimize the flickering problem of `Tabs` when selected under windows [#4241](https://github.com/vueComponent/ant-design-vue/issues/4241)
- 🌟 `Table` supports slot customization expandIcon [#4448](https://github.com/vueComponent/ant-design-vue/issues/4448)
- 🐞 Fix the problem that the global prefixCls of the `Empty` component is not responsive [#4446](https://github.com/vueComponent/ant-design-vue/issues/4446)
## 1.7.6
`2021-06-26`
- 🐞 Fix the problem that the height of the table is misplaced and the expansion does not take effect when the alias is not set [#4223](https://github.com/vueComponent/ant-design-vue/issues/4223)
## 1.7.5
`2021-05-09`
- 🌟 `Card` adds tab property configuration [#3762](https://github.com/vueComponent/ant-design-vue/issues/3762)
- 🌟 `Table`
- Added `v-model:expandedRowKeys` support [#3892](https://github.com/vueComponent/ant-design-vue/issues/3892)
- The group header supports fixed [#3896](https://github.com/vueComponent/ant-design-vue/issues/3896)
- 🌟 `Modal` adds dialogStyle property configuration [#3794](https://github.com/vueComponent/ant-design-vue/issues/3794)
- 🐞 Fix the problem that `Drawer` `esc` cannot close the drawer [#3790](https://github.com/vueComponent/ant-design-vue/issues/3790)
- 🐞 Fix `BackTop` display problem under keepAlive [#3802](https://github.com/vueComponent/ant-design-vue/issues/3802)
- 🐞 Fix the issue that `Input` triggers two change events under Microsoft input method [#3825](https://github.com/vueComponent/ant-design-vue/issues/3825)
- 🐞 Fix the issue that the `Upload` custom method does not take effect [#3843](https://github.com/vueComponent/ant-design-vue/issues/3843)
- 🐞 Fix the problem of selecting the disabled option in `Select` [#3867](https://github.com/vueComponent/ant-design-vue/issues/3867)
- 🐞 Fix `Menu` flickering problem [#3951](https://github.com/vueComponent/ant-design-vue/issues/3951)
- 🐞 Fix `InputNumber` `readonly` not valid issue [#2971](https://github.com/vueComponent/ant-design-vue/issues/2971)
- 🐞 Fix the issue that disabledDate does not take effect when `DatePicker` is in mode="month" [#3988](https://github.com/vueComponent/ant-design-vue/issues/3988)
## 1.7.4
`2021-02-28`
- 🌟 Optimize the performance of `Table` [#3531](https://github.com/vueComponent/ant-design-vue/issues/3531)
## 1.7.3
`2021-02-16`
- 🌟 `Modal` api method call supports defining close icon [#3642](https://github.com/vueComponent/ant-design-vue/issues/3642)
- 🌟 `Form` message support function [#3163](https://github.com/vueComponent/ant-design-vue/issues/3163)
- 🌟 Optimize the animation effect of `Progress` [#3510](https://github.com/vueComponent/ant-design-vue/issues/3510)
- 🐞 Fix the background color problem when `AutoComplete` is disabled [#3143](https://github.com/vueComponent/ant-design-vue/issues/3143)
- 🐞 Fix the issue that the `Alert` close button is displayed abnormally under safari [#3184](https://github.com/vueComponent/ant-design-vue/issues/3184)
- 🐞 Fix the problem that `Dropdown` shows the wrong position under `ButtonGroup` [#2995](https://github.com/vueComponent/ant-design-vue/issues/2995)
- 🐞 Fix the issue that the change event will no longer be triggered after `RadioGroup` is blocked from being selected [#3047](https://github.com/vueComponent/ant-design-vue/issues/3047)
- 🐞 Fix the problem that `Table` cannot be sorted [#3327](https://github.com/vueComponent/ant-design-vue/issues/3327)
- 🐞 Fix missing `Space` component type file issue [#3340](https://github.com/vueComponent/ant-design-vue/issues/3340)
- 🐞 Fix `Slider`'s position calculation error under decimal precision [#3386](https://github.com/vueComponent/ant-design-vue/issues/3386)
- 🐞 Fix `DatePicker` mode="decade" invalidation issue [#3536](https://github.com/vueComponent/ant-design-vue/issues/3536)
- 🐞 Fix the problem that the keyboard can still be switched in the diabled state of `Tabs` [#3575](https://github.com/vueComponent/ant-design-vue/issues/3575)
- 🐞 Fix the issue that `Menu` `forceSubMenuRender` does not take effect [#3615](https://github.com/vueComponent/ant-design-vue/issues/3615)
- 🐞 Fix `Upload` `transformFile` not executing issue [#3636](https://github.com/vueComponent/ant-design-vue/issues/3636)
## 1.7.2
`2020-11-06`
- 🐞 Fix the problem of incorrect height of Textarea component [#2974](https://github.com/vueComponent/ant-design-vue/issues/2974)
- 🐞 Roll back Menu component to version 1.6.5 to be consistent [#3112](https://github.com/vueComponent/ant-design-vue/issues/3112)
- 🐞 Fix TreeSelect throw error [#3126](https://github.com/vueComponent/ant-design-vue/issues/3126)
## 1.7.1
`2020-10-28`
- 🐞 Fix Menu component, wrong display Tooltip prompt problem
## 1.7.0
`2020-10-28`
- 🌟 Recursive Menu component, supports arbitrary nesting of other elements [#1452](https://github.com/vueComponent/ant-design-vue/issues/1452)
- 🇮🇪 Add Irish language internationalization support
- 🐞 Fix webpack 5 compatibility issues.
- 🐞 Fix the problem that the Upload method attribute does not take effect [#2837](https://github.com/vueComponent/ant-design-vue/issues/2837)
- 🐞 Fix the problem that Space does not declare properties and does not mount the root node [#2902](https://github.com/vueComponent/ant-design-vue/issues/2902)
- 🐞 Fix the problem that Table component filter does not support number type [#3052](https://github.com/vueComponent/ant-design-vue/issues/3052)
- 🐞 Fix Table fixed column ellipsis not working issue [#2916](https://github.com/vueComponent/ant-design-vue/issues/2916)
- 🐞 Fix AutoComplete component, need two tab keys to focus issue [#1438](https://github.com/vueComponent/ant-design-vue/issues/1438)
- 🐞 Fix the problem that TreeSelect cannot customize slot [#2827](https://github.com/vueComponent/ant-design-vue/issues/2827)
## 1.6.5
`2020-08-25`
- 🔥🔥🔥 Vue 3 compatible [2.0.0-beta.3](https://2x.antdv.com/)
- 🔥 Add Space component [#2669](https://github.com/vueComponent/ant-design-vue/pull/2669)
- 🌟 Optimize zh_TW language pack [#2679](https://github.com/vueComponent/ant-design-vue/pull/2679)
- 🐞 Fix breadcrumb `Breadcrumb` repeated key problem [#2505](https://github.com/vueComponent/ant-design-vue/issues/2505)
- 🐞 Fix the problem of misalignment in the fixed column of Table [#1493](https://github.com/vueComponent/ant-design-vue/issues/1493)
- 🐞 Fix the problem that the Enter key will report an error when the Mentions component is empty [#2662](https://github.com/vueComponent/ant-design-vue/pull/2662)
## 1.6.4 ## 1.6.4
`2020-07-21` `2020-07-21`

View File

@ -10,6 +10,113 @@
--- ---
## 1.7.8
`2021-08-27`
- 🐞 修复 `AutoComplete` 使用 configProvider 全局配置 prefixCls 不生效问题 [#4566](https://github.com/vueComponent/ant-design-vue/issues/4566)
- 🐞 移除 Transfer 自定义 key warning 问题 [#4574](https://github.com/vueComponent/ant-design-vue/issues/4574)
- 🐞 修复 `Icon` 在 webpack 5 下报错问题 [#4579](https://github.com/vueComponent/ant-design-vue/issues/4579)
## 1.7.7
`2021-08-07`
- 🌟 `Tree` 支持全局通过 slot 设置 title [#4299](https://github.com/vueComponent/ant-design-vue/issues/4299)
- 🌟 `InputPassword` 支持全局设置 prefixCls [#4280](https://github.com/vueComponent/ant-design-vue/issues/4280)
- 🌟 `TreeSelect` 支持 showArrow [#4360](https://github.com/vueComponent/ant-design-vue/issues/4360)
- 🌟 优化 `Tabs` 在 windows 下选中时闪动问题 [#4241](https://github.com/vueComponent/ant-design-vue/issues/4241)
- 🌟 `Table` 支持通过 slot 自定义 expandIcon [#4448](https://github.com/vueComponent/ant-design-vue/issues/4448)
- 🐞 修复 `Empty` 组件全局 prefixCls 没有响应式问题 [#4446](https://github.com/vueComponent/ant-design-vue/issues/4446)
## 1.7.6
`2021-06-26`
- 🐞 修复不设置 alias 时table 高度错位,展开不生效问题 [#4223](https://github.com/vueComponent/ant-design-vue/issues/4223)
## 1.7.5
`2021-05-09`
- 🌟 `Card` 新增 tab 属性配置 [#3762](https://github.com/vueComponent/ant-design-vue/issues/3762)
- 🌟 `Table`
- 新增 `v-model:expandedRowKeys` 支持 [#3892](https://github.com/vueComponent/ant-design-vue/issues/3892)
- 分组表头支持 fixed [#3896](https://github.com/vueComponent/ant-design-vue/issues/3896)
- 🌟 `Modal` 新增 dialogStyle 属性配置 [#3794](https://github.com/vueComponent/ant-design-vue/issues/3794)
- 🐞 修复 `Drawer` `esc` 无法关闭抽屉问题 [#3790](https://github.com/vueComponent/ant-design-vue/issues/3790)
- 🐞 修复 `BackTop` 在 keepAlive 下显示问题 [#3802](https://github.com/vueComponent/ant-design-vue/issues/3802)
- 🐞 修复 `Input` 在微软输入法下触发两次 change 事件问题 [#3825](https://github.com/vueComponent/ant-design-vue/issues/3825)
- 🐞 修复 `Upload` 自定义 method 不生效问题 [#3843](https://github.com/vueComponent/ant-design-vue/issues/3843)
- 🐞 修复 `Select` 选中 disabled 选项问题 [#3867](https://github.com/vueComponent/ant-design-vue/issues/3867)
- 🐞 修复 `Menu` 闪动问题 [#3951](https://github.com/vueComponent/ant-design-vue/issues/3951)
- 🐞 修复 `InputNumber` `readonly` 不生效问题 [#2971](https://github.com/vueComponent/ant-design-vue/issues/2971)
- 🐞 修复 `DatePicker` 在 mode="month" 时, disabledDate 不生效问题 [#3988](https://github.com/vueComponent/ant-design-vue/issues/3988)
## 1.7.4
`2021-02-28`
- 🌟 优化 `Table` 性能 [#3531](https://github.com/vueComponent/ant-design-vue/issues/3531)
## 1.7.3
`2021-02-16`
- 🌟 `Modal` api 方式调用支持定义关闭图标 [#3642](https://github.com/vueComponent/ant-design-vue/issues/3642)
- 🌟 `Form` message 支持函数 [#3163](https://github.com/vueComponent/ant-design-vue/issues/3163)
- 🌟 优化 `Progress` 动画效果 [#3510](https://github.com/vueComponent/ant-design-vue/issues/3510)
- 🐞 修复 `AutoComplete` disabled 时背景颜色异常问题 [#3143](https://github.com/vueComponent/ant-design-vue/issues/3143)
- 🐞 修复 `Alert` 关闭按钮在 safari 下显示异常问题 [#3184](https://github.com/vueComponent/ant-design-vue/issues/3184)
- 🐞 修复 `Dropdown``ButtonGroup` 下显示位置错误问题 [#2995](https://github.com/vueComponent/ant-design-vue/issues/2995)
- 🐞 修复 `RadioGroup` 阻止选中后,不再触发 change 事件问题 [#3047](https://github.com/vueComponent/ant-design-vue/issues/3047)
- 🐞 修复 `Table` 无法排序的问题 [#3327](https://github.com/vueComponent/ant-design-vue/issues/3327)
- 🐞 修复缺失 `Space` 组件类型文件问题 [#3340](https://github.com/vueComponent/ant-design-vue/issues/3340)
- 🐞 修复 `Slider` 在小数精度下位置计算错误问题 [#3386](https://github.com/vueComponent/ant-design-vue/issues/3386)
- 🐞 修复 `DatePicker` mode="decade" 失效问题 [#3536](https://github.com/vueComponent/ant-design-vue/issues/3536)
- 🐞 修复 `Tabs` diabled 状态下依然可以通过键盘切换问题 [#3575](https://github.com/vueComponent/ant-design-vue/issues/3575)
- 🐞 修复 `Menu` `forceSubMenuRender` 不生效问题 [#3615](https://github.com/vueComponent/ant-design-vue/issues/3615)
- 🐞 修复 `Upload` `transformFile` 不执行问题 [#3636](https://github.com/vueComponent/ant-design-vue/issues/3636)
## 1.7.2
`2020-11-06`
- 🐞 修复 Textarea 组件高度不正确问题 [#2974](https://github.com/vueComponent/ant-design-vue/issues/2974)
- 🐞 回滚 Menu 组件到 1.6.5 版本一致 [#3112](https://github.com/vueComponent/ant-design-vue/issues/3112)
- 🐞 修复 TreeSelect throw error [#3126](https://github.com/vueComponent/ant-design-vue/issues/3126)
## 1.7.1
`2020-10-28`
- 🐞 修复 Menu 组件,错误展示 Tooltip 提示的问题
## 1.7.0
`2020-10-28`
- 🌟 递归 Menu 组件,支持任意嵌套其他元素 [#1452](https://github.com/vueComponent/ant-design-vue/issues/1452)
- 🇮🇪 添加爱尔兰语国际化支持
- 🐞 修复 webpack 5 兼容问题。
- 🐞 修复 Upload method 属性不生效问题 [#2837](https://github.com/vueComponent/ant-design-vue/issues/2837)
- 🐞 修复 Space 未声明属性,不挂载根结点上问题 [#2902](https://github.com/vueComponent/ant-design-vue/issues/2902)
- 🐞 修复 Table 组件 filter 不支持 number 类型问题 [#3052](https://github.com/vueComponent/ant-design-vue/issues/3052)
- 🐞 修复 Table 固定列 ellipsis 不生效问题 [#2916](https://github.com/vueComponent/ant-design-vue/issues/2916)
- 🐞 修复 AutoComplete 组件,需要两次 tab 键才可 focus 问题 [#1438](https://github.com/vueComponent/ant-design-vue/issues/1438)
- 🐞 修复 TreeSelect 不能自定义 slot 问题 [#2827](https://github.com/vueComponent/ant-design-vue/issues/2827)
## 1.6.5
`2020-08-25`
- 🔥🔥🔥 兼容 Vue 3 的 [2.0.0-beta.3](https://2x.antdv.com/) 版本发布
- 🔥 新增 Space 组件 [#2669](https://github.com/vueComponent/ant-design-vue/pull/2669)
- 🌟 优化 zh_TW 语言包 [#2679](https://github.com/vueComponent/ant-design-vue/pull/2679)
- 🐞 修复面包屑 `Breadcrumb` 重复 key 问题 [#2505](https://github.com/vueComponent/ant-design-vue/issues/2505)
- 🐞 修复 Table 固定列情况下错位问题 [#1493](https://github.com/vueComponent/ant-design-vue/issues/1493)
- 🐞 修复 Mentions 组件为空时回车键报错的问题 [#2662](https://github.com/vueComponent/ant-design-vue/pull/2662)
## 1.6.4 ## 1.6.4
`2020-07-21` `2020-07-21`

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://qn.antdv.com/logo.png"> <img width="200" src="https://www.antdv.com/logo.png">
</a> </a>
</p> </p>
@ -40,6 +40,7 @@ An enterprise-class UI components based on Ant Design and Vue.
- 提炼自企业级中后台产品的交互语言和视觉风格。 - 提炼自企业级中后台产品的交互语言和视觉风格。
- 开箱即用的高质量 Vue 组件。 - 开箱即用的高质量 Vue 组件。
- 共享 [Ant Design of React](http://ant-design.gitee.io/docs/spec/introduce-cn) 设计工具体系。 - 共享 [Ant Design of React](http://ant-design.gitee.io/docs/spec/introduce-cn) 设计工具体系。
- 从 [2.x](https://2x.antdv.com/) 版本开始支持 Vue 3
## 支持环境 ## 支持环境
@ -79,6 +80,7 @@ $ yarn add ant-design-vue
| [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) | ant-design-vue 的 vscode 扩展 | | [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) | ant-design-vue 的 vscode 扩展 |
| [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | 使用 vue-cli3 快速使用 ant-design-vue 组件库 | | [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | 使用 vue-cli3 快速使用 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 的组件库 |
## 问答 ## 问答
@ -93,7 +95,6 @@ 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://qn.antdv.com/alipay-and-wechat.png)
## Sponsors ## Sponsors

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://qn.antdv.com/logo.png"> <img width="200" src="https://www.antdv.com/logo.png">
</a> </a>
</p> </p>
@ -40,6 +40,7 @@ English | [简体中文](./README-zh_CN.md)
- An enterprise-class UI design system for desktop applications. - An enterprise-class UI design system for desktop applications.
- A set of high-quality Vue components out of the box. - A set of high-quality Vue components out of the box.
- Shared [Ant Design of React](https://ant.design/docs/spec/introduce) design resources. - Shared [Ant Design of React](https://ant.design/docs/spec/introduce) design resources.
- Support Vue 3 from [2.x](https://2x.antdv.com/)
## Environment Support ## Environment Support
@ -79,6 +80,7 @@ If you are in a bad network environmentyou can try other registries and tools
| [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) | A vscode extension for ant-design-vue | | [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) | A vscode extension for ant-design-vue |
| [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | Vue-cli 3 plugin to add ant-design-vue | | [vue-cli-plugin-ant-design](https://github.com/vueComponent/vue-cli-plugin-ant-design) | Vue-cli 3 plugin to add ant-design-vue |
| [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 |
## Donation ## Donation
@ -87,7 +89,6 @@ 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://qn.antdv.com/alipay-and-wechat.png)
## Sponsors ## Sponsors

View File

@ -23,7 +23,7 @@ function transformLess(lessFile, config = {}) {
.render(data, lessOpts) .render(data, lessOpts)
.then(result => { .then(result => {
const source = result.css; const source = result.css;
return postcss(postcssConfig.plugins).process(source); return postcss(postcssConfig.plugins).process(source, { from: undefined });
}) })
.then(r => { .then(r => {
return r.css; return r.css;

@ -1 +0,0 @@
Subproject commit 84ee25d800ce56d1fc170d9dbd7b150343be9b0e

14
antdv-demo/.babelrc Normal file
View File

@ -0,0 +1,14 @@
{
"env": {
"test": {
"presets": [["env", { "targets": { "node": "current" } }]],
"plugins": [
"transform-vue-jsx",
"transform-object-assign",
"transform-object-rest-spread",
"transform-class-properties",
"transform-runtime"
]
}
}
}

11
antdv-demo/.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# 🎨 editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

8
antdv-demo/.eslintignore Normal file
View File

@ -0,0 +1,8 @@
node_modules/
**/*.spec.*
**/style/
*.html
/components/test/*
_site/
dist/
package.json

53
antdv-demo/.eslintrc Normal file
View File

@ -0,0 +1,53 @@
{
"root": true,
"env": {
"browser": true,
"node": true,
"jasmine": true,
"jest": true,
"es6": true
},
"parserOptions": {
"parser": "babel-eslint"
},
"extends": ["plugin:vue/recommended", "prettier"],
"plugins": ["markdown"],
"overrides": [
{
"files": ["**/demo/*.md"],
"processor": "markdown/markdown",
"rules": {
"no-console": "off"
}
}
],
"rules": {
"comma-dangle": [2, "always-multiline"],
"no-var": "error",
"no-console": [2, { "allow": ["warn", "error"] }],
"object-shorthand": 2,
"no-unused-vars": [2, { "ignoreRestSiblings": true, "argsIgnorePattern": "^h$" }],
"no-undef": 2,
"camelcase": "off",
"no-extra-boolean-cast": "off",
"semi": ["error", "always"],
"vue/require-prop-types": "off",
"vue/require-default-prop": "off",
"vue/no-reserved-keys": "off",
"vue/comment-directive": "off",
"vue/prop-name-casing": "off",
"vue/max-attributes-per-line": [
2,
{
"singleline": 20,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}
]
},
"globals": {
"h": true
}
}

109
antdv-demo/.gitignore vendored Normal file
View File

@ -0,0 +1,109 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
site/dev.js
_site/
package-lock.json
testDemo/

7
antdv-demo/.huskyrc Normal file
View File

@ -0,0 +1,7 @@
{
"hooks": {
"pre-commit": "pretty-quick --staged",
"pre-publish": "npm run lint",
"commit-msg": "commitlint -x @commitlint/config-conventional -e $GIT_PARAMS"
}
}

View File

@ -0,0 +1,29 @@
**/*.svg
package.json
lib/
es/
dist/
_site/
coverage/
CNAME
LICENSE
yarn.lock
netlify.toml
yarn-error.log
*.sh
*.snap
.gitignore
.npmignore
.prettierignore
.DS_Store
.editorconfig
.eslintignore
**/*.yml
components/style/color/*.less
**/assets
.gitattributes
.stylelintrc
.vcmrc
.png
.npmrc.template
.huskyrc

14
antdv-demo/.prettierrc Normal file
View File

@ -0,0 +1,14 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"proseWrap": "never",
"overrides": [
{
"files": ".prettierrc",
"options": {
"parser": "json"
}
}
]
}

23
antdv-demo/.stylelintrc Normal file
View File

@ -0,0 +1,23 @@
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": {
"comment-empty-line-before": null,
"declaration-empty-line-before": null,
"function-comma-newline-after": null,
"function-name-case": null,
"function-parentheses-newline-inside": null,
"function-max-empty-lines": null,
"function-whitespace-after": null,
"indentation": null,
"number-leading-zero": null,
"number-no-trailing-zeros": null,
"rule-empty-line-before": null,
"selector-combinator-space-after": null,
"selector-list-comma-newline-after": null,
"selector-pseudo-element-colon-notation": null,
"unit-no-unknown": null,
"value-list-max-empty-lines": null,
"font-family-no-missing-generic-family-keyword": null,
"no-descending-specificity": null
}
}

View File

@ -0,0 +1,3 @@
module.exports = {
...require('./mock/user'),
};

5
antdv-demo/build.sh Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
rm -rf dist
mkdir dist
./node_modules/.bin/webpack --config webpack.site.config.js
cp dist/index.html index.html

View File

@ -0,0 +1,5 @@
module.exports = {
dev: {
componentName: 'form', // dev components
},
};

213
antdv-demo/build/dev.js Normal file
View File

@ -0,0 +1,213 @@
process.env.ENTRY_INDEX = 'dev';
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const importFresh = require('import-fresh');
const replace = require('json-templater/string');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const devWebpack = require('./webpack.dev.conf');
const configPath = path.join(__dirname, './config.js');
/**
* a-bc-d --> aBcD
* @param {string} s
*/
const camelize = s => s.replace(/-(\w)/g, ($, $1) => $1.toUpperCase());
/**
* radio-group --> radio
* @param {string} s
*/
const getUpper = s => s.replace(/(-[a-z]*)/g, '');
let { componentName } = require('./config').dev;
const componentsInPrototype = ['Modal', 'message', 'notification'];
const MAIN_TEMPLATE = `import 'babel-polyfill';
import Vue from 'vue';
import Vuex from 'vuex';
import VueI18n from 'vue-i18n';
import VueRouter from 'vue-router';
import VueClipboard from 'vue-clipboard2';
import Md from '../components/md';
import Api from '../components/api';
import demoBox from '../components/demoBox';
import demoSort from '../components/demoSort';
import demoContainer from '../components/demoContainer';
import { message, notification } from 'ant-design-vue';
{{importComponents}}
{{importStyles}}
import 'ant-design-vue/es/message/style';
import 'ant-design-vue/es/notification/style';
import Test from '../docs/{{name}}/demo/index.vue';
import zhCN from '../theme/zh-CN';
import enUS from '../theme/en-US';
import './index.less';
Vue.use(Vuex);
Vue.use(VueClipboard);
Vue.use(VueRouter);
Vue.use(VueI18n);
Vue.component(Md.name, Md);
Vue.component(Api.name, Api);
Vue.component('demo-box', demoBox);
Vue.component('demo-sort', demoSort);
Vue.component('demo-container', demoContainer);
Vue.prototype.$message = message;
Vue.prototype.$notification = notification;
Vue.prototype.$info = Modal.info;
Vue.prototype.$success = Modal.success;
Vue.prototype.$error = Modal.error;
Vue.prototype.$warning = Modal.warning;
Vue.prototype.$confirm = Modal.confirm;
Vue.prototype.$destroyAll = Modal.destroyAll;
Vue.prototype.$form = Form;
Vue.use(Modal);
{{install}}
const i18n = new VueI18n({
locale: enUS.locale,
messages: {
[enUS.locale]: { message: enUS.messages },
[zhCN.locale]: { message: zhCN.messages },
},
});
const router = new VueRouter({
mode: 'history',
routes: [{
path: '/test',
component: () => import('../testDemo/index.vue'),
}, {
path: '/*', component: Test
}],
});
const store = new Vuex.Store({
state: {
username: 'zeka',
},
mutations: {
update(state, payload) {
state.username = payload.username;
},
},
});
new Vue({
el: '#app',
i18n,
router,
store,
});
`;
const OUTPUT_PATH = path.join(__dirname, '../site/dev.js');
const generateEntry = components =>
Object.keys(components)
.map(component => `import ${component} from 'ant-design-vue/es/${components[component]}';`)
.join('\n');
const generateStyles = components =>
Object.keys(components)
.map(component => `import 'ant-design-vue/es/${components[component]}/style';`)
.join('\n');
const generateInstall = components =>
Object.keys(components)
.map(component => `Vue.use(${component});`)
.join('\n');
const renderTemplate = name => {
const components = {
Tooltip: 'tooltip', // for DemoBox
Icon: 'icon', // Basic
Form: 'form',
Modal: 'modal',
};
const demoPaths = fs
.readdirSync(path.join(__dirname, `../docs/${name}/demo`))
.map(p => `../docs/${name}/demo/${p}`);
const testPaths = fs
.readdirSync(path.join(__dirname, `../testDemo`))
.map(p => `../testDemo/${p}`);
[...demoPaths, ...testPaths].forEach(demoPath => {
const demo = fs.readFileSync(path.join(__dirname, demoPath)).toString();
const componentsInDemo = demo.match(/a-(\w+(-\w+)*)/g) || [];
componentsInDemo.forEach(name => {
const dirName = name.replace(/^a-/, '');
const componentName = camelize(name).replace(/^a/, '');
const upperComponentDir = getUpper(dirName);
const upperComponentName = upperComponentDir.replace(/^[a-z]/, $ => $.toUpperCase());
const componentPath = path.join(__dirname, `../../components/${dirName}`);
if (fs.existsSync(componentPath)) {
if (componentsInPrototype.includes(componentName)) {
return;
}
components[componentName] = dirName;
} else if (fs.existsSync(path.join(__dirname, `../../components/${upperComponentDir}`))) {
components[upperComponentName] = upperComponentDir;
}
});
});
const importComponents = generateEntry(components);
const importStyles = generateStyles(components);
const install = generateInstall(components);
const template = replace(MAIN_TEMPLATE, {
importComponents,
importStyles,
install,
name,
});
fs.writeFileSync(OUTPUT_PATH, template);
};
function fsExistsSync(path) {
try {
fs.accessSync(path, fs.F_OK);
} catch (e) {
return false;
}
return true;
}
if (!fsExistsSync(path.join(__dirname, '../testDemo/index.vue'))) {
if (!fsExistsSync(path.join(__dirname, '../testDemo'))) {
fs.mkdirSync(path.join(__dirname, '../testDemo'));
}
fs.writeFileSync(path.join(__dirname, '../testDemo/index.vue'), `<template></template>`);
}
let demoWatcher;
chokidar.watch(configPath, { ignoreInitial: true }).on('change', async () => {
({ componentName } = importFresh(configPath).dev);
demoWatcher && (await demoWatcher.close());
demoWatcher = chokidar.watch(path.join(__dirname, `../docs/${componentName}/demo`));
demoWatcher.on('change', () => {
renderTemplate(componentName);
});
renderTemplate(componentName);
});
renderTemplate(componentName);
const compiler = webpack(devWebpack);
const configuration = devWebpack.devServer;
const server = new WebpackDevServer(compiler, configuration);
server.listen(configuration.port);

View File

@ -0,0 +1,45 @@
'use strict';
module.exports = function(modules) {
const plugins = [
require.resolve('babel-plugin-transform-vue-jsx'),
require.resolve('babel-plugin-inline-import-data-uri'),
require.resolve('babel-plugin-transform-es3-member-expression-literals'),
require.resolve('babel-plugin-transform-es3-property-literals'),
require.resolve('babel-plugin-transform-object-assign'),
require.resolve('babel-plugin-transform-object-rest-spread'),
require.resolve('babel-plugin-transform-class-properties'),
];
plugins.push([
require.resolve('babel-plugin-transform-runtime'),
{
polyfill: false,
},
]);
return {
presets: [
[
require.resolve('babel-preset-env'),
{
modules,
targets: {
browsers: [
'last 2 versions',
'Firefox ESR',
'> 1%',
'ie >= 9',
'iOS >= 8',
'Android >= 4',
],
},
},
],
],
plugins,
env: {
test: {
plugins: [require.resolve('babel-plugin-istanbul')],
},
},
};
};

View File

@ -0,0 +1,166 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = function(env) {
const isDev = env === 'development';
return {
test: /\.less$/,
oneOf: [
/* config.module.rule('less').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
isDev
? {
loader: 'vue-style-loader',
options: {
sourceMap: isDev,
shadowMode: false,
},
}
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: isDev,
importLoaders: 2,
modules: {
localIdentName: '[name]_[local]_[hash:base64:5]',
},
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: isDev,
},
},
{
loader: 'less-loader',
options: {
lessOptions: {
sourceMap: isDev,
modifyVars: {},
javascriptEnabled: true,
},
},
},
],
},
/* config.module.rule('less').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
isDev
? {
loader: 'vue-style-loader',
options: {
sourceMap: isDev,
shadowMode: false,
},
}
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: isDev,
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: isDev,
},
},
{
loader: 'less-loader',
options: {
lessOptions: {
sourceMap: isDev,
modifyVars: {},
javascriptEnabled: true,
},
},
},
],
},
/* config.module.rule('less').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
isDev
? {
loader: 'vue-style-loader',
options: {
sourceMap: isDev,
shadowMode: false,
},
}
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: isDev,
importLoaders: 2,
modules: {
localIdentName: '[name]_[local]_[hash:base64:5]',
},
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: isDev,
},
},
{
loader: 'less-loader',
options: {
lessOptions: {
sourceMap: isDev,
modifyVars: {},
javascriptEnabled: true,
},
},
},
],
},
/* config.module.rule('less').oneOf('normal') */
{
use: [
isDev
? {
loader: 'vue-style-loader',
options: {
sourceMap: isDev,
shadowMode: false,
},
}
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: isDev,
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: isDev,
},
},
{
loader: 'less-loader',
options: {
lessOptions: {
sourceMap: isDev,
modifyVars: {},
javascriptEnabled: true,
},
},
},
],
},
],
};
};

View File

@ -0,0 +1,226 @@
const path = require('path');
const webpack = require('webpack');
const Prism = require('prismjs');
require('prismjs/components/prism-jsx.min.js');
require('prismjs/components/prism-bash.min.js');
require('prismjs/components/prism-json.min.js');
require('prismjs/components/prism-diff.min.js');
require('prismjs/components/prism-less.min.js');
const Token = require('markdown-it/lib/token');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const cheerio = require('cheerio');
const WebpackBar = require('webpackbar');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const getBabelCommonConfig = require('./getBabelCommonConfig');
const babelConfig = getBabelCommonConfig(false);
babelConfig.plugins.push(require.resolve('babel-plugin-syntax-dynamic-import'));
const fetch = (str, tag, scoped) => {
const $ = cheerio.load(str, {
decodeEntities: false,
xmlMode: true,
});
if (!tag) {
return str;
}
if (tag === 'style') {
return scoped
? $(`${tag}[scoped]`).html()
: $(`${tag}`)
.not(`${tag}[scoped]`)
.html();
}
return $(tag).html();
};
/**
* `{{ }}` => `<span>{{</span> <span>}}</span>`
* @param {string} str
* @return {string}
*/
const replaceDelimiters = function(str) {
return str.replace(/({{|}})/g, '<span>$1</span>');
};
/**
* renderHighlight
* @param {string} str
* @param {string} lang
*/
const renderHighlight = function(str, lang) {
if (!(lang && Prism.languages[lang])) {
return '';
}
try {
return replaceDelimiters(Prism.highlight(str, Prism.languages[lang], lang));
} catch (err) {}
};
const md = require('markdown-it')('default', {
html: true,
breaks: true,
highlight: renderHighlight,
}).use(require('markdown-it-anchor'), {
level: 2,
slugify: string =>
string
.trim()
.split(' ')
.join('-'),
permalink: true,
// renderPermalink: (slug, opts, state, permalink) => {},
permalinkClass: 'anchor',
permalinkSymbol: '#',
permalinkBefore: false,
});
// md.renderer.rules.fence = wrap(md.renderer.rules.fence)
const cnReg = new RegExp('<(cn)(?:[^<]|<)+</\\1>', 'g');
const usReg = new RegExp('<(us)(?:[^<]|<)+</\\1>', 'g');
md.core.ruler.push('update_template', function replace({ tokens }) {
let cn = '';
let us = '';
let template = '';
let script = '';
let style = '';
let scopedStyle = '';
let code = '';
let sourceCode = '';
tokens.forEach(token => {
if (token.type === 'html_block') {
if (token.content.match(cnReg)) {
cn = fetch(token.content, 'cn');
token.content = '';
}
if (token.content.match(usReg)) {
us = fetch(token.content, 'us');
token.content = '';
}
}
if (token.type === 'fence' && token.info === 'vue' && token.markup === '```') {
sourceCode = token.content;
code = '```html\n' + token.content + '```';
template = fetch(token.content, 'template');
script = fetch(token.content, 'script');
style = fetch(token.content, 'style');
scopedStyle = fetch(token.content, 'style', true);
token.content = '';
token.type = 'html_block';
}
});
if (template) {
let jsfiddle = {
us,
cn,
sourceCode: Buffer.from(sourceCode).toString('base64'),
};
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
const codeHtml = code ? md.render(code.replace(/@/g, '__at__')).replace(/__at__/g, '@') : '';
const cnHtml = cn ? md.render(cn) : '';
let newContent = `
<template>
<demo-box :jsfiddle="${jsfiddle}">
<template slot="component">${template}</template>
<template slot="description">${cnHtml}</template>
<template slot="us-description">${us ? md.render(us) : ''}</template>
<template slot="code">${Buffer.from(codeHtml).toString('base64')}</template>
</demo-box>
</template>`;
newContent += script
? `
<script>
${script || ''}
</script>
`
: '';
newContent += style ? `<style>${style || ''}</style>` : '';
newContent += scopedStyle ? `<style scoped>${scopedStyle || ''}</style>` : '';
const t = new Token('html_block', '', 0);
t.content = newContent;
tokens.push(t);
}
});
const vueLoaderOptions = {
loaders: {
js: [
{
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-vue-jsx', 'transform-object-rest-spread'],
},
},
],
},
};
module.exports = {
mode: 'production',
entry: {
index: [`./site/${process.env.ENTRY_INDEX || 'index'}.js`],
},
module: {
rules: [
{
test: /\.md$/,
use: [
{
loader: 'vue-loader',
options: vueLoaderOptions,
},
{
loader: 'vue-antd-md-loader',
options: Object.assign(md, {
wrapper: 'div',
raw: true,
}),
},
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderOptions,
},
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: babelConfig,
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
},
},
],
},
resolve:
process.env.NODE_ENV === 'development'
? {
modules: ['node_modules', path.join(__dirname, '../node_modules')],
extensions: ['.js', '.jsx', '.vue', '.md'],
alias: {
vue$: 'vue/dist/vue.esm.js',
'ant-design-vue$': path.join(__dirname, '../../components/index.js'),
'ant-design-vue/es': path.join(__dirname, '../../components'),
'ant-design-vue/lib': path.join(__dirname, '../../components'),
},
}
: {
modules: ['node_modules'],
extensions: ['.js', '.jsx', '.vue', '.md'],
alias: {
vue$: 'vue/dist/vue.esm.js',
},
},
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new VueLoaderPlugin(),
new WebpackBar(),
new HardSourceWebpackPlugin(),
],
};

View File

@ -0,0 +1,59 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const lessLoaderConfig = require('./lessLoaderConfig');
const { createMockMiddleware } = require('umi-mock-middleware');
module.exports = merge(baseWebpackConfig, {
mode: 'development',
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/',
filename: 'build.js',
},
module: {
rules: [
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
},
lessLoaderConfig('development'),
],
},
devServer: {
port: process.env.PORT || 3000,
host: '0.0.0.0',
historyApiFallback: {
rewrites: [{ from: /./, to: '/index.html' }],
},
disableHostCheck: true,
hot: true,
open: true,
headers: { 'Access-Control-Allow-Origin': '*' },
// 解析body对接真实服务端环境需要注释掉
before(app) {
// var bodyParser = require("body-parser");
// app.use(bodyParser.json());
if (process.env.MOCK !== 'none') {
app.use(createMockMiddleware());
}
},
proxy: {
'/api': {
target: 'http://localhost:3000',
},
},
},
performance: {
hints: false,
},
devtool: '#source-map',
plugins: [
new HtmlWebpackPlugin({
template: 'public/index.html',
filename: 'index.html',
inject: true,
}),
],
});

View File

@ -0,0 +1,64 @@
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
let lessLoaderConfig = require('./lessLoaderConfig')('production');
module.exports = merge(baseWebpackConfig, {
output: {
path: path.resolve(__dirname, '../_site'),
publicPath: '/',
filename: '[name].[contenthash:8].js',
chunkFilename: '[contenthash:8].async.js',
},
module: {
rules: [
lessLoaderConfig,
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
},
],
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: `chunk-vendors`,
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial',
},
common: {
name: `chunk-common`,
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true,
},
},
},
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
}),
new HtmlWebpackPlugin({
template: './public/index.html',
inject: true,
production: true,
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
}),
],
});

View File

@ -0,0 +1,124 @@
<script>
const carbonUrls = {
'www.antdv.com': '//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=antdvcom',
// 'tangjinzhou.gitee.io':
// '//cdn.carbonads.com/carbon.js?serve=CK7DL2JN&placement=tangjinzhougiteeio',
// 'ant-design-vue.gitee.io':
// '//cdn.carbonads.com/carbon.js?serve=CK7DL2JN&placement=antdesignvuegiteeio',
'vue.ant.design': '//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=vueantdesign',
};
const carbonUrl =
carbonUrls[location.host] ||
'//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=vueantdesign';
export default {
props: {
isMobile: Boolean,
},
watch: {
$route(e, t) {
let adId = '#carbonads';
// if(isGitee) {
// adId = '#cf';
// }
if (e.path !== t.path && this.$el.querySelector(adId)) {
this.$el.innerHTML = '';
this.load();
}
this.adInterval && clearInterval(this.adInterval);
this.adInterval = setInterval(() => {
if (!this.$el.querySelector(adId)) {
this.$el.innerHTML = '';
this.load();
}
}, 20000);
},
},
mounted() {
this.load();
},
methods: {
load() {
// if(isGitee) {
// axios.get('https://api.codefund.app/properties/162/funder.html?template=horizontal')
// .then(function (response) {
// document.getElementById("codefund-ads").innerHTML = response.data;
// });
// } else
if (carbonUrl) {
const e = document.createElement('script');
e.id = '_carbonads_js';
e.src = carbonUrl;
this.$el.appendChild(e);
}
},
},
render() {
return <div id="carbon-ads" class={this.isMobile ? 'carbon-mobile' : ''} />;
},
};
</script>
<style lang="less">
#carbon-ads {
width: 280px;
float: right;
margin-top: 75px;
position: relative;
right: 0;
bottom: 0;
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;
}
#carbonads {
overflow: hidden;
}
#carbon-ads a {
display: inline-block;
color: #7f8c8d;
font-weight: normal;
}
#carbon-ads span {
color: #7f8c8d;
}
#carbon-ads img {
float: left;
padding-right: 10px;
}
#carbon-ads .carbon-img,
#carbon-ads .carbon-text {
display: block;
font-weight: normal;
color: #34495e;
}
#carbon-ads .carbon-text {
padding-top: 6px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
overflow: hidden;
}
#carbon-ads .carbon-poweredby {
color: #aaa;
font-weight: normal;
line-height: 1.2;
margin-top: 6px;
}
#carbon-ads.carbon-mobile {
width: 100%;
position: relative;
right: 0;
bottom: 0;
padding: 0;
margin-bottom: 15px;
margin-top: 5px;
.carbon-img {
float: left;
margin-right: 10px;
}
}
</style>

View File

@ -0,0 +1,34 @@
<script>
export default {
mounted() {
this.load();
},
methods: {
load() {
if (this.scriptDom) {
this.$el.removeChild(this.scriptDom);
}
this.$refs.ins.innerHTML = '';
const e = document.createElement('script');
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
e.async = true;
this.$el.appendChild(e);
this.scriptDom = e;
(window.adsbygoogle = window.adsbygoogle || []).push({});
},
},
render() {
return (
<div class="google-ads" id="API">
<ins
ref="ins"
class="adsbygoogle"
data-ad-client="ca-pub-4801326429087140"
data-ad-slot="7647023136"
style="display: inline-block; width: 728px; height: 90px"
></ins>
</div>
);
},
};
</script>

View File

@ -0,0 +1,35 @@
<script>
export default {
mounted() {
this.load();
},
methods: {
load() {
if (this.scriptDom) {
this.$el.removeChild(this.scriptDom);
}
this.$refs.ins.innerHTML = '';
const e = document.createElement('script');
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
e.async = true;
this.$el.appendChild(e);
this.scriptDom = e;
(window.adsbygoogle = window.adsbygoogle || []).push({});
},
},
render() {
return (
<div class="google-ads" id="api">
<ins
ref="ins"
style="display:block"
data-ad-client="ca-pub-4801326429087140"
data-ad-slot="3952358732"
data-ad-format="auto"
data-full-width-responsive="true"
></ins>
</div>
);
},
};
</script>

View File

@ -0,0 +1,35 @@
<script>
export default {
mounted() {
this.load();
},
methods: {
load() {
if (this.scriptDom) {
this.$el.removeChild(this.scriptDom);
}
this.$refs.ins.innerHTML = '';
const e = document.createElement('script');
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
e.async = true;
this.$el.appendChild(e);
this.scriptDom = e;
(window.adsbygoogle = window.adsbygoogle || []).push({});
},
},
render() {
return (
<div class="google-ads">
<ins
ref="ins"
style="display:block"
data-ad-client="ca-pub-4801326429087140"
data-ad-slot="9507921838"
data-ad-format="auto"
data-full-width-responsive="true"
></ins>
</div>
);
},
};
</script>

View File

@ -0,0 +1,34 @@
<script>
export default {
mounted() {
this.load();
},
methods: {
load() {
if (this.scriptDom) {
this.$el.removeChild(this.scriptDom);
}
this.$refs.ins.innerHTML = '';
const e = document.createElement('script');
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
e.async = true;
this.$el.appendChild(e);
this.scriptDom = e;
(window.adsbygoogle = window.adsbygoogle || []).push({});
},
},
render() {
return (
<div style="width: 300px;float: right;margin-top: 75px;position: relative;right: 0;bottom: 0;padding: 0;z-index: 9;">
<ins
ref="ins"
class="adsbygoogle"
style="display:inline-block;width:300px;height:100px"
data-ad-client="ca-pub-4801326429087140"
data-ad-slot="2774992529"
></ins>
</div>
);
},
};
</script>

View File

@ -0,0 +1,34 @@
<script>
export default {
mounted() {
this.load();
},
methods: {
load() {
if (this.scriptDom) {
this.$el.removeChild(this.scriptDom);
}
this.$refs.ins.innerHTML = '';
const e = document.createElement('script');
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
e.async = true;
this.$el.appendChild(e);
this.scriptDom = e;
(window.adsbygoogle = window.adsbygoogle || []).push({});
},
},
render() {
return (
<div class="google-ads">
<ins
ref="ins"
class="adsbygoogle"
data-ad-client="ca-pub-4801326429087140"
data-ad-slot="2425414214"
style="display: inline-block; width: 728px; height: 90px"
></ins>
</div>
);
},
};
</script>

View File

@ -0,0 +1,38 @@
<template>
<div id="rice">
<div class="wwads-cn wwads-horizontal" data-id="62" style="max-width: 350px" />
</div>
</template>
<script>
export default {
// mounted() {
// this.load();
// },
// methods: {
// load() {
// if (this.scriptDom) {
// this.$el.removeChild(this.scriptDom);
// }
// this.$refs.inner.innerHTML = '';
// const e = document.createElement('script');
// e.src = 'https://wwads.cn/js/makemoney.js';
// e.async = true;
// this.$el.appendChild(e);
// this.scriptDom = e;
// },
// },
};
</script>
<style scoped>
#rice {
/* width: 180px; */
/* position: fixed; */
/* z-index: 19; */
padding: 10px;
border-radius: 3px;
font-size: 13px;
float: right;
/* background-color: red;
max-height: 150px; */
}
</style>

View File

@ -0,0 +1,27 @@
<template>
<div class="markdown api-container">
<slot v-if="isZhCN" name="cn" />
<slot v-else />
</div>
</template>
<script>
import { isZhCN } from '../utils/util';
import GoogleAds from './GoogleAds';
const showAd = false; // location.host.indexOf('antdv.com') > -1;
export default {
name: 'Api',
components: {
GoogleAds,
},
inject: {
demoContext: { default: {} },
},
data() {
return {
showAd,
isZhCN: isZhCN(this.demoContext.name),
};
},
};
</script>

View File

@ -0,0 +1,230 @@
<template>
<section :id="id" :class="['code-box', codeExpand ? 'expand' : '']">
<section class="code-box-demo">
<template v-if="iframeDemo[iframeDemoKey]">
<div class="browser-mockup with-url">
<iframe :src="iframeDemo[iframeDemoKey]" height="360" />
</div>
</template>
<template v-else>
<slot name="component" />
</template>
</section>
<section class="code-box-meta markdown">
<slot v-if="isZhCN" name="description" />
<slot v-else name="us-description" />
<div class="code-box-actions">
<a-tooltip
:title="copied ? 'Copied!' : 'Copy code'"
:visible="copyTooltipVisible"
@visibleChange="onCopyTooltipVisibleChange"
>
<a-icon
v-clipboard:copy="sourceCode"
v-clipboard:success="handleCodeCopied"
:type="copied && copyTooltipVisible ? 'check' : 'copy'"
class="code-box-code-copy"
/>
</a-tooltip>
<a-tooltip :title="codeExpand ? 'Hide Code' : 'Show Code'">
<span class="code-expand-icon">
<img
width="16"
alt="expand code"
src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
:class="codeExpand ? 'code-expand-icon-hide' : 'code-expand-icon-show'"
@click="handleCodeExpand"
/>
<img
width="16"
alt="expand code"
src="https://gw.alipayobjects.com/zos/rmsportal/OpROPHYqWmrMDBFMZtKF.svg"
:class="codeExpand ? 'code-expand-icon-show' : 'code-expand-icon-hide'"
@click="handleCodeExpand"
/>
</span>
</a-tooltip>
</div>
</section>
<transition appear :css="false" @enter="enter" @leave="leave">
<section
v-show="codeExpand"
class="highlight-wrapper"
style="position: relative;"
v-html="getCode()"
/>
</transition>
</section>
</template>
<script>
import animate from 'ant-design-vue/es/_util/openAnimation';
import BaseMixin from 'ant-design-vue/es/_util/BaseMixin';
import { isZhCN } from '../utils/util';
import { dev } from '../build/config';
export default {
name: 'DemoBox',
mixins: [BaseMixin],
inject: {
iframeDemo: { default: {} },
demoContext: { default: {} },
},
props: {
jsfiddle: Object,
isIframe: Boolean,
},
data() {
window.test = this;
const { name = '' } = this.demoContext;
const { us, cn, sourceCode } = this.jsfiddle;
const usTitle = (us.split('#### ')[1] || '').split('\n')[0] || '';
const cnTitle = (cn.split('#### ')[1] || '').split('\n')[0] || '';
if (process.env.NODE_ENV !== 'production' && usTitle === '') {
throw new Error(`not have usTitle`);
}
const iframeDemoKey = usTitle
.split(' ')
.join('-')
.toLowerCase();
const id = [
'components',
name.replace(/-cn\/?$/, '') || dev.componentName,
'demo',
...usTitle.split(' '),
]
.join('-')
.toLowerCase();
if (this.demoContext.store) {
const { currentSubMenu } = this.demoContext.store.getState();
this.demoContext.store.setState({
currentSubMenu: [...currentSubMenu, { cnTitle, usTitle, id }],
});
}
return {
codeExpand: false,
isZhCN: isZhCN(name),
copied: false,
copyTooltipVisible: false,
sourceCode: decodeURIComponent(escape(window.atob(sourceCode))),
id,
iframeDemoKey,
isDemo: true,
};
},
methods: {
getCode() {
const { $slots } = this;
return decodeURIComponent(
escape(window.atob(($slots.code && $slots.code[0] && $slots.code[0].text) || '')),
);
},
handleCodeExpand() {
this.codeExpand = !this.codeExpand;
},
enter: animate.enter,
leave: animate.leave,
handleCodeCopied() {
this.setState({ copied: true });
},
onCopyTooltipVisibleChange(visible) {
if (visible) {
this.setState({
copyTooltipVisible: visible,
copied: false,
});
return;
}
this.setState({
copyTooltipVisible: visible,
});
},
},
};
</script>
<style scoped lang="less">
.box-demo {
padding: 0;
border: 1px solid #e9e9e9;
border-radius: 4px;
box-shadow: none;
margin-top: 20px;
margin-bottom: 20px;
}
.box-demo-show {
padding: 20px 25px 30px;
border-bottom: 1px solid #e9e9e9;
}
.box-demo-description {
position: relative;
padding: 17px 16px 15px 20px;
border-radius: 0 0 6px 6px;
-webkit-transition: background-color 0.4s ease;
transition: background-color 0.4s ease;
width: 100%;
font-size: 12px;
&.bordered {
border-bottom: 1px dashed #e9e9e9;
}
h3,
h4 {
position: absolute;
top: -14px;
padding: 1px 8px;
margin-left: -8px;
margin-top: 0;
margin-bottom: 0;
color: #777;
border-radius: 4px;
border-top-left-radius: 0;
background: #fff;
-webkit-transition: background-color 0.4s ease;
transition: background-color 0.4s ease;
.header-anchor {
display: none;
}
}
li {
line-height: 21px;
}
}
.box-demo-code {
-webkit-transition: height 0.2s ease-in-out;
transition: height 0.2s ease-in-out;
overflow: auto;
border-top: 1px dashed #e9e9e9;
pre {
margin: 0;
}
code {
margin: 0;
background: #f7f7f7;
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.9em;
border: 1px solid #eee;
}
}
.btn-toggle {
position: absolute;
right: 16px;
bottom: 17px;
cursor: pointer;
width: 18px;
height: 18px;
font-size: 18px;
line-height: 18px;
color: #999;
i {
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
&.open {
i {
-webkit-transform: rotate(-180deg);
-ms-transform: rotate(-180deg);
transform: rotate(-180deg);
}
}
}
</style>

View File

@ -0,0 +1,82 @@
<template>
<div>
<demo-box :jsfiddle="jsfiddle">
<template slot="component">
<slot />
</template>
<template slot="description">
<div class="demo-description" v-html="cnHtml" />
</template>
<template slot="us-description">
<div class="demo-description" v-html="usHtml" />
</template>
<template slot="code">
{{ codeStr }}
</template>
</demo-box>
</div>
</template>
<script>
import marked from 'marked';
import Prism from 'prismjs';
import 'prismjs/components/prism-jsx.min.js';
import 'prismjs/components/prism-bash.min.js';
const replaceDelimiters = function(str) {
return str.replace(/({{|}})/g, '<span>$1</span>');
};
const renderHighlight = function(str, lang) {
if (!(lang && Prism.languages[lang])) {
return '';
}
try {
return replaceDelimiters(Prism.highlight(str, Prism.languages[lang], lang));
} catch (err) {}
};
const renderer = new marked.Renderer();
renderer.heading = function(text, level) {
return (
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
);
};
marked.setOptions({
renderer,
gfm: true,
tables: true,
breaks: true,
pedantic: true,
sanitize: true,
smartLists: true,
smartypants: true,
html: true,
highlight: renderHighlight,
});
const cnReg = /<cn>([\S\s\t]*?)<\/cn>/;
const usReg = /<us>([\S\s\t]*?)<\/us>/;
export default {
name: 'DemoContainer',
props: ['code'],
data() {
const cn = this.code.match(cnReg) || [];
const us = this.code.match(usReg) || [];
const cnHtml = marked(cn[1].trim());
const usHtml = marked(us[1].trim());
const sourceCode = this.code
.replace(cn[0], '')
.replace(us[0], '')
.trim();
const codeHtml = marked('```html\n' + sourceCode + '```');
return {
codeStr: window.btoa(unescape(encodeURIComponent(codeHtml))),
cnHtml,
usHtml,
jsfiddle: {
sourceCode: window.btoa(unescape(encodeURIComponent(sourceCode))),
cn: cn[1].trim(),
us: us[1].trim(),
},
};
},
};
</script>

View File

@ -0,0 +1,49 @@
import { Col, Row } from '../../components/grid';
import '../../components/grid/style';
function isEmptyElement(c) {
return !(c.tag || (c.text && c.text.trim() !== ''));
}
function filterEmpty(children = []) {
return children.filter(c => !isEmptyElement(c));
}
export default {
props: {
cols: {
type: [Number, String],
default: 2,
},
},
inject: {
demoContext: { default: {} },
},
render() {
const { cols, $slots } = this;
const isSingleCol = cols === 1;
const leftChildren = [];
const rightChildren = [];
const children = filterEmpty($slots.default);
children.forEach((demo, index) => {
if (index % 2 === 0 || isSingleCol) {
leftChildren.push(demo);
} else {
rightChildren.push(demo);
}
});
return (
<Row gutter={16}>
<Col
span={isSingleCol ? 24 : 12}
class={isSingleCol ? 'code-boxes-col-1-1' : 'code-boxes-col-2-1'}
>
{leftChildren}
</Col>
{isSingleCol ? null : (
<Col class="code-boxes-col-2-1" span={12}>
{rightChildren}
</Col>
)}
</Row>
);
},
};

View File

@ -0,0 +1,145 @@
<script>
import moment from 'moment';
export default {
props: {
isCN: Boolean,
},
render() {
const isCN = this.isCN;
const showJeecg = moment().isBefore(moment('2023-09-10'));
return (
<footer id="footer">
<div class="footer-wrap">
<a-row>
<a-col md={6} sm={24} xs={24}>
<div class="footer-center">
<h2>Ant Design</h2>
<div>
<a href="https://github.com/vueComponent/ant-design-vue" target="_blank ">
<span>GitHub</span>
</a>
<span></span>
<span>
<i class="anticon anticon-github"></i>
</span>
</div>
<div>
<a href="https://ant.design/docs/react/introduce-cn" target="_blank">
Ant Design
</a>
<span> - </span>
<span>React</span>
</div>
<div>
<a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank">
Ant Design
</a>
<span> - </span>
<span>Angular</span>
</div>
<div>
<a href="https://github.com/websemantics/awesome-ant-design" target="_blank ">
<span>Awesome Ant Design</span>
</a>
</div>
<div>
<a href="http://library.ant.design/" rel="noopener noreferrer" target="_blank">
AntD Library
</a>
</div>
</div>
</a-col>
<a-col md={6} sm={24} xs={24}>
<div class="footer-center">
<h2>{isCN ? '社区' : 'Community'}</h2>
{isCN ? (
<div>
<a href="https://zhuanlan.zhihu.com/ant-design-vue" target="_blank">
<span>知乎专栏</span>
</a>
</div>
) : (
''
)}
<div>
<a href="https://github.com/vueComponent/ant-design-vue/releases" target="_blank">
<span>{isCN ? '更新记录' : 'Change Log'}</span>
</a>
</div>
<div>
<a
rel="noopener noreferrer"
target="_blank"
href={`https://vuecomponent.github.io/issue-helper/${isCN ? '?lang=zh' : ''}`}
>
<span>{isCN ? '报告 Bug' : 'Bug Report'}</span>
</a>
</div>
</div>
</a-col>
<a-col md={6} sm={24} xs={24}>
<div class="footer-center">
<h2>{isCN ? '友情链接' : 'Links'}</h2>
{showJeecg && (
<div>
<a href="http://www.jeecg.com/" target="_blank">
Jeecg
</a>
</div>
)}
<div>
<a href="https://cn.vuejs.org/" target="_blank">
Vue
</a>
</div>
<div>
<a href="https://cli.vuejs.org/" target="_blank">
Vue CLI
</a>
</div>
<div>
<a href="https://antdv.formilyjs.org/" target="_blank">
@formily/antdv
</a>
</div>
</div>
</a-col>
<a-col md={6} sm={24} xs={24}>
<div class="footer-center">
<h2>
<img
alt=""
class="title-icon"
src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg"
/>
<span>{isCN ? '更多产品' : 'More Products'}</span>
</h2>
<div>
<a href="https://antv.alipay.com/" rel="noopener noreferrer" target="_blank">
AntV
</a>
<span> - </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>
</a-col>
</a-row>
</div>
<div style="padding: 10px 144px;">
备案号
<a href="http://beian.miit.gov.cn/" target="_blank">
浙ICP备19034671号
</a>
</div>
</footer>
);
},
};
</script>

View File

@ -0,0 +1,41 @@
<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://qn.antdv.com/geektime-vue.jpeg" />
</a>
<div class="close" @click="visible = false">
<a-icon type="close" />
</div>
</div>
</template>
<script>
export default {
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,60 @@
<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://qn.antdv.com/chongxueqianduan.jpg" />
</a>
</div>
</template>
<script>
import moment from 'moment';
export default {
props: ['isMobile'],
data() {
return {
visible: true,
effectiveTime: {
start: '2019-08-05 17:00:00',
end: '2019-09-05 17:00:00',
},
};
},
methods: {
isEffective({ start, end }) {
return moment().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

@ -0,0 +1,299 @@
<script>
import { isZhCN } from '../utils/util';
import docsearch from 'docsearch.js';
import packageInfo from '../../package.json';
import logo from '../public/logo.svg';
import antDesignVue from '../public/ant-design-vue.svg';
export default {
inject: {
demoContext: { default: {} },
},
props: {
name: String,
searchData: Array,
},
data() {
return {
visibleAdblockBanner: !!this.demoContext.blocked,
value: null,
showTopBanner: false,
};
},
watch: {
'demoContex.blocked': function blocked(val) {
this.visibleAdblockBanner = !!val;
},
},
mounted() {
this.initDocSearch(this.$i18n.locale);
},
methods: {
handleClose(key) {
localStorage.removeItem(`notification-key-${key}`);
localStorage.setItem(`notification-key-${key}`, true);
this.showTopBanner = false;
},
initDocSearch(locale) {
docsearch({
apiKey: '92003c1d1d07beef165b08446f4224a3',
indexName: 'antdv',
inputSelector: '#search-box input',
algoliaOptions: { facetFilters: [isZhCN(locale) ? 'cn' : 'en'] },
transformData(hits) {
hits.forEach(hit => {
hit.url = hit.url.replace('www.antdv.com', window.location.host);
hit.url = hit.url.replace('https:', window.location.protocol);
});
return hits;
},
debug: false, // Set debug to true if you want to inspect the dropdown
});
},
handleClick() {
const name = this.name;
const path = this.$route.path;
const newName = isZhCN(name) ? name.replace(/-cn\/?$/, '') : `${name}-cn`;
this.$router.push({
path: path.replace(name, newName),
});
this.$i18n.locale = isZhCN(name) ? 'en-US' : 'zh-CN';
},
onSelect(val) {
this.$router.push(val);
this.value = val;
},
closeTopBanner() {},
changeVersion(v) {
location.href = `https://${v}.antdv.com${this.$route.fullPath}`;
},
},
render() {
const name = this.name;
const visibleAdblockBanner = false; // this.visibleAdblockBanner;
const isCN = isZhCN(name);
const path = this.$route.path;
const selectedKeys = path === '/jobs/list-cn' ? ['jobs'] : ['components'];
return (
<header id="header">
{visibleAdblockBanner && (
<div class="adblock-banner">
{isZhCN
? '我们检测到你可能使用了 AdBlock 或 Adblock Plus它会影响到正常功能的使用如复制、展开代码等。'
: '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 />
{isZhCN
? '你可以将 Ant Design Vue 加入白名单,以便我们更好地提供服务。'
: 'You can add Ant Design Vue to the whitelist so that we can provide better services.'}
<CloseOutlined class="close-icon" onClick={() => (this.visibleAdblockBanner = false)} />
</div>
)}
{/* {!isCN && this.showTopBanner && (
<div class="global-notification">
<span>
v3 beta is out! Discover more about it on &nbsp;
<a href="https://next.antdv.com/" target="_blank">
next.antdv.com
</a>
&nbsp;
</span>
<a-icon
type="close"
style="position: absolute;top: 8px;right: 15px;"
onClick={() => this.handleClose('next')}
/>
</div>
)} */}
<a-row>
<a-col class="header-left" xxl={4} xl={5} lg={5} md={6} sm={24} xs={24}>
<router-link to={{ path: '/' }} id="logo">
<img alt="logo" height="32" src={logo} />
<img alt="logo" height="16" src={antDesignVue} />
</router-link>
<a-button
ghost
size="small"
onClick={this.handleClick}
class="header-lang-button"
key="lang-button"
>
{isCN ? 'English' : '中文'}
</a-button>
</a-col>
<a-col xxl={20} xl={19} lg={19} md={18} sm={0} xs={0}>
<div id="search-box">
<a-icon type="search" />
<a-input
placeholder={isCN ? '搜索组件...' : 'input search text'}
style="width: 200px"
/>
</div>
<span id="github-btn" class="github-btn">
<a class="gh-btn" href="//github.com/vueComponent/ant-design-vue/" target="_blank">
<span class="gh-ico" aria-hidden="true"></span>
<span class="gh-text">Star</span>
</a>
</span>
<a-button
ghost
size="small"
onClick={this.handleClick}
class="header-lang-button"
key="lang-button"
>
{isCN ? 'English' : '中文'}
</a-button>
<a-select size="small" defaultValue={packageInfo.version} class="version">
<a-select-option value={packageInfo.version}>{packageInfo.version}</a-select-option>
<a-select-option value="2.x" onClick={() => this.changeVersion('2x')}>
v2 LST
</a-select-option>
<a-select-option value="www" onClick={() => this.changeVersion('www')}>
v3 Current (Latest Features)
</a-select-option>
</a-select>
<a-menu selectedKeys={selectedKeys} mode="horizontal" class="menu-site" id="nav">
<a-menu-item key="components">
<router-link to="/docs/vue/introduce">{isCN ? '组件' : 'Components'}</router-link>
</a-menu-item>
<a-sub-menu
v-if="isZhCN"
key="advanced"
title={
<span style="position: relative">
高级组件
<a-badge color="red" style="position: absolute; top: -35px; right: -15px" />
</span>
}
>
<a-menu-item key="surely-table">
<a
href="https://www.surely.cool"
target="_blank"
rel="noopener noreferrer"
style="position: relative;"
>
Surely Table
</a>
</a-menu-item>
</a-sub-menu>
{isCN ? (
<a-menu-item key="store">
<a
href="https://store.antdv.com/pro/"
target="_blank"
style="position: relative;"
>
商店
</a>
</a-menu-item>
) : (
<a-menu-item key="store">
<a
href="https://store.antdv.com/pro/?lang=en"
target="_blank"
style="position: relative;"
>
Store{' '}
</a>
</a-menu-item>
)}
{isCN ? (
<a-menu-item key="geektime">
<a
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
target="_blank"
style="position: relative;"
>
Vue 实战教程
</a>
</a-menu-item>
) : null}
<a-menu-item key="sponsor">
<router-link to={{ path: isCN ? '/docs/vue/sponsor-cn/' : '/docs/vue/sponsor/' }}>
{isCN ? '支持我们' : 'Support us'}
</router-link>
</a-menu-item>
<a-sub-menu key="Ecosystem" title={isCN ? '更多' : 'More'}>
<a-menu-item key="pro">
<a target="_blank" href="https://pro.antdv.com">
Pro (Admin)
</a>
</a-menu-item>
<a-menu-item key="vip">
<a target="_blank" href="https://store.antdv.com/pro/">
Pro For VIP
</a>
</a-menu-item>
<a-menu-item key="design">
<router-link
to={{ path: isCN ? '/docs/vue/download-cn/' : '/docs/vue/download/' }}
>
{isCN ? '设计资源' : 'Design Resources'}
</router-link>
</a-menu-item>
<a-menu-item key="vscode">
<a
target="_blank"
href="https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper"
>
VS Code Extension
</a>
</a-menu-item>
<a-menu-item key="awesome">
<a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">
Awesome
</a>
</a-menu-item>
<a-menu-item key="qq1">
<a>QQ 1(217490093) 已满</a>
</a-menu-item>
<a-menu-item key="qq2">
<a>QQ 2(809774695) 已满</a>
</a-menu-item>
<a-menu-item key="qq3">
<a>QQ 3(927828249)</a>
</a-menu-item>
</a-sub-menu>
</a-menu>
</a-col>
</a-row>
</header>
);
},
};
</script>
<style scope>
.adblock-banner {
position: relative;
z-index: 100;
min-width: 1000px;
padding: 16px;
line-height: 28px;
color: #8590a6;
text-align: center;
background-color: #ebebeb;
}
.close-icon {
position: absolute;
top: 15px;
right: 15px;
}
.global-notification {
text-align: center;
background: #001529;
padding: 20px 0;
font-size: 16px;
position: fixed;
bottom: 0;
width: 100%;
color: #fff;
z-index: 99;
}
.global-notification a {
color: #177ddc;
}
</style>

View File

@ -0,0 +1,30 @@
<script>
// import * as AllDemo from '../demo'
export default {
props: {
name: String,
hash: String,
},
provide() {
return {
demoContext: this,
};
},
render() {
// const name = this.name
// const titleMap = {}
// for (const [title] of Object.entries(AllDemo)) {
// const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`
// titleMap[key] = title
// }
// const Demo = AllDemo[titleMap[name.replace(/-cn\/?$/, '')]]
// const hash = this.$route.hash.replace('#', '')
return (
<div id="iframe-page">
<router-view></router-view>
</div>
);
},
};
</script>

View File

@ -0,0 +1,375 @@
<script>
import { enquireScreen } from 'enquire-js';
import AllDemo from '../site/demo';
import Header from './header';
import Footer from './footer';
// import Geektime from './geektime';
import GeektimeAds from './geektime_ads';
import RightBottomAd from './right_bottom_ad';
// import Sponsors from './sponsors';
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN';
import enUS from 'ant-design-vue/es/locale-provider/default';
import sortBy from 'lodash/sortBy';
import { isZhCN } from '../utils/util';
import { Provider, create } from '../../components/_util/store';
import NProgress from 'nprogress';
import MobileMenu from '../../components/vc-drawer/src';
import WWAds from './WWAds.vue';
import GoogleAds from './GoogleAds';
import SurelyVue from './surelyVue';
const docsList = [
{ key: 'introduce', enTitle: 'Ant Design of Vue', title: 'Ant Design of Vue' },
{ key: 'getting-started', enTitle: 'Getting Started', title: '快速上手' },
{ key: 'use-with-vue-cli', enTitle: 'Use in vue-cli', title: '在 vue-cli 中使用' },
{ key: 'customize-theme', enTitle: 'Customize Theme', title: '定制主题' },
{ key: 'changelog', enTitle: 'Change Log', title: '更新日志' },
{ key: 'i18n', enTitle: 'Internationalization', title: '国际化' },
{ key: 'faq', enTitle: 'FAQ', title: '常见问题' },
{ key: 'sponsor', enTitle: 'Sponsor', title: '支持我们' },
{ key: 'download', enTitle: 'Download Design Resources', title: '下载设计资源' },
];
const isGitee = window.location.host.indexOf('gitee.io') > -1;
const showAd = false; // location.host.indexOf('antdv.com') > -1;
export default {
provide() {
return {
demoContext: this,
};
},
props: {
name: String,
showDemo: Boolean,
showApi: Boolean,
},
data() {
this.store = create({
currentSubMenu: [],
});
this.subscribe();
let blocked = false;
setTimeout(() => {
const div = document.createElement('div');
div.className = 'adsbox';
document.body.appendChild(div);
blocked = 'none' === getComputedStyle(div).display;
}, 300);
return {
showSideBars: true,
currentSubMenu: [],
sidebarHeight: document.documentElement.offsetHeight,
isMobile: false,
blocked,
};
},
watch: {
'$route.path'() {
this.store.setState({ currentSubMenu: [] });
this.addSubMenu();
},
},
beforeDestroy() {
if (this.unsubscribe) {
this.unsubscribe();
}
clearTimeout(this.timer);
if (this.resizeEvent) {
this.resizeEvent.remove();
}
if (this.debouncedResize && this.debouncedResize.cancel) {
this.debouncedResize.cancel();
}
},
mounted() {
if (isGitee) {
this.$info({
title: '提示',
content: '访问国内镜像站点的用户请访问 antdv.com 站点',
okText: '立即跳转',
onOk() {
location.href = 'https://www.antdv.com';
},
});
}
this.$nextTick(() => {
this.addSubMenu();
const nprogressHiddenStyle = document.getElementById('nprogress-style');
if (nprogressHiddenStyle) {
this.timer = setTimeout(() => {
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
}, 0);
}
enquireScreen(b => {
this.isMobile = !!b;
});
});
},
methods: {
addSubMenu() {
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
this.$nextTick(() => {
const menus = [];
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])];
doms.forEach(dom => {
const id = dom.id;
if (id) {
const title = dom.textContent.split('#')[0].trim();
menus.push({ cnTitle: title, usTitle: title, id });
}
});
this.currentSubMenu = menus;
});
}
},
subscribe() {
const { store } = this;
this.unsubscribe = store.subscribe(() => {
this.currentSubMenu = this.store.getState().currentSubMenu;
});
},
getSubMenu(isCN) {
const currentSubMenu = this.currentSubMenu;
const lis = [];
currentSubMenu.forEach(({ cnTitle, usTitle, id }, index) => {
const title = isCN ? cnTitle : usTitle;
lis.push(<a-anchor-link key={id + index} href={`#${id}`} title={title} />);
});
const showApi = this.$route.path.indexOf('/components/') !== -1;
return (
<a-anchor offsetTop={100} class="demo-anchor">
{lis}
{showApi ? <a-anchor-link key="API" title="API" href="#API" /> : ''}
</a-anchor>
);
},
getDocsMenu(isCN, pagesKey) {
const docsMenu = [];
docsList.forEach(({ key, enTitle, title }) => {
const k = isCN ? `${key}-cn` : key;
pagesKey.push({ name: k, url: `/docs/vue/${k}/`, title: isCN ? title : enTitle });
docsMenu.push(
<a-menu-item key={k}>
<router-link to={`/docs/vue/${k}/`}>{isCN ? title : enTitle}</router-link>
</a-menu-item>,
);
});
return docsMenu;
},
resetDocumentTitle(component, name, isCN) {
let titleStr = 'Ant Design Vue';
if (component) {
const { subtitle, title } = component;
const componentName = isCN ? subtitle + ' ' + title : title;
titleStr = componentName + ' - ' + titleStr;
} else {
const currentKey = docsList.filter(item => {
return item.key === name;
});
if (currentKey.length) {
titleStr = (isCN ? currentKey[0]['title'] : currentKey[0]['enTitle']) + ' - ' + titleStr;
}
}
document.title = titleStr;
},
mountedCallback() {
NProgress.done();
document.documentElement.scrollTop = 0;
},
},
render() {
const name = this.name;
const isCN = isZhCN(name);
const titleMap = {};
const menuConfig = {
General: [],
Layout: [],
Navigation: [],
'Data Entry': [],
'Data Display': [],
Feedback: [],
Other: [],
};
const pagesKey = [];
let prevPage = null;
let nextPage = null;
const searchData = [];
for (const [title, d] of Object.entries(AllDemo)) {
const type = d.type || 'Other';
const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`;
titleMap[key] = title;
AllDemo[title].key = key;
menuConfig[type] = menuConfig[type] || [];
menuConfig[type].push(d);
}
const docsMenu = this.getDocsMenu(isCN, pagesKey);
const reName = name.replace(/-cn\/?$/, '');
const MenuGroup = [];
for (const [type, menus] of Object.entries(menuConfig)) {
const MenuItems = [];
sortBy(menus, ['title']).forEach(({ title, subtitle, key }) => {
const linkValue = isCN
? [<span>{title}</span>, <span class="chinese">{subtitle}</span>]
: [<span>{title}</span>];
if (isCN) {
key = `${key}-cn`;
}
pagesKey.push({
name: key,
url: `/components/${key}/`,
title: isCN ? `${title} ${subtitle}` : title,
});
searchData.push({
title,
subtitle,
url: `/components/${key}/`,
});
MenuItems.push(
<a-menu-item key={key}>
<router-link to={`/components/${key}/`}>{linkValue}</router-link>
</a-menu-item>,
);
});
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>);
}
pagesKey.forEach((item, index) => {
if (item.name === name) {
prevPage = pagesKey[index - 1];
nextPage = pagesKey[index + 1];
}
});
let locale = zhCN;
if (!isCN) {
locale = enUS;
}
const config = AllDemo[titleMap[reName]];
this.resetDocumentTitle(config, reName, isCN);
const { isMobile, $route } = this;
return (
<div class="page-wrapper">
<Header searchData={searchData} name={name} />
<a-config-provider locale={locale}>
<div class="main-wrapper">
<a-row>
{isMobile ? (
<MobileMenu ref="sidebar" wrapperClassName="drawer-wrapper">
<SurelyVue />
<a-menu
class="aside-container menu-site"
selectedKeys={[name]}
defaultOpenKeys={['Components']}
inlineIndent={40}
mode="inline"
>
{docsMenu}
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
{MenuGroup}
</a-sub-menu>
</a-menu>
</MobileMenu>
) : (
<a-col
ref="sidebar"
class="site-sidebar main-menu"
xxl={4}
xl={5}
lg={5}
md={6}
sm={8}
xs={12}
>
<a-affix>
<section class="main-menu-inner">
<SurelyVue />
<a-menu
class="aside-container menu-site"
selectedKeys={[name]}
defaultOpenKeys={['Components']}
inlineIndent={40}
mode="inline"
>
{docsMenu}
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
{MenuGroup}
</a-sub-menu>
</a-menu>
</section>
</a-affix>
</a-col>
)}
<a-col xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
<section class="main-container main-container-component">
{showAd ? <GeektimeAds isMobile={isMobile} /> : null}
<WWAds />
{!isMobile ? (
<div class={['toc-affix', isCN ? 'toc-affix-cn' : '']} style="width: 150px;">
{this.getSubMenu(isCN)}
</div>
) : null}
{this.showDemo ? (
<Provider store={this.store} key={isCN ? 'cn' : 'en'}>
<router-view
class={`demo-cols-${config.cols || 2}`}
{...{
directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
],
}}
></router-view>
</Provider>
) : (
''
)}
{this.showApi ? (
<div class="markdown api-container" ref="doc">
<router-view
{...{
directives: [
{
name: 'mountedCallback',
value: this.mountedCallback,
},
],
}}
></router-view>
</div>
) : (
''
)}
</section>
<section class="prev-next-nav">
{prevPage ? (
<router-link class="prev-page" to={`${prevPage.url}`}>
<a-icon type="left" />
&nbsp;&nbsp;{prevPage.title}
</router-link>
) : (
''
)}
{nextPage ? (
<router-link class="next-page" to={`${nextPage.url}`}>
{nextPage.title}&nbsp;&nbsp;
<a-icon type="right" />
</router-link>
) : (
''
)}
</section>
<Footer ref="footer" isCN={isCN} />
</a-col>
</a-row>
</div>
</a-config-provider>
{name.indexOf('back-top') === -1 ? <a-back-top /> : null}
<RightBottomAd isCN={isCN} isMobile={isMobile} />
</div>
);
},
};
</script>

View File

@ -0,0 +1,51 @@
<template>
<div class="markdown" v-html="marked(text)" />
</template>
<script>
import marked from 'marked';
import { isZhCN } from '../utils/util';
const renderer = new marked.Renderer();
renderer.heading = function(text, level) {
return (
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
);
};
marked.setOptions({
renderer,
gfm: true,
tables: true,
breaks: true,
pedantic: true,
sanitize: true,
smartLists: true,
smartypants: true,
});
export default {
name: 'Md',
props: {
cn: String,
us: String,
},
inject: {
demoContext: { default: {} },
},
data() {
let text = '';
const { cn, us } = this;
if (this.$slots.default && this.$slots.default[0] && this.$slots.default[0].text) {
text = this.$slots.default[0].text;
} else {
text = isZhCN(this.demoContext.name) ? cn : us;
}
text = text || '';
text = text
.split('\n')
.map(t => t.trim())
.join('\n');
return {
marked,
text,
};
},
};
</script>

View File

@ -0,0 +1,61 @@
<template>
<div v-if="isCN" id="right-bottom">
<img width="150" :src="`https://next.antdv.com/common_rice.png?v=${v}`" />
<div v-if="isMobile" class="close" @click="visible = false">
<a-icon type="close" />
</div>
<!-- <span v-if="isCN">广</span> -->
</div>
</template>
<script>
import moment from 'moment';
const isEffective = (start, end) => {
return moment().isBetween(start, end);
};
export default {
components: {},
props: ['isCN', 'isMobile'],
data() {
return {
isEffective,
visible: true,
v: moment().date(),
ads: [
{
alt: 'geektime',
img: 'https://qn.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://qn.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'),
},
],
};
},
};
</script>
<style lang="less" scoped>
#right-bottom {
position: fixed;
bottom: 10px;
right: 10px;
width: 150px;
border-radius: 5px;
overflow: hidden;
.close {
position: absolute;
text-align: center;
top: -8px;
right: -8px;
font-size: 16px;
padding: 15px;
color: #6e3041;
}
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<div class="snd-ad">
<div class="sponsorsWrap">
<span v-if="!isCN" class="sponsorsTitle">
{{ isCN ? '赞助商' : 'Sponsors' }}
</span>
<ul>
<!-- <li class="sponsorsItem">
<a href="https://tipe.io/?ref=ant-design-vue" target="_blank">
<img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" />
</a>
</li> -->
<li v-if="isCN && isEffective(effectiveTime.kkb)" class="sponsorsItem">
<a href="https://datayi.cn/w/Y9J3M2vR" target="_blank">
<img height="66" src="https://qn.antdv.com/kaikeba_ssr.jpeg" alt="kaikeba">
</a>
<span style="position: absolute; top: 0px;right: 10px">广告</span>
</li>
<!-- <li class="sponsorsItem">
<a-button type="primary" ghost style="font-size: 12px" @click="handleClick">
{{ isCN ? '成为赞助商' : 'Become a Sponsor' }}
</a-button>
</li> -->
</ul>
</div>
<a-modal v-model="visible" title="成为赞助商" @ok="visible = false">
如果您有品牌推广活动推广招聘推广社区合作等需求欢迎联系我们成为赞助商<br>
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面<br>
咨询邮箱<a href="mailto:antdv@foxmail.com">antdv@foxmail.com</a><br>
</a-modal>
</div>
</template>
<script>
import moment from 'moment';
export default {
props: ['isCN'],
data() {
return {
top: 50,
effectiveTime: {
bmatch: {
start: '2019-03-11',
end: '2019-06-11',
},
kkb: {
start: '2020-11-16 22:00:00',
end: '2021-05-17 22:00:00',
},
},
visible: false,
};
},
methods: {
isEffective({ start, end }) {
return moment().isBetween(start, end);
},
handleClick() {
if (this.isCN) {
this.visible = true;
} else {
window.open('https://opencollective.com/ant-design-vue#sponsor');
}
},
},
};
</script>

View File

@ -0,0 +1,81 @@
<template>
<div>
<div class="container">
<a-carousel autoplay>
<a style="display: inline-block" href="https://www.surelyvue.com/" target="_blank">
<div :class="cls">
<div class="logo">
<img height="80" src="https://www.surelyvue.com/surely-vue-logo.png" alt="" />
</div>
<div class="desc">
<div class="title">Surely Table</div>
<div class="sub-title">
构建更快的网站
<br />
更快的构建网站
</div>
</div>
</div>
</a>
</a-carousel>
</div>
<div class="placeholder" />
</div>
</template>
<script>
export default {
props: {
type: String,
},
data() {
return {
cls: {
wrap: true,
[`wrap-${this.type}`]: true,
},
};
},
};
</script>
<style scoped>
.container {
position: absolute;
top: 0;
left: 0;
z-index: 9;
width: 100%;
height: 100px;
}
.wrap {
display: flex;
background-color: #f4f8fa;
padding: 8px 16px;
width: 100%;
height: 100px;
overflow: hidden;
}
.logo {
width: 80px;
display: flex;
align-items: center;
justify-content: center;
}
.placeholder {
height: 100px;
}
.desc {
margin-left: 16px;
overflow: hidden;
color: rgba(0, 0, 0, 0.85);
font-family: Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji', sans-serif;
}
.title {
font-size: 18px;
}
.sub-title {
opacity: 0.7;
margin-top: 5px;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div>
<template v-if="ads.length">
<a-carousel autoplay>
<template v-for="ad in ads">
<a :key="ad.href" :href="ad.href" target="_blank">
<img style="width: 100%; max-width: 1200px" :alt="ad.alt || ''" :src="ad.img" />
</a>
</template>
</a-carousel>
</template>
<template v-else-if="showGoogleAd">
<template v-if="isCN">
<WWAds :key="`WWAds_${$route.path}`" />
</template>
</template>
</div>
</template>
<script>
import moment from 'moment';
import GoogleAdsTop from './GoogleAdsTop';
import WWAds from './WWAds.vue';
const isEffective = (start, end) => {
return moment().isBetween(start, end);
};
export default {
components: {
GoogleAdsTop,
WWAds,
},
props: ['isCN', 'isMobile'],
data() {
return {
showGoogleAd: location.host.indexOf('antdv.com') > -1,
cnAds: [
{
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`,
href: 'https://yidengfe.com/launches/01/yd.html',
visible: isEffective('2020-09-11 17:00:00', '2021-03-11 17:00:00'),
},
].filter(ad => ad.visible),
enAds: [
{
img: 'https://qn.antdv.com/TheBigRichGroup.png',
href: 'https://thebigrichgroup.com/',
visible: isEffective('2020-09-18 17:00:00', '2021-07-11 17:00:00'),
},
].filter(ad => ad.visible),
};
},
computed: {
ads() {
return this.isCN ? this.cnAds : this.enAds;
},
},
};
</script>
<style lang="less" scoped></style>

View File

@ -0,0 +1,38 @@
<cn>
#### 基本
最简单的用法。
</cn>
<us>
#### basic
The simplest usage.
</us>
```vue
<template>
<div>
<a-affix :offset-top="top">
<a-button type="primary" @click="top += 10">
Affix top
</a-button>
</a-affix>
<br />
<a-affix :offset-bottom="bottom">
<a-button type="primary" @click="bottom += 10">
Affix bottom
</a-button>
</a-affix>
</div>
</template>
<script>
export default {
data() {
return {
top: 10,
bottom: 10,
};
},
};
</script>
```

View File

@ -0,0 +1,44 @@
<script>
import Basic from './basic';
import Onchange from './on-change';
import Target from './target';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# Affix 固钉
将页面元素钉在可视范围
## 何时使用
当内容区域比较长需要滚动页面时这部分内容对应的操作或者导航需要在滚动范围内始终展现常用于侧边菜单和按钮组合
页面可视范围过小时慎用此功能以免遮挡页面内容
## 代码演示`,
us: `# Affix
Make an element stick to viewport.
## When To Use
When user browses a long web page, some content need to stick to the viewport. This is common for menus and actions.
Please note that Affix should not cover other content on the page, especially when the size of the viewport is small.
## Examples `,
};
export default {
category: 'Components',
subtitle: '固钉',
zhType: '导航',
type: 'Navigation',
title: 'Affix',
render() {
return (
<div>
<md cn={md.cn} us={md.us} />
<demo-sort>
<Basic />
<Onchange />
<Target />
</demo-sort>
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>

View File

@ -0,0 +1,26 @@
<cn>
#### 固定状态改变的回调
可以获得是否固定的状态。
</cn>
<us>
#### Callback
Callback with affixed state.
</us>
```vue
<template>
<a-affix :offset-top="120" @change="change">
<a-button>120px to affix top</a-button>
</a-affix>
</template>
<script>
export default {
methods: {
change(affixed) {
console.log(affixed);
},
},
};
</script>
```

View File

@ -0,0 +1,34 @@
<cn>
#### 滚动容器
`target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`
</cn>
<us>
#### Container to scroll.
Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`).
</us>
```vue
<template>
<div id="components-affix-demo-target" ref="container" class="scrollable-container">
<div class="background">
<a-affix :target="() => this.$refs.container">
<a-button type="primary">
Fixed at the top of container
</a-button>
</a-affix>
</div>
</div>
</template>
<style>
#components-affix-demo-target.scrollable-container {
height: 100px;
overflow-y: scroll;
}
#components-affix-demo-target .background {
padding-top: 60px;
height: 300px;
background-image: url('https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg');
}
</style>
```

View File

@ -0,0 +1,29 @@
## API
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - | |
| offsetTop | Offset from the top of the viewport (in pixels) | number | 0 | |
| target | Specifies the scrollable area DOM node | () => HTMLElement | () => window | |
### events
| Events Name | Description | Arguments | Version |
| ----------- | ---------------------------------------- | ----------------- | ------- |
| change | Callback for when Affix state is changed | Function(affixed) |
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:
```html
<a-affix :style="{ position: 'absolute', top: y, left: x}">
...
</a-affix>
```
## FAQ
### Affix bind container with `target`, sometime move out of container.
We don't listen window scroll for performance consideration.
Related issues[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)

View File

@ -0,0 +1,29 @@
## API
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | |
### 事件
| 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | ---------------------------- | ----------------- | ---- |
| change | 固定状态改变时触发的回调函数 | Function(affixed) | 无 | |
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
```html
<a-affix :style="{ position: 'absolute', top: y, left: x}">
...
</a-affix>
```
## FAQ
### Affix 使用 `target` 绑定容器时,元素会跑到容器外。
从性能角度考虑,我们只监听容器滚动事件。
相关 issue[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)

View File

@ -0,0 +1,27 @@
<cn>
#### 顶部公告
页面顶部通告形式,默认有图标且`type` 为 'warning'。
</cn>
<us>
#### Banner
Display Alert as a banner at top of page.
</us>
```vue
<template>
<div>
<a-alert message="Warning text" banner />
<br />
<a-alert
message="Very long warning text warning text text text text text text text"
banner
closable
/>
<br />
<a-alert :show-icon="false" message="Warning text without icon" banner />
<br />
<a-alert type="error" message="Error text" banner />
</div>
</template>
```

View File

@ -0,0 +1,15 @@
<cn>
#### 基本
最简单的用法,适用于简短的警告提示。
</cn>
<us>
#### basic
The simplest usage for short messages.
</us>
```vue
<template>
<a-alert message="Success Text" type="success" />
</template>
```

View File

@ -0,0 +1,38 @@
<cn>
#### 可关闭的警告提示
显示关闭按钮,点击可关闭警告提示。
</cn>
<us>
#### Closable
To show close button.
</us>
```vue
<template>
<div>
<a-alert
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
type="warning"
closable
@close="onClose"
/>
<a-alert
message="Error Text"
description="Error Description Error Description Error Description Error Description Error Description Error Description"
type="error"
closable
@close="onClose"
/>
</div>
</template>
<script>
export default {
methods: {
onClose(e) {
console.log(e, 'I was closed.');
},
},
};
</script>
```

View File

@ -0,0 +1,15 @@
<cn>
#### 自定义关闭
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`
</cn>
<us>
#### Customized Close Text
Replace the default icon with customized text.
</us>
```vue
<template>
<a-alert message="Info Text" type="info" close-text="Close Now" />
</template>
```

View File

@ -0,0 +1,63 @@
<cn>
#### 自定义图标
可口的图标让信息类型更加醒目。
</cn>
<us>
#### Custom Icon
Decent icon make information more clear and more friendly.
</us>
```vue
<template>
<div>
<a-alert message="showIcon = false" type="success">
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert message="Success Tips" type="success" show-icon>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert message="Informational Notes" type="info" show-icon>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert message="Warning" type="warning" show-icon>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert message="Error" type="error" show-icon>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert
message="Success Tips"
description="Detailed description and advices about successful copywriting."
type="success"
show-icon
>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert
message="Informational Notes"
description="Additional description and informations about copywriting."
type="info"
show-icon
>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert
message="Warning"
description="This is a warning notice about copywriting."
type="warning"
show-icon
>
<a-icon slot="icon" type="smile" />
</a-alert>
<a-alert
message="Error"
description="This is an error message about copywriting."
type="error"
show-icon
>
<a-icon slot="icon" type="smile" />
</a-alert>
</div>
</template>
```

View File

@ -0,0 +1,36 @@
<cn>
#### 含有辅助性文字介绍
含有辅助性文字介绍的警告提示。
</cn>
<us>
#### Description
Additional description for alert message.
</us>
```vue
<template>
<div>
<a-alert message="Success Text" type="success">
<p slot="description">
Success Description <span style="color: red">Success</span> Description Success Description
</p>
</a-alert>
<a-alert
message="Info Text"
description="Info Description Info Description Info Description Info Description"
type="info"
/>
<a-alert
message="Warning Text"
description="Warning Description Warning Description Warning Description Warning Description"
type="warning"
/>
<a-alert
message="Error Text"
description="Error Description Error Description Error Description Error Description"
type="error"
/>
</div>
</template>
```

View File

@ -0,0 +1,44 @@
<cn>
#### 图标
可口的图标让信息类型更加醒目。
</cn>
<us>
#### Icon
Decent icon make information more clear and more friendly.
</us>
```vue
<template>
<div>
<a-alert message="Success Tips" type="success" show-icon />
<a-alert message="Informational Notes" type="info" show-icon />
<a-alert message="Warning" type="warning" show-icon />
<a-alert message="Error" type="error" show-icon />
<a-alert
message="Success Tips"
description="Detailed description and advices about successful copywriting."
type="success"
show-icon
/>
<a-alert
message="Informational Notes"
description="Additional description and informations about copywriting."
type="info"
show-icon
/>
<a-alert
message="Warning"
description="This is a warning notice about copywriting."
type="warning"
show-icon
/>
<a-alert
message="Error"
description="This is an error message about copywriting."
type="error"
show-icon
/>
</div>
</template>
```

View File

@ -0,0 +1,61 @@
<script>
import Banner from './banner';
import Basic from './basic';
import Closable from './closable';
import CloseText from './close-text';
import Description from './description';
import Icon from './icon';
import Style from './style';
import SmoothClosed from './smooth-closed';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# Alert 警告提示
警告提示展现需要关注的信息
## 何时使用
- 当某个页面需要向用户显示警告的信息时
- 非浮层的静态展现形式始终展现不会自动消失用户可以点击关闭
## 代码演示`,
us: `# Alert
Alert component for feedback.
## When To Use
- When you need to show alert messages to users.
- When you need a persistent static container which is closable by user actions.
## Examples
`,
};
export default {
category: 'Components',
subtitle: '警告提示',
type: 'Feedback',
zhType: '反馈',
title: 'Alert',
render() {
return (
<div id="components-alert-demo">
<md cn={md.cn} us={md.us} />
<demo-sort>
<Banner />
<Basic />
<Closable />
<CloseText />
<Description />
<Icon />
<Style />
<SmoothClosed />
</demo-sort>
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>
<style>
#components-alert-demo .ant-alert {
margin-bottom: 16px;
}
</style>

View File

@ -0,0 +1,37 @@
<cn>
#### 平滑地卸载
平滑、自然的卸载提示。
</cn>
<us>
#### Smoothly Unmount
Smoothly and unaffectedly unmount Alert.
</us>
```vue
<template>
<div>
<a-alert
v-if="visible"
message="Alert Message Text"
type="success"
closable
:after-close="handleClose"
/>
</div>
</template>
<script>
export default {
data() {
return {
visible: true,
};
},
methods: {
handleClose() {
this.visible = false;
},
},
};
</script>
```

View File

@ -0,0 +1,20 @@
<cn>
#### 四种样式
共有四种样式 `success`、`info`、`warning`、`error`。
</cn>
<us>
#### More types
There are 4 types of Alert: `success`, `info`, `warning`, `error`.
</us>
```vue
<template>
<div>
<a-alert message="Success Text" type="success" />
<a-alert message="Info Text" type="info" />
<a-alert message="Warning Text" type="warning" />
<a-alert message="Error Text" type="error" />
</div>
</template>
```

View File

@ -0,0 +1,19 @@
## API
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| afterClose | Called when close animation is finished | () => void | - | - |
| banner | Whether to show as banner | boolean | false | - |
| closable | Whether Alert can be closed | boolean | - | - |
| closeText | Close text to show | string\|slot | - | - |
| description | Additional content of Alert | string\|slot | - | - |
| icon | Custom icon, effective when `showIcon` is `true` | vnode \| slot | - | - |
| message | Content of Alert | string\|slot | - | - |
| showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | - |
| type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | - |
### events
| Events Name | Description | Arguments | Version |
| ----------- | ----------------------------- | ----------------------- | ------- |
| close | Callback when Alert is closed | (e: MouseEvent) => void | - |

View File

@ -0,0 +1,19 @@
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - | - |
| banner | 是否用作顶部公告 | boolean | false | - |
| closable | 默认不显示关闭按钮 | boolean | 无 | - |
| closeText | 自定义关闭按钮 | string\|slot | 无 | - |
| description | 警告提示的辅助性文字介绍 | string\|slot | 无 | - |
| icon | 自定义图标,`showIcon` 为 `true` 时有效 | vnode \| slot | - | - |
| message | 警告提示内容 | string\|slot | 无 | - |
| showIcon | 是否显示辅助图标 | boolean | false`banner` 模式下默认值为 true | - |
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info``banner` 模式下默认值为 `warning` | - |
### 事件
| 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | -------------------- | ----------------------- | ---- |
| close | 关闭时触发的回调函数 | (e: MouseEvent) => void | - |

View File

@ -0,0 +1,27 @@
<cn>
#### 基本
最简单的用法。
</cn>
<us>
#### basic
The simplest usage.
</us>
```vue
<template>
<a-anchor>
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link
href="#components-anchor-demo-basic"
title="Basic demo with Target"
target="_blank"
/>
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
```

View File

@ -0,0 +1,31 @@
<cn>
#### 自定义锚点高亮
自定义锚点高亮。
</cn>
<us>
#### Customize the anchor highlight
Customize the anchor highlight.
</us>
```vue
<template>
<a-anchor :affix="false" :get-current-anchor="getCurrentAnchor">
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
<script>
export default {
methods: {
getCurrentAnchor() {
return '#components-anchor-demo-static';
},
},
};
</script>
```

View File

@ -0,0 +1,61 @@
<script>
import Basic from './basic';
import Static from './static';
import OnClick from './onClick';
import CustomizeHighlight from './customizeHighlight';
import OnChange from './onChange';
import TargetOffset from './targetOffset';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# Anchor 锚点
用于跳转到页面指定位置
## 何时使用
需要展现当前页面上可供跳转的锚点链接以及快速在锚点之间跳转
## 代码演示`,
us: `# Anchor
Hyperlinks to scroll on one page.
## When To Use
For displaying anchor hyperlinks on page and jumping between them.
## Examples
`,
};
export default {
category: 'Components',
subtitle: '锚点',
cols: 2,
type: 'Other',
zhType: '其他',
title: 'Anchor',
render() {
return (
<div id="components-anchor-demo">
<md cn={md.cn} us={md.us} />
<demo-sort>
<Basic />
<Static />
<OnClick />
<CustomizeHighlight />
<OnChange />
<TargetOffset />
</demo-sort>
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>
<style>
#components-anchor-demo .ant-affix {
z-index: 11;
}
</style>

View File

@ -0,0 +1,31 @@
<cn>
#### 监听锚点链接改变
监听锚点链接改变
</cn>
<us>
#### Listening for anchor link change
Listening for anchor link change.
</us>
```vue
<template>
<a-anchor :affix="false" @change="onChange">
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
<script>
export default {
methods: {
onChange(link) {
console.log('Anchor:OnChange', link);
},
},
};
</script>
```

View File

@ -0,0 +1,32 @@
<cn>
#### 自定义 click 事件
点击锚点不记录历史。
</cn>
<us>
#### Customize the click event
Clicking on an anchor does not record history.
</us>
```vue
<template>
<a-anchor :affix="false" @click="handleClick">
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
<script>
export default {
methods: {
handleClick(e, link) {
e.preventDefault();
console.log(link);
},
},
};
</script>
```

View File

@ -0,0 +1,22 @@
<cn>
#### 静态位置
不浮动,状态不随页面滚动变化。
</cn>
<us>
#### Static
Do not change state when page is scrolling.
</us>
```vue
<template>
<a-anchor :affix="false">
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
```

View File

@ -0,0 +1,34 @@
<cn>
#### 设置锚点滚动偏移量
锚点目标滚动到屏幕正中间。
</cn>
<us>
#### Set Anchor scroll offset
Anchor target scroll to screen center.
</us>
```vue
<template>
<a-anchor :target-offset="targetOffset">
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
<a-anchor-link href="#API" title="API">
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
<a-anchor-link href="#Link-Props" title="Link Props" />
</a-anchor-link>
</a-anchor>
</template>
<script>
export default {
data() {
return {
targetOffset: undefined,
};
},
mounted() {
this.targetOffset = window.innerHeight / 2;
},
};
</script>
```

View File

@ -0,0 +1,31 @@
## API
### Anchor Props
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| affix | Fixed mode of Anchor | boolean | true | |
| bounds | Bounding distance of anchor area | number | 5(px) | |
| getContainer | Scrolling container | () => HTMLElement | () => window | |
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | |
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | |
| wrapperClass | The class name of the container | string | - | |
| wrapperStyle | The style of the container | object | - | |
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 1.5.0 |
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 1.5.0 |
### Events
| Events Name | Description | Arguments | Version |
| --- | --- | --- | --- |
| click | set the handler to handle `click` event | Function(e: Event, link: Object) | |
| change | Listening for anchor link change | (currentActiveLink: string) => void | | 1.5.0 |
### Link Props
| Property | Description | Type | Default | Version |
| -------- | ----------------------------------------- | ------------ | ------- | ------- |
| href | target of hyperlink | string | | |
| title | content of hyperlink | string\|slot | | |
| target | Specifies where to display the linked URL | string | | 1.5.0 |

View File

@ -0,0 +1,31 @@
## API
### Anchor Props
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| affix | 固定模式 | boolean | true | |
| bounds | 锚点区域边界 | number | 5(px) | |
| getContainer | 指定滚动的容器 | () => HTMLElement | () => window | |
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
| showInkInFixed | 固定模式是否显示小圆点 | boolean | false | |
| wrapperClass | 容器的类名 | string | - | |
| wrapperStyle | 容器样式 | object | - | |
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 1.5.0 |
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 1.5.0 |
### 事件
| 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | ---------------------- | ----------------------------------- | ---- |
| click | `click` 事件的 handler | Function(e: Event, link: Object) | |
| change | 监听锚点链接改变 | (currentActiveLink: string) => void | | 1.5.0 |
### Link Props
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| ------ | -------------------------------- | ------------ | ------ | ----- |
| href | 锚点链接 | string | | |
| title | 文字内容 | string\|slot | | |
| target | 该属性指定在何处显示链接的资源。 | string | | 1.5.0 |

View File

@ -0,0 +1,49 @@
<cn>
#### 基本使用
基本使用。通过 dataSource 设置自动完成的数据源
</cn>
<us>
#### Basic Usage
Basic Usage, set datasource of autocomplete with `dataSource` property.
</us>
```vue
<template>
<a-auto-complete
v-model="value"
:data-source="dataSource"
style="width: 200px"
placeholder="input here"
@select="onSelect"
@search="onSearch"
@change="onChange"
/>
</template>
<script>
export default {
data() {
return {
value: '',
dataSource: [],
};
},
watch: {
value(val) {
console.log('value', val);
},
},
methods: {
onSearch(searchText) {
this.dataSource = !searchText ? [] : [searchText, searchText.repeat(2), searchText.repeat(3)];
},
onSelect(value) {
console.log('onSelect', value);
},
onChange(value) {
console.log('onChange', value);
},
},
};
</script>
```

View File

@ -0,0 +1,149 @@
<cn>
#### 查询模式 - 确定类目
查询模式 - 确定类目
</cn>
<us>
#### Lookup-Patterns - Certain Category
Lookup-Patterns - Certain Category
</us>
```vue
<template>
<div class="certain-category-search-wrapper" style="width: 250px">
<a-auto-complete
class="certain-category-search"
dropdown-class-name="certain-category-search-dropdown"
:dropdown-match-select-width="false"
:dropdown-style="{ width: '300px' }"
size="large"
style="width: 100%"
placeholder="input here"
option-label-prop="value"
>
<template slot="dataSource">
<a-select-opt-group v-for="group in dataSource" :key="group.title">
<span slot="label">
{{ group.title }}
<a
style="float: right"
href="https://www.google.com/search?q=antd"
target="_blank"
rel="noopener noreferrer"
>more
</a>
</span>
<a-select-option v-for="opt in group.children" :key="opt.title" :value="opt.title">
{{ opt.title }}
<span class="certain-search-item-count">{{ opt.count }} people</span>
</a-select-option>
</a-select-opt-group>
<a-select-option key="all" disabled class="show-all">
<a
href="https://www.google.com/search?q=ant-design-vue"
target="_blank"
rel="noopener noreferrer"
>
View all results
</a>
</a-select-option>
</template>
<a-input>
<a-icon slot="suffix" type="search" class="certain-category-icon" />
</a-input>
</a-auto-complete>
</div>
</template>
<script>
const dataSource = [
{
title: 'Libraries',
children: [
{
title: 'AntDesign',
count: 10000,
},
{
title: 'AntDesign UI',
count: 10600,
},
],
},
{
title: 'Solutions',
children: [
{
title: 'AntDesign UI',
count: 60100,
},
{
title: 'AntDesign',
count: 30010,
},
],
},
{
title: 'Articles',
children: [
{
title: 'AntDesign design language',
count: 100000,
},
],
},
];
export default {
data() {
return {
dataSource,
};
},
};
</script>
<style>
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group-title {
color: #666;
font-weight: bold;
}
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group {
border-bottom: 1px solid #f6f6f6;
}
.certain-category-search-dropdown .ant-select-dropdown-menu-item {
padding-left: 16px;
}
.certain-category-search-dropdown .ant-select-dropdown-menu-item.show-all {
text-align: center;
cursor: default;
}
.certain-category-search-dropdown .ant-select-dropdown-menu {
max-height: 300px;
}
</style>
<style scoped>
.certain-category-search-wrapper
>>> .certain-category-search.ant-select-auto-complete
.ant-input-affix-wrapper
.ant-input-suffix {
right: 12px;
}
.certain-category-search-wrapper >>> .certain-search-item-count {
position: absolute;
color: #999;
right: 16px;
}
.certain-category-search-wrapper
>>> .certain-category-search.ant-select-focused
.certain-category-icon {
color: #108ee9;
}
.certain-category-search-wrapper >>> .certain-category-icon {
color: #6e6e6e;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
font-size: 16px;
}
</style>
```

View File

@ -0,0 +1,47 @@
<cn>
#### 自定义输入组件
自定义输入组件。
</cn>
<us>
#### Customize Input Component
Customize Input Component
</us>
```vue
<template>
<a-auto-complete
:data-source="dataSource"
style="width: 200px"
@search="handleSearch"
@select="onSelect"
>
<a-textarea
placeholder="input here"
class="custom"
style="height: 50px"
@keypress="handleKeyPress"
/>
</a-auto-complete>
</template>
<script>
export default {
data() {
return {
dataSource: [],
};
},
methods: {
onSelect(value) {
console.log('onSelect', value);
},
handleSearch(value) {
this.dataSource = !value ? [] : [value, value + value, value + value + value];
},
handleKeyPress(ev) {
console.log('handleKeyPress', ev);
},
},
};
</script>
```

View File

@ -0,0 +1,51 @@
<script>
import Basic from './basic';
import CertainCategory from './certain-category';
import Custom from './custom';
import NonCaseSensitive from './non-case-sensitive';
import Options from './options';
import UncertainCategory from './uncertain-category';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# AutoComplete 自动完成
输入框自动完成功能
## 何时使用
需要自动完成时
## 代码演示`,
us: `# AutoComplete
Autocomplete function of input field.
## When To Use
When there is a need for autocomplete functionality.
## Examples
`,
};
export default {
category: 'Components',
subtitle: '自动完成',
type: 'Data Entry',
zhType: '数据录入',
cols: 2,
title: 'AutoComplete',
render() {
return (
<div>
<md cn={md.cn} us={md.us} />
<demo-sort>
<Basic />
<CertainCategory />
<Custom />
<NonCaseSensitive />
<Options />
<UncertainCategory />
</demo-sort>
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>

View File

@ -0,0 +1,36 @@
<cn>
#### 不区分大小写
不区分大小写的 AutoComplete
</cn>
<us>
#### Non-case-sensitive AutoComplete
A non-case-sensitive AutoComplete
</us>
```vue
<template>
<a-auto-complete
:data-source="dataSource"
style="width: 200px"
placeholder="input here"
:filter-option="filterOption"
/>
</template>
<script>
export default {
data() {
return {
dataSource: ['Burns Bay Road', 'Downing Street', 'Wall Street'],
};
},
methods: {
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toUpperCase().indexOf(input.toUpperCase()) >= 0
);
},
},
};
</script>
```

View File

@ -0,0 +1,41 @@
<cn>
#### 自定义选项
也可以直接传递slot="dataSource"的Option
</cn>
<us>
#### Customized
You could pass `slot="dataSource` as children of `AutoComplete`, instead of using `dataSource`
</us>
```vue
<template>
<a-auto-complete style="width: 200px" placeholder="input here" @search="handleSearch">
<template slot="dataSource">
<a-select-option v-for="email in result" :key="email">
{{ email }}
</a-select-option>
</template>
</a-auto-complete>
</template>
<script>
export default {
data() {
return {
result: [],
};
},
methods: {
handleSearch(value) {
let result;
if (!value || value.indexOf('@') >= 0) {
result = [];
} else {
result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
}
this.result = result;
},
},
};
</script>
```

View File

@ -0,0 +1,120 @@
<cn>
#### 查询模式 - 不确定类目
查询模式 - 不确定类目
</cn>
<us>
#### Lookup-Patterns - Uncertain Category
Lookup-Patterns - Uncertain Category
</us>
```vue
<template>
<div class="global-search-wrapper" style="width: 300px">
<a-auto-complete
class="global-search"
size="large"
style="width: 100%"
placeholder="input here"
option-label-prop="title"
@select="onSelect"
@search="handleSearch"
>
<template slot="dataSource">
<a-select-option v-for="item in dataSource" :key="item.category" :title="item.category">
Found {{ item.query }} on
<a
:href="`https://s.taobao.com/search?q=${item.query}`"
target="_blank"
rel="noopener noreferrer"
>
{{ item.category }}
</a>
<span className="global-search-item-count">{{ item.count }} results</span>
</a-select-option>
</template>
<a-input>
<a-button
slot="suffix"
style="margin-right: -12px"
class="search-btn"
size="large"
type="primary"
>
<a-icon type="search" />
</a-button>
</a-input>
</a-auto-complete>
</div>
</template>
<script>
export default {
data() {
return {
dataSource: [],
};
},
methods: {
onSelect(value) {
console.log('onSelect', value);
},
handleSearch(value) {
this.dataSource = value ? this.searchResult(value) : [];
},
getRandomInt(max, min = 0) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
searchResult(query) {
return new Array(this.getRandomInt(5))
.join('.')
.split('.')
.map((item, idx) => ({
query,
category: `${query}${idx}`,
count: this.getRandomInt(200, 100),
}));
},
},
};
</script>
<style>
.global-search-wrapper {
padding-right: 50px;
}
.global-search {
width: 100%;
}
.global-search.ant-select-auto-complete .ant-select-selection--single {
margin-right: -46px;
}
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input:not(:last-child) {
padding-right: 62px;
}
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input-suffix button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.global-search-item {
display: flex;
}
.global-search-item-desc {
flex: auto;
text-overflow: ellipsis;
overflow: hidden;
}
.global-search-item-count {
flex: none;
}
</style>
```

View File

@ -0,0 +1,41 @@
## API
```html
<a-auto-complete :dataSource="dataSource" />
```
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| allowClear | Show clear button, effective in multiple mode only. | boolean | false | |
| autoFocus | get focus when component mounted | boolean | false | |
| backfill | backfill selected item the input when using keyboard | boolean | false | |
| slot="default" (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
| dataSource | Data source for autocomplete | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
| dropdownMenuStyle | additional style applied to dropdown menu | object | | 1.5.0 |
| defaultActiveFirstOption | Whether active first option by default | boolean | true | |
| defaultValue | Initial selected option. | string\|string\[]\| - | |
| disabled | Whether disabled select | boolean | false | |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | |
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` | |
| placeholder | placeholder of input | string | - | |
| value(v-model) | selected option | string\|string\[]\|{ key: string, label: string\|vNodes }\|Array&lt;{ key: string, label: string\|vNodes }> | - | |
| defaultOpen | Initial open state of dropdown | boolean | - | |
| open | Controlled open state of dropdown | boolean | - | |
### events
| Events Name | Description | Arguments | Version |
| --- | --- | --- | --- |
| change | Called when select an option or input value change, or value of input is changed | function(value) | |
| blur | Called when leaving the component. | function() | |
| focus | Called when entering the component | function() | |
| search | Called when searching items. | function(value) | - | |
| select | Called when a option is selected. param is option's value and option instance. | function(value, option) | |
| dropdownVisibleChange | Call when dropdown open | function(open) | |
## Methods
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | remove focus | |
| focus() | get focus | |

View File

@ -0,0 +1,41 @@
## API
```html
<a-auto-complete :dataSource="dataSource" />
```
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| allowClear | 支持清除, 单选模式有效 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| slot="default" (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
| dataSource | 自动完成的数据源 | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | | 1.5.0 |
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
| defaultValue | 指定默认选中的条目 | string\|string\[]\| 无 | |
| disabled | 是否禁用 | boolean | false | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` | |
| placeholder | 输入框提示 | string \| slot | - | |
| value(v-model) | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|vNodes }\|Array&lt;{ key: string, label: string\|vNodes }> | 无 | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| open | 是否展开下拉菜单 | boolean | - | |
### 事件
| 事件名称 | 说明 | 回调参数 | 版本 |
| --- | --- | --- | --- |
| change | 选中 option或 input 的 value 变化时,调用此函数 | function(value) |
| blur | 失去焦点时的回调 | function() |
| focus | 获得焦点时的回调 | function() |
| search | 搜索补全项的时候调用 | function(value) |
| select | 被选中时调用,参数为选中项的 value 值 | function(value, option) |
| dropdownVisibleChange | 展开下拉菜单的回调 | function(open) |
## 方法
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 |
| focus() | 获取焦点 |

View File

@ -0,0 +1,22 @@
<cn>
#### 带徽标的头像
通常用于消息提示。
</cn>
<us>
#### With Badge
Usually used for reminders and notifications.
</us>
```vue
<template>
<div>
<span style="margin-right:24px">
<a-badge :count="1"><a-avatar shape="square" icon="user"/></a-badge>
</span>
<span>
<a-badge dot><a-avatar shape="square" icon="user"/></a-badge>
</span>
</div>
</template>
```

View File

@ -0,0 +1,29 @@
<cn>
#### 基本
头像有三种尺寸,两种形状可选。
</cn>
<us>
#### basic
Three sizes and two shapes are available.
</us>
```vue
<template>
<div>
<div>
<a-avatar :size="64" icon="user" />
<a-avatar size="large" icon="user" />
<a-avatar icon="user" />
<a-avatar size="small" icon="user" />
</div>
<br />
<div>
<a-avatar shape="square" :size="64" icon="user" />
<a-avatar shape="square" size="large" icon="user" />
<a-avatar shape="square" icon="user" />
<a-avatar shape="square" size="small" icon="user" />
</div>
</div>
</template>
```

View File

@ -0,0 +1,49 @@
<cn>
#### 自动调整字符大小
对于字符型的头像,当字符串较长时,字体大小可以根据头像宽度自动调整。
</cn>
<us>
#### Autoset Font Size
For letter type Avatar, when the letters are too long to display, the font size can be automatically adjusted according to the width of the Avatar.
</us>
```vue
<template>
<div>
<a-avatar
shape="square"
size="large"
:style="{ backgroundColor: color, verticalAlign: 'middle' }"
>
{{ avatarValue }}
</a-avatar>
<a-button
size="small"
:style="{ marginLeft: 16, verticalAlign: 'middle' }"
@click="changeValue"
>
改变
</a-button>
</div>
</template>
<script>
const UserList = ['U', 'Lucy', 'Tom', 'Edward'];
const colorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
export default {
data() {
return {
avatarValue: UserList[0],
color: colorList[0],
};
},
methods: {
changeValue() {
const index = UserList.indexOf(this.avatarValue);
this.avatarValue = index < UserList.length - 1 ? UserList[index + 1] : UserList[0];
this.color = index < colorList.length - 1 ? colorList[index + 1] : colorList[0];
},
},
};
</script>
```

View File

@ -0,0 +1,47 @@
<script>
import Basic from './basic';
import Badge from './badge';
import Type from './type';
import Dynamic from './dynamic';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# Avatar 头像
用来代表用户或事物支持图片图标或字符展示
## 设计师专属
安装 [Kitchen Sketch 插件 <EFBFBD>](https://kitchen.alipay.com).
## 代码演示`,
us: `# Avatar
Avatars can be used to represent people or objects. It supports images, 'Icon's, or letters.
## Examples
`,
};
export default {
category: 'Components',
subtitle: '头像',
type: 'Data Display',
zhType: '数据展示',
title: 'Avatar',
render() {
return (
<div>
<md cn={md.cn} us={md.us} />
<demo-sort>
<Basic />
<Badge />
<Type />
<Dynamic />
</demo-sort>
<api>
<template slot="cn">
<CN />
</template>
<US />
</api>
</div>
);
},
};
</script>

View File

@ -0,0 +1,27 @@
<cn>
#### 类型
支持三种类型图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。
</cn>
<us>
#### Type
Image, Icon and letter are supported, and the latter two kinds avatar can have custom colors and background colors.
</us>
```vue
<template>
<div>
<a-avatar icon="user" />
<a-avatar>
<a-icon slot="icon" type="user" />
</a-avatar>
<a-avatar>U</a-avatar>
<a-avatar>USER</a-avatar>
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
<a-avatar style="color: #f56a00; backgroundColor: #fde3cf">
U
</a-avatar>
<a-avatar style="backgroundColor:#87d068" icon="user" />
</div>
</template>
```

View File

@ -0,0 +1,11 @@
## API
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| icon | the `Icon` type for an icon avatar, see `Icon` Component | string | - |
| shape | the shape of avatar | `circle` \| `square` | `circle` |
| size | the size of the avatar | number \| string: `large` `small` `default` | `default` |
| src | the address of the image for an image avatar | string | - |
| srcSet | a list of sources to use for different screen resolutions | string | - |
| alt | This attribute defines the alternative text describing the image | string | - |
| loadError | handler when img load error, return false to prevent default fallback behavior | () => boolean | - |

View File

@ -0,0 +1,11 @@
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| icon | 设置头像的图标类型,可设为 Icon 的 `type` 或 VNode | string \| VNode \| slot | - |
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` |
| size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` |
| src | 图片类头像的资源地址 | string | - |
| srcSet | 设置图片类头像响应式资源地址 | string | - |
| alt | 图像无法显示时的替代文本 | string | - |
| loadError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - |

View File

@ -0,0 +1,20 @@
<cn>
#### 基本
最简单的用法。
</cn>
<us>
#### basic
The most basic usage.
</us>
```vue
<template>
<div>
<a-back-top />
Scroll down to see the bottom-right
<strong style="color: rgba(64, 64, 64, 0.6)"> gray </strong>
button.
</div>
</template>
```

View File

@ -0,0 +1,39 @@
<cn>
#### 自定义样式
可以自定义回到顶部按钮的样式,限制宽高:`40px * 40px`。
</cn>
<us>
#### Custom style
You can customize the style of the button, just note the size limit: no more than `40px * 40px`.
</us>
```vue
<template>
<div id="components-back-top-demo-custom">
<a-back-top>
<div class="ant-back-top-inner">
UP
</div>
</a-back-top>
Scroll down to see the bottom-right
<strong style="color: #1088e9"> blue </strong>
button.
</div>
</template>
<style scoped>
#components-back-top-demo-custom .ant-back-top {
bottom: 100px;
}
#components-back-top-demo-custom .ant-back-top-inner {
height: 40px;
width: 40px;
line-height: 40px;
border-radius: 4px;
background-color: #1088e9;
color: #fff;
text-align: center;
font-size: 20px;
}
</style>
```

View File

@ -0,0 +1,43 @@
<script>
import Basic from './basic';
import Custom from './custom';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
const md = {
cn: `# BackTop 回到顶部
返回页面顶部的操作按钮
## 何时使用
- 当页面内容区域比较长时
- 当用户需要频繁返回顶部查看相关内容时
## 代码演示`,
us: `# BackTop
\`BackTop\` makes it easy to go back to the top of the page.
## When To Use
- When the page content is very long.
- When you need to go back to the top very frequently in order to view the contents.
## Examples
`,
};
export default {
category: 'Components',
type: 'Other',
zhType: '其他',
subtitle: '回到顶部',
title: 'BackTop',
render() {
return (
<div>
<md cn={md.cn} us={md.us} />
<demo-sort>
<Basic />
<Custom />
</demo-sort>
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>

View File

@ -0,0 +1,16 @@
## API
> The distance to the bottom is set to `50px` by default, which is overridable.
>
> If you decide to use custom styles, please note the size limit: no more than `40px * 40px`.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| target | specifies the scrollable area dom node | () => HTMLElement | () => window | |
| visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 | |
### events
| Events Name | Description | Arguments | Version |
| --- | --- | --- | --- |
| click | a callback function, which can be executed when you click the button | Function | |

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