This commit is contained in:
songwanli2025@163.com 2020-03-16 13:03:39 +08:00
commit eb2dd164f6
136 changed files with 1521 additions and 955 deletions

View File

@ -18,7 +18,7 @@ As is.
Dark theme included. Theme can be changed seamlessly.
> When you find that the UI drafts are already in dark mode, you can't start with light theme. But if you start to build a dark mode UI, sooner or later you have to build a light themed UI. As a result, Naive UI has both of them.
### Batteries Included
More than 60 components. Utils for building themed components are provided.
There are more than 60 components. Utils for building themed component are provided.
## License
Naive UI is licensed under the [MIT license](https://opensource.org/licenses/MIT).

View File

@ -10,6 +10,8 @@ no-icon
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|title|`string`|`null`||
|show-icon|`string`|`true`||
|type|`'default' \| 'info' \| 'success' \| 'warning' \| 'error'`|`'default'`||

View File

@ -10,6 +10,8 @@ no-icon
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|title|`string`|`null`||
|show-icon|`string`|`true`||
|type|`'default' \| 'info' \| 'success' \| 'warning' \| 'error'`|`'default'`||

View File

@ -0,0 +1,30 @@
# Group
```html
<n-auto-complete :options="options" v-model="value" placeholder="Email" />
```
```js
export default {
computed: {
options () {
return [
['Google', '@gmail.com'],
['Netease', '@163.com'],
['Tencent', '@qq.com']
].map(emailInfo => {
return {
type: 'group',
name: emailInfo[0],
children: [
this.value.split('@')[0] + emailInfo[1]
]
}
})
}
},
data () {
return {
value: ''
}
}
}
```

View File

@ -4,6 +4,7 @@ Use as search hint or something similar.
```demo
basic
size
group
custom-input
after-select
```
@ -15,14 +16,14 @@ after-select
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|value|`string`|`null`||
|options|`Array<AutoCompleteOption \| AutoCompleteOptionGroup>`|`[]`||
|options|`Array<string \| AutoCompleteOption \| AutoCompleteOptionGroup>`|`[]`||
|placeholder|`string`|`null`||
|blur-after-select|`boolean`|`false`||
|clear-after-select|`boolean`|`false`||
## API
### AutoCompleteOption Type
|Property|Type|Description|
|-|-|-|
@ -36,12 +37,12 @@ after-select
|-|-|-|
|type|`'group'`||
|name|`string`||
|children|`Array<AutoCompleteOption>`||
|children|`Array<string | AutoCompleteOption>`||
## Slots
|Name|Parameters|Description|
|-|-|-|
|default|`({ handleInput: (value: string) => any, handleFocus: function, handleBlur: function, value: string })`||
|default|`({ handleInput: (value: string) => any, handleFocus: function, handleBlur: function, value: string, theme: string \| null })`||
## Events
|Name|Parameters|Description|

View File

@ -0,0 +1,30 @@
# 成组
```html
<n-auto-complete :options="options" v-model="value" placeholder="邮箱" />
```
```js
export default {
computed: {
options () {
return [
['谷歌', '@gmail.com'],
['网易', '@163.com'],
['腾讯', '@qq.com']
].map(emailInfo => {
return {
type: 'group',
name: emailInfo[0],
children: [
this.value.split('@')[0] + emailInfo[1]
]
}
})
}
},
data () {
return {
value: ''
}
}
}
```

View File

@ -4,6 +4,7 @@
```demo
basic
size
group
custom-input
after-select
```
@ -16,17 +17,33 @@ after-select
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|value|`string`|`null`||
|options|`Array<AutoCompleteOption \| AutoCompleteOptionGroup>`|`[]`||
|options|`Array<string \| AutoCompleteOption \| AutoCompleteOptionGroup>`|`[]`||
|placeholder|`string`|`null`||
|blur-after-select|`boolean`|`false`||
|clear-after-select|`boolean`|`false`||
### AutoCompleteOption Type
|属性|类型|介绍|
|-|-|-|
|label|`string`||
|value|`string \| number`|Should be unique in options.|
|disabled|`boolean`||
|render|`function`||
### AutoCompleteOptionGroup Type
|属性|类型|介绍|
|-|-|-|
|type|`'group'`||
|name|`string`||
|children|`Array<string | AutoCompleteOption>`||
## Slots
|名称|参数|说明|
|-|-|-|
|default|`({ handleInput: (value: string) => any, handleFocus: function, handleBlur: function, value: string })`||
|default|`({ handleInput: (value: string) => any, handleFocus: function, handleBlur: function, value: string, theme: string \| null })`||
## Events
|名称|参数|说明|

View File

@ -1,10 +1,10 @@
# Basic
```html
<n-badge :value="value" :max="15">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" dot>
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -37,16 +37,6 @@ export default {
```
```css
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
margin: 0 32px 12px 0;
}
```

View File

@ -2,24 +2,14 @@
Insert some custom content in it.
```html
<n-badge value="new">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge value="hot">
<div class="block" />
<n-avatar />
</n-badge>
```
```css
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -14,6 +14,8 @@ raw
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|value|`string \| number`|`null`||
|max|`number`|`null`||
|dot|`boolean`|`false`||

View File

@ -1,11 +1,11 @@
# Controlled Display
```html
<div class="demo">
<div class="badge-demo">
<n-badge :value="value" :max="15" :show="show">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" dot :show="show">
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -43,21 +43,8 @@ export default {
.n-badge {
margin: 0 32px 0px 0;
}
.demo {
.badge-demo {
display: flex;
align-items: center;
}
.n-button-group {
margin: 0 12px 0 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,16 +2,16 @@
Set `max` prop to handle overflow situation.
```html
<n-badge :value="value" show-zero>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" :max="99">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero :max="100">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero :max="10">
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -46,14 +46,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,27 +2,17 @@
Set `processing` prop to indicate it is processing.
```html
<n-badge dot processing>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="20" processing>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="info" processing>
<div class="block" />
<n-avatar />
</n-badge>
```
```css
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -35,14 +35,4 @@ export default {
.n-badge {
margin: 0 32px 0 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,10 +2,10 @@
Set `show-zero` prop to display zero.
```html
<n-badge :value="value">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero>
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -40,14 +40,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,19 +2,19 @@
Badge has `default`, `error`, `info`, `success`, `warning` types.
```html
<n-badge dot>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="error">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="info">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="success">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="warning">
<div class="block" />
<n-avatar />
</n-badge>
```
```js
@ -30,14 +30,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -1,10 +1,10 @@
# 基础用法
```html
<n-badge :value="value" :max="15">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" dot>
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -39,14 +39,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,24 +2,14 @@
在里面插入一些自定义内容。
```html
<n-badge value="新">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge value="火">
<div class="block" />
<n-avatar />
</n-badge>
```
```css
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -14,6 +14,8 @@ raw
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|value|`string \| number`|`null`||
|max|`number`|`null`||
|dot|`boolean`|`false`||

View File

@ -1,11 +1,11 @@
# 受控显示
```html
<div class="demo">
<div class="badge-demo">
<n-badge :value="value" :max="15" :show="show">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" dot :show="show">
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -43,21 +43,8 @@ export default {
.n-badge {
margin: 0 32px 0px 0;
}
.demo {
.badge-demo {
display: flex;
align-items: center;
}
.n-button-group {
margin: 0 12px 0 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,16 +2,16 @@
设定 `max` 来处理溢出情况。
```html
<n-badge :value="value" show-zero>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" :max="99">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero :max="100">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero :max="10">
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -46,14 +46,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,27 +2,17 @@
设定 `processing` 来表明正在处理。
```html
<n-badge dot processing>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="20" processing>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="info" processing>
<div class="block" />
<n-avatar />
</n-badge>
```
```css
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -35,14 +35,4 @@ export default {
.n-badge {
margin: 0 32px 0 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,10 +2,10 @@
设定 `show-zero` 来显示 0。
```html
<n-badge :value="value">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge :value="value" show-zero>
<div class="block" />
<n-avatar />
</n-badge>
<n-button-group>
<n-button @click="value = Math.min(16, value + 1)">
@ -40,14 +40,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -2,19 +2,19 @@
标记有 `default`、`error`、`info`、`success`、`warning` 类型。
```html
<n-badge dot>
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="error">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="info">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="success">
<div class="block" />
<n-avatar />
</n-badge>
<n-badge dot type="warning">
<div class="block" />
<n-avatar />
</n-badge>
```
```js
@ -30,14 +30,4 @@ export default {
.n-badge {
margin: 0 32px 8px 0;
}
.block {
width: 32px;
height: 32px;
background-color: #dddddd;
border-radius: 4px;
transition: background-color .3s cubic-bezier(.4, 0, .2, 1);
}
.n-dark-theme .block {
background-color: rgba(255, 255, 255, .15);
}
```

View File

@ -1,5 +1,5 @@
# 卡片 Card
一些经验不足的 UI 设计师喜欢在上面滥用阴影。
一些经验不足的 UI 设计师喜欢在上面滥用阴影。
## 演示
```demo
basic

View File

@ -26,6 +26,7 @@ filter
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|options|`Array<CascaderOption>`|`null`||
|value|`string \| number`|`null`||
|placeholder|`string`|`'Please Select'`||

View File

@ -27,6 +27,7 @@ filter
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|options|`Array<CascaderOption>`|`null`||
|value|`string \| number`|`null`||
|placeholder|`string`|`'请选择'`||

View File

@ -24,6 +24,7 @@ event
### Checkbox Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`string \| number`|`null`||
|checked|`boolean`|`false`||
|disabled|`boolean`|`false`||
@ -31,6 +32,7 @@ event
### Checkbox Group Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`Array<string \| number>`|`null`||
|disabled|`boolean`|`false`||

View File

@ -24,6 +24,7 @@ event
### Checkbox Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`string \| number`|`null`||
|checked|`boolean`|`false`||
|disabled|`boolean`|`false`||
@ -31,6 +32,7 @@ event
### Checkbox Group Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`Array<string \| number>`|`null`||
|disabled|`boolean`|`false`||

View File

@ -28,6 +28,7 @@ basic
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|language|`string`|`null`||
|code|`string`|`null`||
|trim|`boolean`|`true`||

View File

@ -28,6 +28,7 @@ basic
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|language|`string`|`null`||
|code|`string`|`null`||
|trim|`boolean`|`true`||

View File

@ -15,6 +15,7 @@ nested
### Collapse
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|expanded-names|`Array`|`null`||
|accordion|`boolean`|`false`||

View File

@ -15,6 +15,7 @@ nested
### Collapse Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|expanded-names|`Array`|`null`||
|accordion|`boolean`|`false`||

View File

@ -21,10 +21,10 @@ export default {
content:
'Click and count down 3 second',
positiveText: 'Confirm',
onPositiveClick: hide => {
onPositiveClick: () => {
confirmInstance.loading = true
this.$NMessage.success('Count down 3 second')
window.setTimeout(hide, 3000)
return new Promise(resolve => window.setTimeout(() => resolve(true), 3000))
}
})
}

View File

@ -29,9 +29,9 @@ use-component
|show-icon|`boolean`|`true`||
|loading|`boolean`|`false`||
|bordered|`boolean`|`false`||
|onPositiveClick|`(hide: function) => any`|`hide => hide()`||
|onNegativeClick|`(hide: function) => any`|`hide => hide()`|
|onClose|`(hide: function) => any`|`hide => hide()`||
|onPositiveClick|`() => Promise<boolean> \| boolean`|`() => true`|The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior.|
|onNegativeClick|`() => Promise<boolean> \| boolean`|`() => true`|The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior.|
|onClose|`() => Promise<boolean> \| boolean`|`() => true`|The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior.|
### ConfirmEnvironment API
#### ConfirmEnvironment Properties

View File

@ -21,10 +21,10 @@ export default {
content:
'点击,倒计时 3 秒',
positiveText: '确认',
onPositiveClick: hide => {
onPositiveClick: () => {
confirmInstance.loading = true
this.$NMessage.success('倒计时 3 秒')
window.setTimeout(hide, 3000)
return new Promise(resolve => window.setTimeout(() => resolve(true), 3000))
}
})
}

View File

@ -29,9 +29,9 @@ use-component
|show-icon|`boolean`|`true`||
|loading|`boolean`|`false`||
|bordered|`boolean`|`false`||
|onPositiveClick|`(hide: function) => any`|`hide => hide()`||
|onNegativeClick|`(hide: function) => any`|`hide => hide()`|
|onClose|`(hide: function) => any`|`hide => hide()`||
|onPositiveClick|`() => Promise<boolean> \| boolean`|`() => true`|默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为|
|onNegativeClick|`() => Promise<boolean> \| boolean`|`() => true`|默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为|
|onClose|`() => Promise<boolean> \| boolean`|`() => true`|默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为|
### ConfirmEnvironment API
#### ConfirmEnvironment Properties

View File

@ -23,6 +23,7 @@ format
### All Types Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`number`|`null`||
|actions|`Array<'clear' \| 'now' \| 'confirm'>`|`null`||
|clearable|`boolean`|`false`||

View File

@ -23,6 +23,7 @@ format
### 通用的 Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`number`|`null`||
|actions|`Array<'clear' \| 'now' \| 'confirm'>`|`null`||
|clearable|`boolean`|`false`||

View File

@ -14,13 +14,19 @@ target
## Props
|Name|Parameters|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|show|`boolean`|`false`||
|placement|`'top' \| 'right' \| 'bottom' \| 'left'`|`'right'`||
|width|`number \| string`|`251`||
|height|`number \| string`|`251`|Works when placement is `top` and `bottom`.|
|mask-closable|`boolean`|`true`|Whether to emit `hide` event when click mask.|
|drawer-style|`object`|`null`||
<<<<<<< HEAD
|target|`() => HTMLElement`|`null`|
=======
|drawer-class|`string`|`null`||
>>>>>>> upstream/develop
## Slots
|Name|Parameters|Description|

View File

@ -18,13 +18,19 @@ dark-4-debug
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|show|`boolean`|`false`||
|placement|`'top' \| 'right' \| 'bottom' \| 'left'`|`'right'`||
|width|`number \| string`|`251`||
|height|`number \| string`|`251`|在位置是 `top``bottom` 时生效|
|mask-closable|`boolean`|`true`|点击遮罩时是否发出 `hide` 事件|
|drawer-style|`object`|`null`||
<<<<<<< HEAD
|target|`() => HTMLElement`|`null`|
=======
|drawer-class|`string`|`null`||
>>>>>>> upstream/develop
## Slots
|名称|参数|说明|

View File

@ -1,28 +1,26 @@
# Basic
# Use Preset Input
By default, the preset of `n-dynamic-input` is `input`.
```html
<n-dynamic-input
v-model="test"
placeholder-key="placeholder1"
placeholder-value="placeholder2"
:on-add="add"
v-model="value"
placeholder="优化内容"
:min="3"
:max="6"
/>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(value, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
value: [
'',
'',
''
]
}
},
methods: {
add (resolve) {
resolve('')
}
}
}
```

View File

@ -1,52 +1,52 @@
# Custom
# Custom Input Content
```html
<n-dynamic-input
v-model="test"
title="Add CheckBox"
preset="custom"
:on-add="add"
v-model="customValue"
:on-add="onAdd"
>
<template v-slot="slotProps">
<div style="width:100%">
<n-checkbox
v-model="slotProps.item.isCheck"
style="width: 120px;"
/>
<n-input-number
v-model="slotProps.item.num"
/>
<n-input
v-model="slotProps.item.string"
type="input"
size="small"
/>
<template v-slot="{ value }">
<div style="width: 100%;">
<div style="display: flex; align-items: center;">
<n-checkbox
v-model="value.isCheck"
style="margin-right: 12px;"
/>
<n-input-number
v-model="value.num"
style="margin-right: 12px; width: 160px;"
/>
<n-input
v-model="value.string"
type="input"
/>
</div>
</div>
</template>
</n-dynamic-input>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(customValue, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
{
isCheck: true,
num: 1,
string: 'Test string'
}
customValue: [
{
isCheck: true,
num: 1,
string: 'A String'
}
]
}
},
methods: {
add (resolve) {
resolve({
onAdd () {
return {
isCheck: false,
num: 1,
string: 'Test string'
})
string: 'A String'
}
}
}
}

View File

@ -0,0 +1,96 @@
# Use it in Form
`n-dynamic-input` 并不能作为一个单独的表项检验,如果你需要检验 `n-dynamic-input` 里面的内容,可以在自定义内容中传入 `n-form-item` 来完成数据的检验。下面是一个完整的例子。
```html
<n-form :model="model" ref="form">
<!--
设定 key-field 是为了每一项都能稳定的待在原地。如果不做设定可能会导致在增加删除项目时,表
项的验证信息消失或错位
-->
<n-dynamic-input
v-model="model.dynamicInputValue"
key-field="key"
:on-create="onCreate"
@clear="handleClear"
>
<template v-slot="{ index, value }">
<div style="display: flex;">
<!--
通常path 的变化会导致 form-item 验证内容或规则的改变,所以 naive-ui 会清理掉
表项已有的验证信息。但是这个例子是个特殊情况我们明确的知道path 的改变不会导致
form-item 验证内容和规则的变化,所以就 ignore-path-change
-->
<n-form-item
ignore-path-change
:path="`dynamicInputValue[${index}].name`"
:rule="dynamicInputRule"
>
<n-input
placeholder="Name"
@keydown.enter.native.prevent
v-model="model.dynamicInputValue[index].name"
/>
<!--
由于在 input 元素里按回车会导致 form 里面的 button 被点击,所以阻止了默认行为
-->
</n-form-item>
<div style="height: 34px; line-height: 34px; margin: 0 8px;">=</div>
<n-form-item
ignore-path-change
:path="`dynamicInputValue[${index}].value`"
:rule="dynamicInputRule"
>
<n-input
placeholder="Value"
@keydown.enter.native.prevent
v-model="model.dynamicInputValue[index].value"
/>
</n-form-item>
</div>
</template>
</n-dynamic-input>
</n-form>
<pre>
{{ JSON.stringify(model.dynamicInputValue, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
dynamicInputRule: {
trigger: 'input',
validator (rule, value) {
if (value.length >= 5) return new Error('最多输入四个字符')
return true
}
},
model: {
dynamicInputValue: [
{ key: 0, value: '' }
]
}
}
},
methods: {
onCreate () {
return {
name: '',
value: '',
/** 生成 key ,目的是让这个值对应的表项的验证信息不错位 */
key: Math.random().toString(16).slice(2, 10)
}
},
/**
* 由于清除 input 的内容是个外部行为input 不会发出事件,所以 form-item 无法得到从
* input 发出的事件。于是为了验证结果和显示的值同步,需要手动验证。使用 $nextTick 是因
* 为在接受这个事件时input 的值刚放在事件中发出,还没有落实到实际的值上,需要等下个
* tick 才能验证新的结果
*/
handleClear () {
this.$nextTick().then(
() => this.$refs.form.validate()
)
}
}
}
```

View File

@ -1,36 +1,45 @@
# Dynamic Input
<!--single-column-->
这个组件的名字改过很多次。
## Demos
一开始它被造出来是为了输入环境变量。
## 演示
```demo
basic
pair
custom
form
```
## Props
### Input Props
|Name|Type|Default|Description|
### Dynamic Input Props
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array`||**required**|
|preset|`'input' \| 'preset'`|`'input'`|动态录入使用的预设,在不设定 `$scopedSlots.default` 的时候生效|
|value|`Array`|-|**必需**|
|max|`number`|`null`|最多有几项内容|
|key-field|`string`|`null`||
|on-create|`(index: number) => any`|`null`|点击添加按钮时的回调,如果设定则返回值会被用作新添加的初始值以及清空内容时的初始值。其中 `index` 是创建内容将要被放置到的位置,从 0 开始计算|
### Dynamic Input Props(Input Preset)
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array<string>`|-|**必需**|
|placeholder|`string`|`''`||
|onAdd|`(resolve: (item) => void) => any`|`null`| Callback when click at '+'. Pass resolved item to resolve function to set a new node.|
### Pair Props
|Name|Type|Default|Description|
### Dynamic Input Props(Pair Preset)
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array`||**required**|
|placeholderKey|`string`|`key`||
|placeholderValue|`string`|`value`||
|onAdd|`(resolve: (item) => void) => any`|`null`| Callback when click at '+'. Pass resolved item to resolve function to set a new node.|
### Custom Props
|Name|Type|Default|Description|
|-|-|-|-|
|value|`Array`||**required**|
|onAdd|`(resolve: (item) => void) => any`|`null`| Callback when click at '+'. Pass resolved item to resolve function to set a new node.|
|value|`Array<{ key: string, value: string }>`|-|**必需**|
|key-placeholder|`string`|`''`||
|value-placeholder|`string`|`''`||
## Slots
|名称|参数|说明|
|-|-|-|
|default|`({ value: any, index: number })`|每一项的渲染方式,其中 `value` 为该项对应的数组值,`index` 为该项对应的数组索引|
## Events
|Name|Parameters|Description|
|名称|参数|说明|
|-|-|-|
|remove|`(index: Number)`| Index is the item which you removed|
|clear|`()`||
|remove|`(index: Number)`|`index` 是要移除的数据的索引|

View File

@ -1,23 +1,23 @@
# Pair
# Use Preset Pair
```html
<n-dynamic-input
preset="pair"
v-model="test"
placeholder-key="placeholder1"
placeholder-value="placeholder2"
v-model="value"
key-placeholder="优化内容"
value-placeholder="优化成本"
/>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(value, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
value: [
{
key: 'key1',
value: 'value1'
key: '',
value: ''
}
]
}

View File

@ -1,28 +1,26 @@
# 基础用法
# 使用输入预设
默认状况下,`n-dynamic-input` 的预设是 `input`
```html
<n-dynamic-input
v-model="test"
placeholder-key="placeholder1"
placeholder-value="placeholder2"
:on-add="add"
v-model="value"
placeholder="优化内容"
:min="3"
:max="6"
/>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(value, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
value: [
'',
'',
''
]
}
},
methods: {
add (resolve) {
resolve('')
}
}
}
```

View File

@ -1,52 +1,52 @@
# 自定义
# 自定义内容
```html
<n-dynamic-input
v-model="test"
title="Add CheckBox"
preset="custom"
:onAdd="add"
v-model="customValue"
:on-add="onAdd"
>
<template v-slot="slotProps">
<div style="width:100%">
<n-checkbox
v-model="slotProps.item.isCheck"
style="width: 120px;"
/>
<n-input-number
v-model="slotProps.item.num"
/>
<n-input
v-model="slotProps.item.string"
type="input"
size="small"
/>
<template v-slot="{ value }">
<div style="width: 100%;">
<div style="display: flex; align-items: center;">
<n-checkbox
v-model="value.isCheck"
style="margin-right: 12px;"
/>
<n-input-number
v-model="value.num"
style="margin-right: 12px; width: 160px;"
/>
<n-input
v-model="value.string"
type="input"
/>
</div>
</div>
</template>
</n-dynamic-input>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(customValue, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
customValue: [
{
isCheck: true,
num: 1,
string: 'Test string'
string: 'A String'
}
]
}
},
methods: {
add (resolve) {
resolve({
onAdd () {
return {
isCheck: false,
num: 1,
string: 'Test string'
})
string: 'A String'
}
}
}
}

View File

@ -0,0 +1,96 @@
# 在表单中使用
`n-dynamic-input` 并不能作为一个单独的表项检验,如果你需要检验 `n-dynamic-input` 里面的内容,可以在自定义内容中传入 `n-form-item` 来完成数据的检验。下面是一个完整的例子。
```html
<n-form :model="model" ref="form">
<!--
设定 key-field 是为了每一项都能稳定的待在原地。如果不做设定可能会导致在增加删除项目时,表
项的验证信息消失或错位
-->
<n-dynamic-input
v-model="model.dynamicInputValue"
key-field="key"
:on-create="onCreate"
@clear="handleClear"
>
<template v-slot="{ index, value }">
<div style="display: flex;">
<!--
通常path 的变化会导致 form-item 验证内容或规则的改变,所以 naive-ui 会清理掉
表项已有的验证信息。但是这个例子是个特殊情况我们明确的知道path 的改变不会导致
form-item 验证内容和规则的变化,所以就 ignore-path-change
-->
<n-form-item
ignore-path-change
:path="`dynamicInputValue[${index}].name`"
:rule="dynamicInputRule"
>
<n-input
placeholder="Name"
@keydown.enter.native.prevent
v-model="model.dynamicInputValue[index].name"
/>
<!--
由于在 input 元素里按回车会导致 form 里面的 button 被点击,所以阻止了默认行为
-->
</n-form-item>
<div style="height: 34px; line-height: 34px; margin: 0 8px;">=</div>
<n-form-item
ignore-path-change
:path="`dynamicInputValue[${index}].value`"
:rule="dynamicInputRule"
>
<n-input
placeholder="Value"
@keydown.enter.native.prevent
v-model="model.dynamicInputValue[index].value"
/>
</n-form-item>
</div>
</template>
</n-dynamic-input>
</n-form>
<pre>
{{ JSON.stringify(model.dynamicInputValue, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
dynamicInputRule: {
trigger: 'input',
validator (rule, value) {
if (value.length >= 5) return new Error('最多输入四个字符')
return true
}
},
model: {
dynamicInputValue: [
{ key: 0, value: '' }
]
}
}
},
methods: {
onCreate () {
return {
name: '',
value: '',
/** 生成 key ,目的是让这个值对应的表项的验证信息不错位 */
key: Math.random().toString(16).slice(2, 10)
}
},
/**
* 由于清除 input 的内容是个外部行为input 不会发出事件,所以 form-item 无法得到从
* input 发出的事件。于是为了验证结果和显示的值同步,需要手动验证。使用 $nextTick 是因
* 为在接受这个事件时input 的值刚放在事件中发出,还没有落实到实际的值上,需要等下个
* tick 才能验证新的结果
*/
handleClear () {
this.$nextTick().then(
() => this.$refs.form.validate()
)
}
}
}
```

View File

@ -1,36 +1,45 @@
# 自定义增加
# 动态录入 Dynamic Input
<!--single-column-->
这个组件的名字改过很多次。
一开始它被造出来是为了输入环境变量。
## 演示
```demo
basic
pair
custom
form
```
## Props
### Input Props
### Dynamic Input Props
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array`||**必需**|
|preset|`'input' \| 'preset'`|`'input'`|动态录入使用的预设,在不设定 `$scopedSlots.default` 的时候生效|
|value|`Array`|-|**必需**|
|max|`number`|`null`|最多有几项内容|
|key-field|`string`|`null`||
|on-create|`(index: number) => any`|`null`|点击添加按钮时的回调,如果设定则返回值会被用作新添加的初始值以及清空内容时的初始值。其中 `index` 是创建内容将要被放置到的位置,从 0 开始计算|
### Dynamic Input Props(Input Preset)
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array<string>`|-|**必需**|
|placeholder|`string`|`''`||
|onAdd|`(resolve: (item) => void) => any`|`null`| 点击 '+' 时的回调.将要增加的一条数据传入resolve方法用来新增一个节点.|
### Pair Props
### Dynamic Input Props(Pair Preset)
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array`||**必需**|
|placeholderKey|`string`|`key`||
|placeholderValue|`string`|`value`||
|onAdd|`(resolve: (item) => void) => any`|`null`| 点击 '+' 时的回调.将要增加的一条数据传入resolve方法用来新增一个节点.|
### Custom Props
|名称|类型|默认值|说明|
|-|-|-|-|
|value|`Array`||**必需**|
|onAdd|`(resolve: (item) => void) => any`|`null`| 点击 '+' 时的回调.将要增加的一条数据传入resolve方法用来新增一个节点.|
|value|`Array<{ key: string, value: string }>`|-|**必需**|
|key-placeholder|`string`|`''`||
|value-placeholder|`string`|`''`||
## Slots
|名称|参数|说明|
|-|-|-|
|default|`({ value: any, index: number })`|每一项的渲染方式,其中 `value` 为该项对应的数组值,`index` 为该项对应的数组索引|
## Events
|名称|参数|说明|
|-|-|-|
|remove|`(index: Number)`| Index 是要移除的数据的索引|
|clear|`()`||
|remove|`(index: Number)`|`index` 是要移除的数据的索引|

View File

@ -1,23 +1,23 @@
# 键值对
# 使用键值对预设
```html
<n-dynamic-input
preset="pair"
v-model="test"
placeholder-key="placeholder1"
placeholder-value="placeholder2"
v-model="value"
key-placeholder="优化内容"
value-placeholder="优化成本"
/>
<pre>
{{ JSON.stringify(test,0,2) }}
{{ JSON.stringify(value, 0, 2) }}
</pre>
```
```js
export default {
data () {
return {
test: [
value: [
{
key: 'key1',
value: 'value1'
key: '',
value: ''
}
]
}

View File

@ -1,12 +1,30 @@
# Custom Rules
You can custom you valiation by setting custom trigger in rules.
Sometimes builtin triggers don't meet you demand. You can custom you valiation by setting custom trigger in rules and manually trigger the validation.
```html
<n-form :model="model" ref="form" :rules="rules">
<n-form-item-row path="age" label="Age">
<n-input v-model="model.age"/>
<n-form
:model="model"
ref="form"
:rules="rules"
>
<n-form-item-row
path="age"
label="Age"
>
<n-input
v-model="model.age"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row path="password" label="Password">
<n-input v-model="model.password" @input="handlePasswordInput" type="password"/>
<n-form-item-row
path="password"
label="Password"
>
<n-input
v-model="model.password"
@input="handlePasswordInput"
type="password"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row
first
@ -14,41 +32,24 @@ You can custom you valiation by setting custom trigger in rules.
label="Re-enter Password"
ref="reenteredPassword"
>
<n-input :disabled="!model.password" v-model="model.reenteredPassword" type="password"/>
</n-form-item-row>
<n-form-item-row label="Env" path="env" rule-path="null">
<n-dynamic-input
v-model="model.env"
preset="pair"
<n-input
:disabled="!model.password"
v-model="model.reenteredPassword"
type="password"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row label="group" path="group" rule-path="null">
<n-dynamic-input
v-model="model.group"
preset='custom'
>
<template v-slot="slotProps">
<div style="width:100%">
<n-form-item
:path="'group[' + slotProps.index + '].inputNumberValue'"
rule-path="group.inputNumberValue"
>
<n-input-number v-model="slotProps.item.inputNumberValue"/>
</n-form-item>
<n-form-item
:path="'group[' + slotProps.index + '].input'"
rule-path="group.input"
>
<n-input v-model="slotProps.item.input"/>
</n-form-item>
</div>
</template>
</n-dynamic-input>
</n-form-item-row>
<n-row :gutter="[0, 24]">
<n-col :span="24">
<div style="display: flex; justify-content: flex-end;">
<n-button @click="handleValidateButtonClick" round type="primary">Validate</n-button>
<n-button
:disabled="model.age === null"
@click="handleValidateButtonClick"
round
type="primary"
>
Validate
</n-button>
</div>
</n-col>
</n-row>
@ -65,19 +66,7 @@ export default {
model: {
age: null,
password: null,
reenteredPassword: null,
env: [
{
key:'',
value:''
}
],
group: [
{
inputNumberValue: 1,
input: null
}
]
reenteredPassword: null
},
rules: {
age: [
@ -96,6 +85,12 @@ export default {
trigger: ['input', 'blur']
}
],
password: [
{
required: true,
message: 'Password is required'
}
],
reenteredPassword: [
{
required: true,
@ -112,38 +107,14 @@ export default {
message: 'Password is not same as re-entered password!',
trigger: ['blur', 'password-input']
}
],
env: {
key: {
required: true,
message: 'Please input your key',
trigger: ['input', 'blur']
},
value: {
required: true,
message: 'Please input your value',
trigger: ['input', 'blur']
}
},
group: {
inputNumberValue: {
validator: this.validateGroupNumber,
trigger: ['blur', 'change'],
message: 'Please input a number which is not zero'
},
input: {
required: true,
message: 'Please input your key',
trigger: ['input', 'blur']
},
}
]
}
}
},
methods: {
handlePasswordInput () {
if (this.model.reenteredPassword) {
this.$refs.reenteredPassword.validate('password-input')
this.$refs.reenteredPassword.validate({ trigger: 'password-input' })
}
},
handleValidateButtonClick (e) {
@ -162,9 +133,6 @@ export default {
},
validatePasswordSame (rule, value) {
return value === this.model.password
},
validateGroupNumber (rule, value) {
return value !== 0
}
}
}

View File

@ -36,17 +36,18 @@ async
|Name|Type|Default|Description|
|-|-|-|-|
|label|`string`|`null`||
|label-width|`number \| string`|`null`|If not set, use label-align from wrapper form.|
|label-width|`number \| string`|`null`|If not set, use `label-width` from the wrapper form.|
|label-style|`object`|`{}`||
|label-align|`'left' \| 'right'`|`null`|Text align in label. If not set, use label-align from wrapper form.|
|label-placement|`'left' \| 'top'`|`null`|If not set, use label-placement from wrapper form.|
|label-align|`'left' \| 'right'`|`null`|Text align in label. If not set, use `label-align` from wrapper form.|
|label-placement|`'left' \| 'top'`|`null`|If not set, use `label-placement` from wrapper form.|
|path|`string`|`null`|The path to collect item value to wrapper form's model object.|
|rule-path|`string`|`null`|The path to get rule from wrapper form's rule object. If not set, use path of the form item instead.|
|required|`boolean`|`false`|Whether to show required mark. Note: a required rule has higher priority than this props & this prop **won't** change the validation process. The validation still depends on the rules.|
|show-require-mark|`boolean`|`true`|Whether to show require mark when form item is required. If not set, use show-require-mark from wrapper form.|
|rule|`FormItemRule \| Array<FormItemRule>`|`null`|The rule to validate the form item. It will be merged with the rules acquired by rule-path from wrapper form's rules. It's recommend to set all rules on wrapper form.|
|required|`boolean`|`false`|Whether to show required mark. Note: a required rule has higher priority than this prop & this prop **won't** have any effect on validation. The validation still depends on the rules.|
|show-require-mark|`boolean`|`true`|Whether to show require mark when form item is required. If not set, use `show-require-mark` from wrapper form.|
|rule|`FormItemRule \| Array<FormItemRule>`|`null`|The rule to validate the form item. It will be merged with the rules acquired by `rule-path` from wrapper form's rules. It's recommend to set all rules on wrapper form.|
|first|`boolean`|`false`|Whether only to show the first validation error message.|
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|ingore-path-change|`boolean`|`false`|Usually, the change of `path` will cause the data source's variation. So naive-ui will clear the validation result. If it is not expected, you can set it to `true`|
### Form Item Row Props
@ -59,20 +60,19 @@ Accept all props from form-item & [Col](n-row#Col-Props)
<n-alert type="warning" title="Caveat on Validate Method" style="margin-bottom: 16px;">
<n-ol align-text>
<n-li>Validation will only be executed on form items which have a <n-text code>path</n-text></n-li>
<n-li>Validation will use the path to get collected value from form <n-text code>model</n-text>, then use <n-text code>path</n-text> or <n-text code>rule-path</n-text>(if specified) to get validation rules</n-li>
<n-li>Validation will use all rules regardless of the triggers of form items.</n-li>
<n-li>By default, validation will use all rules regardless of the triggers of the rules.</n-li>
</n-ol>
</n-alert>
|Name|Type|Description|
|-|-|-|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any) => Promise<void>`|Validate the form.The rejection value type of returned promise is `Array<ValidationError>`.|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any, shouldRuleBeApplied?: FormItemRule => boolean) => Promise<void>`|Validate the form. The rejection value type of returned promise is `Array<ValidationError>`.|
|clearValidationEffect|`() => void`||
### Form Item, Form Item Row, Form Item Col Methods
|Name|Type|Description|
|-|-|-|
|validate|`(trigger?: string, validateCallback?: (errors?: Array<ValidationError>) => any, options?: AsyncValidatorOptions) => Promise<void>`|Validate the form item. The rejection value type of returned promise is `Array<ValidationError>`. If trigger is not passed, all rules of the item will be applied.|
|validate|`({ trigger?: string, callback?: (errors?: Array<ValidationError>) => any, shouldRuleBeApplied?: FormItemRule => boolean, options?: AsyncValidatorOptions }) => Promise<void>`|Validate the form item. The rejection value type of returned promise is `Array<ValidationError>`. If trigger is not set, all rules of the item will be applied. `shouldRuleBeApplied` can filter rules after they are filtered by the trigger.|
|clearValidationEffect|`() => void`||
About AsyncValidatorOptions, see <n-a href="https://github.com/yiminghe/async-validator">async-validator</n-a>.

View File

@ -1,12 +1,30 @@
# 自定义规则
你可以通过设定自定的 trigger 来控制验证。
有时候内置的 trigger 无法满足验证的需要。你可以通过设定自定的 trigger 然后手动触发它来控制验证。
```html
<n-form :model="model" ref="form" :rules="rules">
<n-form-item-row path="age" label="年龄">
<n-input v-model="model.age"/>
<n-form
:model="model"
ref="form"
:rules="rules"
>
<n-form-item-row
path="age"
label="年龄"
>
<n-input
v-model="model.age"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row path="password" label="密码">
<n-input v-model="model.password" @input="handlePasswordInput" type="password"/>
<n-form-item-row
path="password"
label="密码"
>
<n-input
v-model="model.password"
@input="handlePasswordInput"
type="password"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row
first
@ -14,39 +32,24 @@
label="重复密码"
ref="reenteredPassword"
>
<n-input :disabled="!model.password" v-model="model.reenteredPassword" type="password"/>
</n-form-item-row>
<n-form-item-row label="Env" path="env" rule-path="null">
<n-dynamic-input
v-model="model.env"
<n-input
:disabled="!model.password"
v-model="model.reenteredPassword"
type="password"
@keydown.enter.native.prevent
/>
</n-form-item-row>
<n-form-item-row label="group" path="group" rule-path="null">
<n-dynamic-input
v-model="model.group"
>
<template v-slot="slotProps">
<div style="width:100%">
<n-form-item
:path="'group[' + slotProps.index + '].inputNumberValue'"
rule-path="group.inputNumberValue"
>
<n-input-number v-model="slotProps.item.inputNumberValue"/>
</n-form-item>
<n-form-item
:path="'group[' + slotProps.index + '].input'"
rule-path="group.input"
>
<n-input v-model="slotProps.item.input"/>
</n-form-item>
</div>
</template>
</n-dynamic-input>
</n-form-item-row>
<n-row :gutter="[0, 24]">
<n-col :span="24">
<div style="display: flex; justify-content: flex-end;">
<n-button @click="handleValidateButtonClick" round type="primary">验证</n-button>
<n-button
@click="handleValidateButtonClick"
:disabled="model.age === null"
round
type="primary"
>
验证
</n-button>
</div>
</n-col>
</n-row>
@ -63,19 +66,7 @@ export default {
model: {
age: null,
password: null,
reenteredPassword: null,
env: [
{
key:'',
value:''
}
],
group: [
{
inputNumberValue: 1,
input: null
}
]
reenteredPassword: null
},
rules: {
age: [
@ -85,7 +76,7 @@ export default {
if (!value) {
return new Error('需要年龄')
} else if (!/^\d*$/.test(value)) {
return new Error('年龄应该是个整数')
return new Error('年龄应该整数')
} else if (Number(value) < 18) {
return new Error('年龄应该超过十八岁')
}
@ -94,10 +85,16 @@ export default {
trigger: ['input', 'blur']
}
],
password: [
{
required: true,
message: '请输入密码'
}
],
reenteredPassword: [
{
required: true,
message: '需要重复输入密码',
message: '请再次输入密码',
trigger: ['input', 'blur']
},
{
@ -110,26 +107,14 @@ export default {
message: '两次密码输入不一致',
trigger: ['blur', 'password-input']
}
],
group: {
inputNumberValue: {
validator: this.validateGroupNumber,
trigger: ['blur', 'change'],
message: '请输入不为0的数字'
},
input: {
required: true,
message: '请输入你的key',
trigger: ['input', 'blur']
},
}
]
}
}
},
methods: {
handlePasswordInput () {
if (this.model.reenteredPassword) {
this.$refs.reenteredPassword.validate('password-input')
this.$refs.reenteredPassword.validate({ trigger: 'password-input' })
}
},
handleValidateButtonClick (e) {
@ -148,9 +133,6 @@ export default {
},
validatePasswordSame (rule, value) {
return value === this.model.password
},
validateGroupNumber (rule, value) {
return value !== 0
}
}
}

View File

@ -37,17 +37,18 @@ validator-debug
|名称|类型|默认值|说明|
|-|-|-|-|
|label|`string`|`null`||
|label-width|`number \| string`|`null`|如果没有被设定,使用外层表单的 label-align|
|label-width|`number \| string`|`null`|如果没有被设定,使用外层表单的 `label-width`|
|label-style|`object`|`{}`||
|label-align|`'left' \| 'right'`|`null`|标签的文本对齐方式。如果没有被设定,使用外层表单的 label-align|
|label-placement|`'left' \| 'top'`|`null`|如果没有被设定,使用外层表单的 label-placement|
|label-align|`'left' \| 'right'`|`null`|标签的文本对齐方式。如果没有被设定,使用外层表单的 `label-align`|
|label-placement|`'left' \| 'top'`|`null`|如果没有被设定,使用外层表单的 `label-placement`|
|path|`string`|`null`|将值收集到外层表单 `model` 对象的路径|
|rule-path|`string`|`null`|从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替|
|required|`boolean`|`false`|是否展示必填的星号。注意:一个 required 的规则比这个属性有更高的优先级 & 这个属性不会影响表单的验证。验证完全依赖于规则|
|show-require-mark|`boolean`|`true`|在表项是必填的时候是不是展示星号。如果没有被设定,使用外层表单的 show-require-mark|
|rule-path|`string`|`null`|从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替|
|required|`boolean`|`false`|是否展示必填的星号。注意:一个 `required: true` 的规则比这个属性有更高的优先级 & 这个属性不会影响表单的验证。验证完全依赖于规则|
|show-require-mark|`boolean`|`true`|在表项是必填的时候是不是展示星号。如果没有被设定,使用外层 `n-form``show-require-mark`|
|rule|`FormItemRule \| Array<FormItemRule>`|`null`|验证表项的规则,它会被通过 `rule-path` 从外层表单获取的规则合并来作为表项的验证规则。推荐还是在外层表单设置所有规则。|
|first|`boolean`|`false`|是否只展示首个出错信息。|
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|ingore-path-change|`boolean`|`false`|通常 `path` 的改变会导致数据来源的变化,所以 naive-ui 会清空验证信息。如果不期望这个行为,可以将其置为 `true`|
### Form Item Row Props
接受 Form Item & [Row](n-row#Row-Props) 所有的 Props。
@ -59,20 +60,19 @@ validator-debug
<n-alert type="warning" title="Validate 方法的注意事项" style="margin-bottom: 16px;">
<n-ol align-text>
<n-li>验证只会在有 <n-text code>path</n-text> 属性的表项上执行</n-li>
<n-li>验证会使用 <n-text code>path</n-text><n-text code>model</n-text> 获取收集到的值,使用 <n-text code>path</n-text> 或者 <n-text code>rule-path</n-text>(如果声明了)去获取验证规则</n-li>
<n-li>验证将会在合法表项的所有规则上进行,不管规则的 trigger 是什么</n-li>
<n-li>默认情况下,验证将会在合法表项的所有规则上进行,不管规则的 trigger 是什么</n-li>
</n-ol>
</n-alert>
|名称|类型|说明|
|-|-|-|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any) => Promise<void>`|验证表单。Promise rejection 的返回值类型是 `Array<ValidationError>`。|
|validate|`(validateCallback?: (errors?: Array<ValidationError>) => any, shouldRuleBeApplied?: FormItemRule => boolean) => Promise<void>`|验证表单。Promise rejection 的返回值类型是 `Array<ValidationError>`。|
|clearValidationEffect|`() => void`||
### Form Item, Form Item Row, Form Item Col Methods
|名称|类型|说明|
|-|-|-|
|validate|`(trigger?: string, validateCallback?: (errors?: Array<ValidationError>) => any, options?: AsyncValidatorOptions) => Promise<void>`|验证表项Promise rejection 的返回值类型是 `Array<ValidationError>`。如果不传 trigger这一个表项全部的 Rules 都会被使用。|
|validate|`({ trigger?: string, callback?: (errors?: Array<ValidationError>) => any, shouldRuleBeApplied?: FormItemRule => boolean, options?: AsyncValidatorOptions }) => Promise<void>`|验证表项Promise rejection 的返回值类型是 `Array<ValidationError>`。如果设定 `trigger`,这一个表项全部的规则都会被使用。`shouldRuleBeApplied` 可以用来进一步过滤已经经过 `trigger` 筛选的规则|
|clearValidationEffect|`() => void`||
关于 AsyncValidatorOptions参考 <n-a href="https://github.com/yiminghe/async-validator">async-validator</n-a>

View File

@ -13,6 +13,7 @@ custom
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|type|`'primary' \| 'info' \| 'success' \| 'warning' \| 'error'`|`'primary'`||
|size|`number \| string`|`null`||
|gradient|`string \| { from: string, to: string, deg: number \| string }`|`null`||

View File

@ -12,6 +12,7 @@ custom
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|themed-style|`{ [themeName: string]: object }`|`null`||
|type|`'primary' \| 'info' \| 'success' \| 'warning' \| 'error'`|`'primary'`||
|size|`number \| string`|`null`||
|gradient|`string \| { from: string, to: string, deg: number \| string }`|`null`||

View File

@ -2,7 +2,7 @@
Naive-UI use Ionicons as its builtin icon library.
Many thanks to [Ionicons](https://github.com/ionic-team/ionicons) for creating those high quality icons!
Many thanks to [Ionicons](https://github.com/ionic-team/ionicons) for creating those high quality icons.
## Demos
To view all available icons, see <n-a href="https://ionicons.com/" target="_blank" rel="noreferer noopener">Ionicons V5</n-a> & <n-a href="https://ionicons.com/v4/" target="_blank" rel="noreferer noopener">Ionicons V4</n-a>. Icons' name are the same as Ionicons in naive-ui. See demos to know the way to import icons.

View File

@ -1,7 +1,7 @@
# 图标 Icon
Naive-UI 使用 Ionicons 作为内置的 Icon 库。
感谢 [Ionicons](https://github.com/ionic-team/ionicons) 创造了这么多好看的图标!
感谢 [Ionicons](https://github.com/ionic-team/ionicons) 创造了这么多好看的图标
## 演示
全部图标请参考 <n-a href="https://ionicons.com/" target="_blank" rel="noreferer noopener">Ionicons V5</n-a><n-a href="https://ionicons.com/v4/" target="_blank" rel="noreferer noopener">Ionicons V4</n-a>。在 Naive UI 中,图标名称和 Ionicons 维持一致。导入方式请参考演示。

View File

@ -1,5 +1,7 @@
# Input
Many years ago, people used punched card to input.
<n-alert title="Caveat" type="warning">`n-input` is a controlled component. If you don't handle with its `input` event, its value will never be changed. (v-model doesn't matter, since it is an abbreviation for controlled data-bindings)</n-alert>
## Demos
```demo
basic
@ -23,6 +25,7 @@ passively-activated
### Input Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|type|`'text' \| 'password' \| 'textarea'`|`'text'`||
|pair|`boolean`|`false`|Whether to input pairwise value.|
|value|`string \| [string, string]`|`null`|Value of input. When `pair` is `true`, `value` is an array.|

View File

@ -1,5 +1,7 @@
# 文本输入 Input
很多年前,人们还在用打孔纸卡输入。
<n-alert title="注意" type="warning">`n-input` 是严格受控的组件,如果你不对 `input` 事件做任何响应那么它的值永远不会改变。v-model 并不会出问题,因为 v-model 只是受控用法的简写)</n-alert>
## 演示
```demo
basic
@ -23,6 +25,7 @@ passively-activated
### Input Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|type|`'text' \| 'password' \| 'textarea'`|`'text'`||
|pair|`boolean`|`false`|是否输入成对的值|
|value|`string \| [string, string]`|`null`|文本输入的值。如果是 `pair``true``value` 是一个数组|

View File

@ -18,6 +18,7 @@ validator
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`number`|`null`||
|step|`number`|`1`||
|min|`number`|`null`||

View File

@ -18,6 +18,7 @@ validator
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`number`|`null`||
|step|`number`|`1`||
|min|`number`|`null`||

View File

@ -18,6 +18,7 @@ collapse
### Menu Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|collapsed|`boolean`|`false`|The collapsed status of menu, only works when menu is vertical.|
|collapsed-width|`number`|`null`|The menu width after collapsed.|
|icon-size|`number`|`20`|The icon size when menu is not collapsed.|

View File

@ -18,6 +18,7 @@ collapse
### Menu Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|collapsed|`boolean`|`false`|菜单是否折叠,值在菜单为垂直时有用|
|collapsed-width|`number`|`null`|折叠后菜单的宽度|
|icon-size|`number`|`20`|菜单未折叠时图标的大小|

View File

@ -17,6 +17,7 @@ disabled
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|page|`number`|`null`||
|page-count|`number`|`null`||
|page-size|`number`|`null`||

View File

@ -17,6 +17,7 @@ disabled
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|page|`number`|`null`||
|page-count|`number`|`null`||
|page-size|`number`|`null`||

View File

@ -14,6 +14,7 @@ processing
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|processing|`boolean`|`false`||
|type|`'line' \| 'circle' \| 'multiple-circle'`|`line`||
|status|`'default' \| 'success' \| 'error' \| 'warning' \| 'info'`|`'default'`||

View File

@ -14,6 +14,7 @@ processing
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|processing|`boolean`|`false`||
|type|`'line' \| 'circle' \| 'multiple-circle'`|`line`||
|status|`'default' \| 'success' \| 'error' \| 'warning' \| 'info'`|`'default'`||

View File

@ -1,7 +1,7 @@
# Result
Result is for showing result.
Many thanks to [twemoji](https://github.com/twitter/twemoji) for creating those high quality icons!
Many thanks to [twemoji](https://github.com/twitter/twemoji) for creating those high quality icons.
## Demos
```demo
s404
@ -17,6 +17,7 @@ error
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|status|`'info' \| 'success' \| 'error' \| 'warning' \| 404 \| '404' \| 500 \| '500' \| 400 \| '400' \| 418 \| '418'`|`'info'`||
|title|`string`|`null`||
|description|`string`|`null`||

View File

@ -1,7 +1,7 @@
# 结果页 Result
结果页是展示结果的。
感谢 [twemoji](https://github.com/twitter/twemoji) 创造了这么多好看的图标!
感谢 [twemoji](https://github.com/twitter/twemoji) 创造了这么多好看的图标
## 演示
```demo
s404
@ -17,6 +17,7 @@ error
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|status|`'info' \| 'success' \| 'error' \| 'warning' \| 404 \| '404' \| 500 \| '500' \| 400 \| '400' \| 418 \| '418'`|`'info'`||
|title|`string`|`null`||
|description|`string`|`null`||

View File

@ -7,6 +7,7 @@ size
multiple
events
filterable
tag
remote
remote-multiple
clearable
@ -24,6 +25,7 @@ action
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|loading|`boolean`|`false`||
|clearable|`boolean`|`false`||
|value|`Array \| string \| number`|`false`||
@ -32,8 +34,11 @@ action
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|disabled|`boolean`|`false`||
|options|`Array<SelectOption \| SelectOptionGroup>`|`[]`||
|remote|`boolean`|`false`|If you want to async get options|
|filter|`(pattern: string, option: Object) => boolean`|`null`||
|remote|`boolean`|`false`|If you want to async get options. Note that if remote is set, `filter` & `tag` won't work on `options`. At that time, you are taking all control of `options`.|
|filterable|`boolean`|`false`|Whether it can filter options.|
|filter|`(pattern: string, option: Object) => boolean`|A basic string based search method.||
|tag|`boolean`|`false`|Whether it can create new option, should be used with `filterable`.|
|create-option|`(label: string) => SelectOption`|`label => ({ label, value: label })`|How to create a option when you input a string to create a option. Note that `filter` will be applied to the option too. And make sure the value of the created option is not the same as any other option.|
## API
### SelectOption Type

View File

@ -0,0 +1,90 @@
# Create Option Dynamically
Use `tag` & `filterable` to create option dynamically.
```html
<n-select
v-model="multipleSelectValue"
filterable
multiple
tag
:options="options"
/>
<n-select
v-model="selectValue"
filterable
tag
:options="options"
/>
```
```js
export default {
data () {
return {
multipleSelectValue: null,
selectValue: null,
options: [
{
label: "Everybody's Got Something to Hide Except Me and My Monkey",
value: 'song0',
disabled: true
},
{
label: 'Drive My Car',
value: 'song1'
},
{
label: 'Norwegian Wood',
value: 'song2'
},
{
label: 'You Won\'t See',
value: 'song3',
disabled: true
},
{
label: 'Nowhere Man',
value: 'song4'
},
{
label: 'Think For Yourself',
value: 'song5'
},
{
label: 'The Word',
value: 'song6'
},
{
label: 'Michelle',
value: 'song7',
disabled: true
},
{
label: 'What goes on',
value: 'song8'
},
{
label: 'Girl',
value: 'song9'
},
{
label: 'I\'m looking through you',
value: 'song10'
},
{
label: 'In My Life',
value: 'song11'
},
{
label: 'Wait',
value: 'song12'
}
]
}
}
}
```
```css
.n-select {
width: 180px;
margin: 0 12px 8px 0;
}
```

View File

@ -7,6 +7,7 @@ size
multiple
events
filterable
tag
remote
remote-multiple
clearable
@ -32,8 +33,12 @@ action
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|disabled|`boolean`|`false`||
|options|`Array<SelectOption \| SelectOptionGroup>`|`[]`||
|remote|`boolean`|`false`|是否要异步获取选项|
|filter|`(pattern: string, option: Object) => boolean`|`null`||
|remote|`boolean`|`false`|是否要异步获取选项。注意如果设定了,那么 `fitler``tag` 都不会对 `options` 生效。这个时候你在全权控制 `options`|
|filterable|`boolean`|`false`|是否可以过滤|
|filter|`(pattern: string, option: Object) => boolean`|一个简单的字符串搜索算法||
|tag|`boolean`|`false`|是否可以创建新的选项,需要和 `filterable` 一起使用|
|create-option|`(label: string) => SelectOption`|`label => ({ label, value: label })`|在输入内容时如何创建一个选项。注意 `filter` 对这个选项同样会生效。同时确保这个选项和其他选项的 `value` 不要有重复|
## API
### SelectOption Type

View File

@ -0,0 +1,90 @@
# 动态创建选项
使用 `tag` & `filterable` 来允许动态创建选项。
```html
<n-select
v-model="multipleSelectValue"
filterable
multiple
tag
:options="options"
/>
<n-select
v-model="selectValue"
filterable
tag
:options="options"
/>
```
```js
export default {
data () {
return {
multipleSelectValue: null,
selectValue: null,
options: [
{
label: "Everybody's Got Something to Hide Except Me and My Monkey",
value: 'song0',
disabled: true
},
{
label: 'Drive My Car',
value: 'song1'
},
{
label: 'Norwegian Wood',
value: 'song2'
},
{
label: 'You Won\'t See',
value: 'song3',
disabled: true
},
{
label: 'Nowhere Man',
value: 'song4'
},
{
label: 'Think For Yourself',
value: 'song5'
},
{
label: 'The Word',
value: 'song6'
},
{
label: 'Michelle',
value: 'song7',
disabled: true
},
{
label: 'What goes on',
value: 'song8'
},
{
label: 'Girl',
value: 'song9'
},
{
label: 'I\'m looking through you',
value: 'song10'
},
{
label: 'In My Life',
value: 'song11'
},
{
label: 'Wait',
value: 'song12'
}
]
}
}
}
```
```css
.n-select {
width: 180px;
margin: 0 12px 8px 0;
}
```

View File

@ -14,6 +14,7 @@ mark
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|marks|`{ [markValue: number]: string }`|||
|disabled|`boolean`|`false`||
|min|`number`|`0`||

View File

@ -15,6 +15,7 @@ mark
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|marks|`{ [markValue: number]: string }`|||
|disabled|`boolean`|`false`||
|min|`number`|`0`||

View File

@ -8,6 +8,7 @@ wrap
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|spinning|`boolean`|`false`|It spin is active|
|size|`'small' \| 'in-small' \| 'medium' \| 'in-medium' \| 'large' \| 'in-large'`|`medium`||
|stroke|`string`|`null`|Color of spin|

View File

@ -8,6 +8,7 @@ wrap
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|spinning|`boolean`|`false`|Spin 在填入内容的状态是否激活|
|size|`'small' \| 'in-small' \| 'medium' \| 'in-medium' \| 'large' \| 'in-large'`|`medium`||
|stroke|`string`|`null`|Spin 的颜色|

View File

@ -12,6 +12,7 @@ vertical
### Steps Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|current|`number`|`null`||
|status|`'process' \| 'finish' \| 'error' \| 'wait'`|`'process'`||
|size|`'small' \| 'medium'`|`'medium'`||

View File

@ -12,6 +12,7 @@ vertical
### Steps Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|current|`number`|`null`||
|status|`'process' \| 'finish' \| 'error' \| 'wait'`|`'process'`||
|size|`'small' \| 'medium'`|`'medium'`||

View File

@ -13,6 +13,7 @@ event
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`boolean`|`false`||
|disabled|`boolean`|`false`||

View File

@ -13,6 +13,7 @@ event
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`boolean`|`false`||
|disabled|`boolean`|`false`||

View File

@ -16,6 +16,7 @@ display-directive
### Tabs Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|active-name|`string \| number`|`null`||
|type|`'line' \| 'card'`|`'line'`||
|closable|`boolean`|`false`||

View File

@ -16,6 +16,7 @@ display-directive
### Tabs Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|active-name|`string \| number`|`null`||
|type|`'line' \| 'card'`|`'line'`||
|closable|`boolean`|`false`||

View File

@ -18,7 +18,7 @@ export default {
},
methods: {
disabledHours (hour) {
return hour>13 && hour<16
return hour > 13 && hour < 16
},
disabledMinutes (minute, selectedHour) {
if(Number(selectedHour) === 17) {

View File

@ -15,6 +15,7 @@ format
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|placeholder|`string`|`'Select Time'`||
|value|`number`|`null`||
|format|`string`|`'HH:mm:ss'`||

View File

@ -18,7 +18,7 @@ export default {
},
methods: {
disabledHours (hour) {
return hour>13 && hour<16
return hour > 13 && hour < 16
},
disabledMinutes (minute, selectedHour) {
if(Number(selectedHour) === 17) {

View File

@ -16,6 +16,7 @@ format
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|placeholder|`string`|`'请选择时间'`||
|value|`number`|`null`||
|format|`string`|`'HH:mm:ss'`||

View File

@ -16,6 +16,7 @@ filterable
## Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`Array<string \| number>`|`null`||
|options|`Array<TransferOption>`|`[]`||
|disabled|`boolean`|`true`||
@ -42,10 +43,10 @@ filterable
|change|`(Array<string \| number>)`||
## Notes
When I heared from my FE fellow he's going to put more than a thousand of items inside the transfer, I was astonished. My poor mind can't come up with a scene that must use a transfer with thousands of items. But I must admit, it's my mind that always not considerate enough.
When I heared from my colleague he's going to put more than a thousand items into the transfer, I was astonished. My poor imagination can't come up with a scene that must use a transfer with thousands of items. But I must admit, it's my mind that always not considerate enough.
Months earlier, I have built a interisting animation in transfer but it will cause reflow on many DOM elements. At that time, I hadn't think of people would insert too many data in it. Although I never compromise on style, it's hard to surpass the limit of browser and hardware. It sounds like a kind of philosophy problem to build a car as comfort as a Rolls Royce and as fast as a Ferrari (or Porsche, etc) which is nearly impossible.
Months earlier, I have built a interesting animation in transfer but it will cause reflow on many DOM elements. At that time, I hadn't think of people would insert so much data in it. Although I never compromise on styles, it's hard to surpass the limit of browser and hardware. It sounds like a kind of philosophy problem to build a car as comfort as a Rolls Royce and as fast as a Ferrari (or Porsche, etc) which is nearly impossible.
(Don't tell me the Bentley Continental GT, I don't like the car looks.)
(Don't tell me the Bentley Continental GT, I don't like the car's appearance.)
Style can't be compromised on. However, the problem need to be solved. So finally I add a boost trigger on transfer to deal with large data (by the way turn off the animation).

View File

@ -16,6 +16,7 @@ filterable
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|value|`Array<string \| number>`|`null`||
|options|`Array<TransferOption>`|`[]`||
|disabled|`boolean`|`true`||

View File

@ -14,6 +14,7 @@ default-files
### Upload Props
|Name|Type|Default|Description|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|name|`string`|`'file'`|The field name of file in form data.|
|accept|`string`|`null`|The accept type of upload. See <n-a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept">accept</n-a>.|
|action|`string`|`null`|The URL to submit data to.|
@ -30,8 +31,8 @@ default-files
|file-list|`Array<UploadFile>`|`undefined`|The file list of component. If set, the component will work in controlled manner.|
|file-list-style|`Object`|`null`|The style of file list area|
|default-file-list|`Array<UploadFile>`|`[]`|The default file list in uncontrolled manner.|
|show-cancel-button|`boolean`|`true`|Whether to show remove button (at file pending, uploadin, error status). Click on cancel button will fire onRemove callback.|
|show-remove-button|`boolean`|`true`|Whether to show remove button (at file finished status). Click on remove button will fire onRemove callback.|
|show-cancel-button|`boolean`|`true`|Whether to show remove button (at file pending, uploadin, error status). Click on cancel button will fire `on-remove` callback.|
|show-remove-button|`boolean`|`true`|Whether to show remove button (at file finished status). Click on remove button will fire `on-remove` callback.|
|disabled|`boolean`|`false`||
### UploadFile Type

View File

@ -13,6 +13,7 @@ default-files
### Upload Props
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark'`|`null`||
|name|`string`|`'file'`|文件在提交表单中的字段名|
|accept|`string`|`null`|接受的文件类型,参考 <n-a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept">accept</n-a>|
|action|`string`|`null`|请求提交的地址|
@ -29,11 +30,10 @@ default-files
|file-list|`Array<UploadFile>`|`undefined`|文件列表,如果传入组件会处于受控状态|
|file-list-style|`Object`|`null`|文件列表区域的样式|
|default-file-list|`Array<UploadFile>`|`[]`|非受控状态下默认的文件列表|
|show-cancel-button|`boolean`|`true`|是否显示取消按钮(在 pending、uploading、error 的时候展示),点击取消按钮会触发 onRemove 回调|
|show-remove-button|`boolean`|`true`|是否显示删除按钮(在 finished 的时候展示),点击删除按钮会触发 onRemove 回调|
|show-cancel-button|`boolean`|`true`|是否显示取消按钮(在 pending、uploading、error 的时候展示),点击取消按钮会触发 `on-remove` 回调|
|show-remove-button|`boolean`|`true`|是否显示删除按钮(在 finished 的时候展示),点击删除按钮会触发 `on-remove` 回调|
|disabled|`boolean`|`false`||
### UploadFile Type
|属性|类型|说明|
|-|-|-|

View File

@ -107,6 +107,7 @@ function changeThemeInPath (path, theme) {
<style lang="scss" scoped>
.demo {
z-index: auto;
position: absolute;
left: 0;
right: 0;

View File

@ -27,6 +27,7 @@
<n-layout-header
bordered
:style="{
position: 'relative',
zIndex: zIndex
}"
>

View File

@ -195,18 +195,18 @@ export default function (locale, instance) {
titleExtra: 'Checkbox',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-checkbox'
},
{
name: 'Dynamic Input',
title: '动态输入',
titleExtra: 'Dynamic Input',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-dynamic-input'
},
{
name: 'Date Picker',
title: '日期选择器',
titleExtra: 'Date Picker',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-date-picker'
},
{
name: 'Dynamic Input',
title: '动态录入',
titleExtra: 'Dynamic Input',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-dynamic-input'
},
{
name: 'Form',
title: '表单',
@ -673,14 +673,14 @@ export default function (locale, instance) {
name: 'Checkbox',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-checkbox'
},
{
name: 'Dynamic Input',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-dynamic-input'
},
{
name: 'Date Picker',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-date-picker'
},
{
name: 'Dynamic Input',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-dynamic-input'
},
{
name: 'Form',
path: `/${instance.lang}/${instance.theme}/doc` + '/n-form'

View File

@ -111,8 +111,14 @@ export default {
return this.state.mode
},
url () {
<<<<<<< HEAD
const relativePath = this.NDocumentation.gheUrl.replace('index.md', hyphenToHump(this.name) + '.md')
return relativePath
=======
// const relativePath = this.NDocumentation.url
// return 'https://***REMOVED***/tree/develop/' + relativePath
return ''
>>>>>>> upstream/develop
}
},
watch: {
@ -135,13 +141,17 @@ export default {
},
methods: {
handleEditOnGithubClick () {
window.open(this.url, '_blank')
this.$NMessage.info('Preview Only')
// window.open(this.url, '_blank')
},
toggleCodeDisplay () {
this.showCode = !this.showCode
},
init () {
<<<<<<< HEAD
console.log('this111111', this.NDocumentation.url)
=======
>>>>>>> upstream/develop
const map = this.NDocumentation.anchorLinkMap
this.isDebug = this.name && (~this.name.indexOf('debug') || ~this.name.indexOf('Debug'))
if (this.isDebug) {

View File

@ -1,6 +1,6 @@
{
"name": "naive-ui",
"version": "0.7.24",
"version": "0.7.25",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",

View File

@ -8,7 +8,9 @@
'n-alert--no-icon': showIcon === false,
[`n-${syntheticTheme}-theme`]: syntheticTheme
}"
:style="syntheticStyle"
:style="{
...syntheticStyle
}"
>
<div v-if="closable" class="n-alert__close" @click="handleCloseClick">
<n-icon>

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