mirror of
https://github.com/ElemeFE/element.git
synced 2025-12-16 11:44:01 +08:00
Compare commits
53 Commits
v2.0.0-rc.
...
v2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d7d5a8757 | ||
|
|
906580eb88 | ||
|
|
c1155b3be0 | ||
|
|
80e60efc0a | ||
|
|
6dc98ebcf7 | ||
|
|
9ae38e01e4 | ||
|
|
ee72cd5b9f | ||
|
|
1412b5757c | ||
|
|
633cb30d52 | ||
|
|
03a52ab38e | ||
|
|
fecc38f495 | ||
|
|
5d172ad5cf | ||
|
|
877718099e | ||
|
|
f642294949 | ||
|
|
0a24f05125 | ||
|
|
7074a247f4 | ||
|
|
6619daf1ab | ||
|
|
5d6a7b6f9c | ||
|
|
0cca820dac | ||
|
|
3eb06dcb0e | ||
|
|
409a3c852f | ||
|
|
146e02c4a3 | ||
|
|
468124f956 | ||
|
|
476d1c4f6e | ||
|
|
0c47e6d308 | ||
|
|
85a8ea0ade | ||
|
|
2b5efef3fa | ||
|
|
c0e9a0f44f | ||
|
|
31e39a3e8a | ||
|
|
8479b2fbaf | ||
|
|
2e8161e68e | ||
|
|
cdf05c46ec | ||
|
|
d180ec5c9e | ||
|
|
6a172c758b | ||
|
|
c3d996a60d | ||
|
|
aa709c7071 | ||
|
|
e8cf84cbc0 | ||
|
|
9aac9d80eb | ||
|
|
ca0bc1359f | ||
|
|
407fd70ba6 | ||
|
|
6995641d72 | ||
|
|
f3aa9b30ad | ||
|
|
d2efebcbeb | ||
|
|
4b3edc13ab | ||
|
|
3cc8b0064b | ||
|
|
cee3154304 | ||
|
|
07acf66a69 | ||
|
|
4aff63826c | ||
|
|
00e8c7454f | ||
|
|
b85b67d928 | ||
|
|
e2932fd781 | ||
|
|
d2908487d7 | ||
|
|
c856d9268b |
@@ -1,15 +1,121 @@
|
||||
## Changelog
|
||||
|
||||
### 2.0.0-rc.1
|
||||
### 2.0.2
|
||||
|
||||
*2017-10-25*
|
||||
*2017-10-31*
|
||||
|
||||
- Now right-clicking the buttons of InputNumber won't change its value, #7817
|
||||
- `validate` method of Form can now wait for asynchronous validations before executing its callback, #7774 (by @Allenice)
|
||||
- Fixed range selection of DatePicker not working in Chromium 53-57 browsers, #7838
|
||||
- Fixed missing preview and delete icons of Upload when its `list-type` is picture-card, #7857
|
||||
- Added `sort-by` attribute for TableColumn, #7828 (by @wangfengming)
|
||||
- Fixed DatePicker sometimes displaying wrong year number when selecting the first week in week mode, #7860 (by @hh23485)
|
||||
- Fixed icon style error of vertical Steps, #7891
|
||||
- The hot area for node arrows in Tree is expanded, #7891
|
||||
|
||||
### 2.0.1
|
||||
|
||||
*2017-10-28*
|
||||
|
||||
- Fixed style error of RadioButton and CheckboxButton, #7793
|
||||
- Fixed TimePicker not respond to mouse scroll in some conditions, #7811
|
||||
- Fixed incomplete styles of some components when imported on demand, #7811
|
||||
|
||||
### 2.0.0 Carbon
|
||||
|
||||
*2017-10-27*
|
||||
|
||||
#### New features
|
||||
- Form
|
||||
- Added `clearValidate` method for clearing validating results for all form items, #7623
|
||||
- General
|
||||
- A new theme: `theme-chalk`
|
||||
- Accessibility of the following components are improved: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload
|
||||
- Added TypeScript typings
|
||||
- All existing icons are redesigned. Some new icons are added
|
||||
- Added a series of breakpoint-based utility classes that hide elements when the viewport size meets certain conditions
|
||||
- Added layout components: Container, Header, Aside, Main, Footer
|
||||
- Now you can configure component sizes globally. When importing Element, you can add a global config object with a `size` prop to configure default sizes for all components.
|
||||
- Button
|
||||
- Added `round` attribute. It's used for round-cornered Buttons #6643
|
||||
- TimeSelect
|
||||
- Now can be navigated by `Up` and `Down`, and hitting `Enter` selects the time #6023
|
||||
- TimePicker
|
||||
- Now can be navigated by arrow keys, and hitting `Enter` selects the time #6050
|
||||
- Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169
|
||||
- Added `arrow-control` attribute to spin the time with arrows #7438
|
||||
- Tree
|
||||
- Now child nodes don't render before the first expand #6257
|
||||
- Added `check-descendants` attribute. It determines if child nodes are checked when checking their parent node in `lazy` mode #6235
|
||||
- Tag
|
||||
- Added `size` attribute #7203
|
||||
- Datepicker
|
||||
- Now `timeFormat` can format the TimePicker when type is set to `datetimerange` #6052
|
||||
- Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169
|
||||
- Added `value-format` attribute to customize the format of the binding value, #7367
|
||||
- Added `unlink-panels` attribute to unlink the two date panels when selecting a date range
|
||||
- MessageBox
|
||||
- Added `closeOnHashChange` attribute #6043
|
||||
- Added `center` attribute so that the content can be centered #7029
|
||||
- Added `roundButton` attribute to display round Buttons #7029
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6043
|
||||
- Added `inputType` attribute to assign type for the inner input box, #7651
|
||||
- Dialog
|
||||
- Added `width`、`fullscreen`、`append-to-body` attributes. Now Dialog can be nested
|
||||
- Added `center` attribute so that the content can be centered #7042
|
||||
- Added `focus-after-closed`、`focus-after-open` to improve accessibility #6511
|
||||
- ColorPicker
|
||||
- Now you can type colors in the input box #6167
|
||||
- Added `size` and `disabled` attributes #7026
|
||||
- Added `popper-class` attribute #7351
|
||||
- Message
|
||||
- Now color of the icons can be overridden by CSS #6207
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6207
|
||||
- Added `center` attribute so that the content can be centered #6875
|
||||
- Notification
|
||||
- Added `position` attribute to configure where Notification pops up #6231
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6231
|
||||
- Added `showClose` attribute to hide the close button #6402
|
||||
- Rate
|
||||
- Added `show-score` attribute to determine if current score is displayed #6295
|
||||
- Tabs
|
||||
- Added `tab-position` attribute #6096
|
||||
- Radio
|
||||
- Added `border` and `size` attributes #6690
|
||||
- Checkbox
|
||||
- Added `border` and `size` attributes #6690
|
||||
- Alert
|
||||
- Added `center` attribute so that the content can be centered #6876
|
||||
- Menu
|
||||
- Added `background-color`, `text-color` and `active-text-color` attributes #7064
|
||||
- Added `open` and `close` methods to open and close SubMenu programmatically, #7412
|
||||
- Form
|
||||
- Added `inline-message` attribute to determine if the validation message is displayed in inline style #7032
|
||||
- Added `status-icon` attribute to display a feedback icon when validated #7032
|
||||
- Form and FormItem now have a `size` attribute. Inner components will inherit this size if not specified on themselves, #7428
|
||||
- `validate` method will now return a promise if the callback is omitted, #7405
|
||||
- Added `clearValidate` method for clearing validating results for all form items, #7623
|
||||
- Input
|
||||
- Added `suffix` and `prefix` named slots, `suffixIcon` and `prefixIcon` attributes to add contents inside the input box #7032
|
||||
- Breadcrumb
|
||||
- Added `separator-class` attribute to support icons as item separators #7203
|
||||
- Steps
|
||||
- Added `simple` attribute to activate simple-styled Steps #7274
|
||||
- Pagination
|
||||
- Added `prev-text` and `next-text` attributes to customize texts of previous page and next page #7005
|
||||
- Loading
|
||||
- Now you can customize spinner icon and background color with `spinner` and `background` prop, #7390
|
||||
- Autocomplete
|
||||
- Added `debounce` attribute, #7413
|
||||
- Upload
|
||||
- Added `limit` and `on-exceed` attributes to limit the amount of files, #7405
|
||||
- DateTimePicker
|
||||
- Added `time-arrow-control` attribute to activate `arrow-control` of the nesting TimePicker, #7438
|
||||
- Layout
|
||||
- Added a new breakpoint `xl` for viewport wider than 1920px
|
||||
- Table
|
||||
- Added `span-method` attribute for merging cells
|
||||
- Added `clearSort` method to clear sorting programmatically
|
||||
- Added `clearFilter` method to clear filter programmatically
|
||||
- For expandable rows, when a row is expanded, a `.expanded` class will be added to its class list, so that you can customize its style
|
||||
- Added `size` attribute
|
||||
- Added `toggleRowExpansion` method to expand or collapse expandable rows programmatically
|
||||
- Added `cell-class-name` attribute to assign class name for cells
|
||||
@@ -20,237 +126,74 @@
|
||||
- Added `header-cell-style` attribute to style header cells
|
||||
- TableColumn's `prop` attribute now accepts `object[key]` notations
|
||||
- Added `index` attribute for TableColumn to customize row indices
|
||||
|
||||
#### Fixes
|
||||
- Table
|
||||
- Fixed a dynamic `max-height` bug
|
||||
- Fixed some style calculation errors
|
||||
|
||||
#### Breaking changes
|
||||
- Autocomplete
|
||||
- Removed `props` attribute. Now you can use `value-key` attribute to designate key name of the input suggestion
|
||||
object for display
|
||||
- Table
|
||||
- `append` slot is moved outside the `tbody` element to avoid multiple rendering
|
||||
- `expand` event is renamed to `expand-change`
|
||||
- The params of `row-class-name` and `row-style` method is now an object
|
||||
|
||||
### 2.0.0-beta.1
|
||||
|
||||
*2017-10-20*
|
||||
|
||||
#### New features
|
||||
- General
|
||||
- Added TypeScript typings
|
||||
- All existing icons are redesigned. Some new icons are added.
|
||||
- To help you migrate from Element 1.x, we added some console warnings against deprecated APIs. When you use a removed or renamed attribute or event in your project, you'll get a warning like this:
|
||||
```
|
||||
[Element Migrating][ElSwitch][Attribute]: on-color is renamed to active-color.
|
||||
```
|
||||
- Added a series of breakpoint-based utility classes that hide elements when the viewport size meets certain conditions
|
||||
- Layout
|
||||
- Added a new breakpoint `xl` for viewport wider than 1920px
|
||||
- Table
|
||||
- Added `span-method` attribute for merging cells
|
||||
- Added `clearSort` method to clear sorting programmatically
|
||||
- Added `clearFilter` method to clear filter programmatically
|
||||
- For expandable rows, when a row is expanded, a `.expanded` class will be added to its class list, so that you can customize its styles
|
||||
- DatePicker
|
||||
- Added `unlink-panels` attribute to unlink the two date panels when selecting a date range
|
||||
- Select
|
||||
- Added `reserve-keyword` attribute for reserving current search keyword after selecting an option
|
||||
|
||||
#### Fixes
|
||||
#### Bug fixes
|
||||
- DatePicker
|
||||
- Fixed `v-model` returning the second day of the selected week in week mode #6038
|
||||
- Fixed the first input being cleared in `daterange` type #6021
|
||||
- DateTimePicker
|
||||
- Fixed DateTimePicker and TimePicker affecting each other when picked #6090
|
||||
- Fixed hour and second can be beyond limit when selecting time #6076
|
||||
- TimePicker
|
||||
- Fixed `v-model` not update correctly when blurred #6023
|
||||
- Dialog
|
||||
- Fixed texts having blurry edges when opening and closing nesting dropdowns #6088
|
||||
- Select
|
||||
- Improved performance. Now Vue dev-tool won't crash when a large number of Selects are destroyed #6151
|
||||
- Table
|
||||
- Now `header-align` of TableColumn works properly
|
||||
- Fixed a bug that Table remains hiding when its parent element appears from `display: none`
|
||||
- Fixed Table expanding its width when its parent element has `display: flex`
|
||||
- Fixed a bug that fixed columns of a Table with `append` slot would disappear when data is dynamically fetched
|
||||
- Fixed `expand-row-keys` attribute not working with initial value
|
||||
- Fixed filter failing when `data` updates
|
||||
- Fixed a calculation error of fixed columns layout with grouped headers
|
||||
- Fixed a dynamic `max-height` bug
|
||||
- Fixed some style calculation errors
|
||||
|
||||
#### Breaking changes
|
||||
- General
|
||||
- Removed `theme-default`
|
||||
- Compatible with Vue 2.5.2+ and IE 10+
|
||||
- `change` event of form components and `current-change` event of Pagination now only trigger on user interaction
|
||||
- `size` attribute of Button and form components now accept `medium`, `small` and `mini`
|
||||
- To facilitate the use of third-party icons, `icon` attribute of Button and Steps, `prefix-icon` and `suffix-icon` attributes of Input now require a full class name
|
||||
- Dialog
|
||||
- Removed `size` attribute. Now the size of Dialog can be configured by `width` and `fullscreen`
|
||||
- Now the visibility of Dialog cannot be controlled by `v-model`
|
||||
- Rate
|
||||
- `text-template` is renamed to `score-template`
|
||||
- Dropdown
|
||||
- `menu-align` is renamed to `placement`. Now it supports more positions
|
||||
- Transfer
|
||||
- `footer-format` is renamed to `format`
|
||||
- Switch
|
||||
- Attributes starting with `on-*` will be parsed to events in JSX, making all `on-*` attributes of Switch not
|
||||
able to work in JSX. So `on-*` attributes are renamed to `active-*`, and accordingly `off-*` attributes are renamed to `inactive-*`. This change affects the following attributes: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value`
|
||||
able to work in JSX. So `on-*` attributes are renamed to `active-*`, and accordingly `off-*` attributes are renamed to `inactive-*`. This change affects the following attributes: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value`
|
||||
- `active-text` and `inactive-text` attributes now don't have default values
|
||||
- Tag
|
||||
- `type` attribute now accepts `success`, `info`, `warning` and `danger`
|
||||
- Menu
|
||||
- Removed `theme` attribute. The color of Menu can be configured using `background-color`, `text-color` and `active-text-color`
|
||||
- Input
|
||||
- Removed `icon` attribute. Now the suffix icon can be configured using `suffix-icon` attribute or `suffix` named slot
|
||||
- Removed `on-icon-click` attribute and `click` event. Now to add click handler on icons, please use named slots
|
||||
- `change` event now behaves like the native input element, which triggers only on blur or pressing enter. If you need to respond to user input in real time, you can use `input` event.
|
||||
- Autocomplete
|
||||
- Removed `custom-item` attribute. Now the template of input suggestions can be customized using `scoped slot`
|
||||
- Removed `props` attribute. Now you can use `value-key` attribute to designate key name of the input suggestion object for display
|
||||
- Steps
|
||||
- Removed `center` attribute
|
||||
- Now the Steps will fill its parent container by default
|
||||
- DatePicker
|
||||
- The params of DatePicker's `change` event is now the binding value itself. Its format is controlled by `value-format`
|
||||
- Table
|
||||
- Removed support for customizing column template using `inline-template`
|
||||
- `sort-method` now aligns with `Array.sort`. It should return a number instead of a boolean
|
||||
|
||||
### 2.0.0-alpha.3
|
||||
|
||||
*2017-10-16*
|
||||
|
||||
#### New features
|
||||
- General
|
||||
- Configure component sizes globally. Now when you import Element, you can add a global config object with a `size` prop to configure default sizes for all components. For fully import:
|
||||
```JS
|
||||
import Vue from 'vue'
|
||||
import Element from 'element-ui'
|
||||
Vue.use(Element, { size: 'small' })
|
||||
```
|
||||
For partial import:
|
||||
```JS
|
||||
import Vue from 'vue'
|
||||
import { Button } from 'element-ui'
|
||||
|
||||
Vue.prototype.$ELEMENT = { size: 'small' }
|
||||
Vue.use(Button)
|
||||
```
|
||||
With the above config, the default size of all components that have `size` attribute will be 'small'.
|
||||
- Loading
|
||||
- Now you can customize spinner icon and background color with `spinner` and `background` prop, #7390
|
||||
- Autocomplete
|
||||
- Added `debounce` attribute, #7413
|
||||
- Upload
|
||||
- Added `limit` and `on-exceed` attributes to limit the amount of files, #7405
|
||||
- Menu
|
||||
- Added `open` and `close` methods to open and close SubMenu programmatically, #7412
|
||||
- DatePicker
|
||||
- Added `value-format` attribute to customize the format of the binding value, #7367
|
||||
- TimePicker
|
||||
- Added `arrow-control` attribute to spin the time with arrows #7438
|
||||
- DateTimePicker
|
||||
- Added `time-arrow-control` attribute to activate `arrow-control` of the nesting TimePicker, #7438
|
||||
- Form
|
||||
- Form and Form-item now have a `size` attribute. Inner components will inherit this size if not specified on themselves, #7428
|
||||
- `validate` method will now return a promise if the callback is omitted, #7405
|
||||
|
||||
#### Fixes
|
||||
- Fixed the console warning `Injection "elFormItem" not found` of some components
|
||||
|
||||
#### Breaking changes
|
||||
- The params of DatePicker's `change` event is now the binding value itself. Its format is controlled by `value-format`
|
||||
- Input's `change` event now behaves like the native input element, which triggers only on blur or pressing enter. If you need to respond to user input in real time, you can use `input` event.
|
||||
- Only compatible with Vue 2.5.2 and beyond
|
||||
|
||||
### 2.0.0-alpha.2
|
||||
|
||||
*2017-10-05*
|
||||
|
||||
- Updated the primary color of `theme-chalk`, #7351
|
||||
- Fixed console error when using Dropdown, #7322
|
||||
- Fixed console error when using Menu, #7321
|
||||
- Added `popper-class` attribute for ColorPicker, #7351
|
||||
- Now Button's `disabled` attribute works correctly, #7352
|
||||
|
||||
### 2.0.0-alpha.1
|
||||
|
||||
*2017-09-30*
|
||||
|
||||
#### New features
|
||||
- General
|
||||
- A new theme: `theme-chalk`
|
||||
- Accessibility of the following components are improved: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload
|
||||
- Layout components: Container, Header, Aside, Main, Footer
|
||||
- Button
|
||||
- Added `round` attribute. It's used for round-cornered Buttons #6643
|
||||
- TimeSelect
|
||||
- Now can be navigated by `Up` and `Down`, and hitting `Enter` selects the time #6023
|
||||
- TimePicker
|
||||
- Now can be navigated by arrow keys, and hitting `Enter` selects the time #6050
|
||||
- Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169
|
||||
- Tree
|
||||
- Now child nodes don't render before the first expand #6257
|
||||
- Added `check-descendants` attribute. It determines if child nodes are checked when checking their parent node
|
||||
in `lazy` mode #6235
|
||||
- Tag
|
||||
- Added `size` attribute #7203
|
||||
- Datepicker
|
||||
- Now `timeFormat` can format the TimePicker when type is set to `datetimerange` #6052
|
||||
- Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169
|
||||
- MessageBox
|
||||
- Added `closeOnHashChange` attribute #6043
|
||||
- Added `center` attribute so that the content can be centered #7029
|
||||
- Added `roundButton` attribute to display round Buttons #7029
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6043
|
||||
- Dialog
|
||||
- Added `width`、`fullscreen`、`append-to-body` attributes. Now Dialog can be nested
|
||||
- Added `center` attribute so that the content can be centered #7042
|
||||
- Added `focus-after-closed`、`focus-after-open` to improve accessibility #6511
|
||||
- ColorPicker
|
||||
- Now you can type colors in the input box #6167
|
||||
- Added `size` and `disabled` attributes #7026
|
||||
- Message
|
||||
- Now color of the icons can be overridden by CSS #6207
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6207
|
||||
- Added `center` attribute so that the content can be centered #6875
|
||||
- Notification
|
||||
- Added `position` attribute to configure where Notification pops up #6231
|
||||
- Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string<sup>*</sup> #6231
|
||||
- Added `showClose` attribute to hide the close button #6402
|
||||
- Rate
|
||||
- Added `show-score` attribute to determine if current score is displayed #6295
|
||||
- Tabs
|
||||
- Added `tab-position` attribute #6096
|
||||
- Radio
|
||||
- Improved accessibility #6101
|
||||
- Added `border` and `size` attributes #6690
|
||||
- Checkbox
|
||||
- Added `border` and `size` attributes #6690
|
||||
- Alert
|
||||
- Added `center` attribute so that the content can be centered #6876
|
||||
- Menu
|
||||
- Added `background-color`, `text-color` and `active-text-color` attributes #7064
|
||||
- Form
|
||||
- Added `inline-message` attribute to determine if the validation message is displayed in inline style #7032
|
||||
- Added `status-icon` attribute to display a feedback icon when validated #7032
|
||||
- Input
|
||||
- Added `suffix` and `prefix` named slots, `suffixIcon` and `prefixIcon` attributes to add contents inside the input box #7032
|
||||
- Breadcrumb
|
||||
- Added `separator-class` attribute to support icons as item separators #7203
|
||||
- Steps
|
||||
- Added `simple` attribute to activate simple-styled Steps #7274
|
||||
- Pagination
|
||||
- Added `prev-text` and `next-text` attributes to customize texts of prev page and next page #7005
|
||||
|
||||
#### Bug fixes
|
||||
- DatePicker
|
||||
- Fixed `v-model` returning the second day of the selected week in week mode #6038
|
||||
- Fixed the first input being cleared in `daterange` type #6021
|
||||
- DateTimePicker
|
||||
- Fixed DateTimePicker and TimePicker affecting each other when picked #6090
|
||||
- Fixed hour and second can be beyond limit when selecting time #6076
|
||||
- TimePicker
|
||||
- Fixed `v-model` not update correctly when blurred #6023
|
||||
- Dialog
|
||||
- Fixed texts having blurry edges when opening and closing nesting dropdowns #6088
|
||||
- Select
|
||||
- Improved performance. Now Vue dev-tool won't crash when a large number of Selects are destroyed #6151
|
||||
|
||||
#### Breaking changes
|
||||
- General
|
||||
- Removed `theme-default`
|
||||
- `change` event of form components and `current-change` event of Pagination now only trigger on user interaction
|
||||
- `size` attribute of Button and form components can no longer be set to `large`. Now they accept `medium`, `small` and `mini`
|
||||
- To facilitate the use of third-party icons, `icon` attribute of Button and Steps, `prefix-icon` and `suffix-icon` attributes of Input now require a full class name
|
||||
- Dialog
|
||||
- Removed `size` attribute. Now the size of Dialog can be configured by `width` and `fullscreen`
|
||||
- Now the visibility of Dialog cannot be controlled by `v-model`
|
||||
- Rate
|
||||
- `text-template` is renamed to `score-template`
|
||||
- Dropdown
|
||||
- `menu-align` is renamed to `placement`. Now it supports more positions
|
||||
- Transfer
|
||||
- `footer-format` is renamed to `format`
|
||||
- Switch
|
||||
- `on-text` and `off-text` attributes now don't have default values
|
||||
- Tag
|
||||
- `type` attribute now accepts `success`, `info`, `warning` and `danger`
|
||||
- `close-transition` is renamed to `disable-transitions`
|
||||
- Menu
|
||||
- Removed `theme` attribute. The color of Menu can be configured using `background-color`, `text-color` and `active-text-color`
|
||||
- Input
|
||||
- Removed `icon` attribute. Now the suffix icon can be configured using `suffix-icon` attribute or `suffix` named slot
|
||||
- Removed `on-icon-click` attribute and `click` event. Now to add click handler on icons, please use named slots
|
||||
- Autocomplete
|
||||
- Removed `icon` and `on-icon-click` attributes. Now the icons can be configured using `prefix` or `suffix` named slot
|
||||
- Removed `custom-item` attribute. Now the template of input suggestions can be customized using `scoped slot`
|
||||
- Table
|
||||
- Removed support for customizing column template using `inline-template`
|
||||
- Steps
|
||||
- Removed `center` attribute
|
||||
- Now the Steps will fill its parent container by default
|
||||
- `append` slot is moved outside the `tbody` element to avoid multiple rendering
|
||||
- `expand` event is renamed to `expand-change`
|
||||
- The params of `row-class-name` and `row-style` method is now an object
|
||||
|
||||
##
|
||||
<i><sup>*</sup> Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to [XSS attacks](https://en.wikipedia.org/wiki/Cross-site_scripting). So when `dangerouslyUseHTMLString` is on, please make sure the content of `message` is trusted, and **never** assign `message` to user-provided content.</i>
|
||||
@@ -1,140 +1,39 @@
|
||||
## 更新日志
|
||||
|
||||
### 2.0.0-rc.1
|
||||
*2017-10-25*
|
||||
### 2.0.2
|
||||
|
||||
#### 新特性
|
||||
- Form
|
||||
- 新增 `clearValidate` 方法,用于清空所有表单项的验证信息,#7623
|
||||
- MessageBox
|
||||
- 新增 `inputType` 属性,用户指定内部输入框的类型,#7651
|
||||
- Table
|
||||
- 新增 `size` 属性,用于控制表格尺寸
|
||||
- 新增 `toggleRowExpansion` 方法,用于手动展开或关闭行
|
||||
- 新增 `cell-class-name` 属性,用于指定单元格的类名
|
||||
- 新增 `cell-style` 属性,用于指定单元格的样式
|
||||
- 新增 `header-row-class-name` 属性,用于指定表头行的类名
|
||||
- 新增 `header-row-style` 属性,用于指定表头行的样式
|
||||
- 新增 `header-cell-class-name` 属性,用于指定表头单元格的类名
|
||||
- 新增 `header-cell-style` 属性,用于指定表头单元格的样式
|
||||
- TableColumn 的 `prop` 属性支持 `object[key]` 格式
|
||||
- TableColumn 新增 `index` 属性,用于自定义索引值
|
||||
*2017-10-31*
|
||||
|
||||
#### 修复
|
||||
- Table
|
||||
- 修复 `max-height` 变更后无法恢复的问题
|
||||
- 修复一些样式上的计算错误
|
||||
- 在 InputNumber 的加减按钮上单击鼠标右键不再触发值的改变,#7817
|
||||
- Form 的 `validate` 方法现在能够正确地在异步校验完成后执行回调了,#7774(by @Allenice)
|
||||
- 修复 DatePicker 的范围选择在内核为 Chromium 53-57 的浏览器中无法使用的问题,#7838
|
||||
- 修复 `list-type` 为 picture-card 的 Upload 预览和删除图标丢失的问题,#7857
|
||||
- 新增 TableColumn 的 `sort-by` 属性,#7828(by @wangfengming)
|
||||
- 修复周模式下的 DatePicker 在选择某年第一周可能会显示为前一年第一周的问题,#7860(by @hh23485)
|
||||
- 修复垂直模式的 Steps 中图标宽度的样式错误,#7891
|
||||
- 增大了 Tree 中展开箭头的点击热区,#7891
|
||||
|
||||
#### 非兼容性更新
|
||||
- Autocomplete
|
||||
- 移除 `props` 属性,现在使用 `value-key` 属性指定输入建议对象中用于显示的键名
|
||||
- Table
|
||||
- 将 `append` slot 移至 `tbody` 元素以外,以保证其只被渲染一次
|
||||
- `expand` 事件更名为 `expand-change`,以保证 API 的命名一致性
|
||||
- `row-class-name` 和 `row-style` 的函数参数改为对象,以保证 API 的一致性
|
||||
### 2.0.1
|
||||
|
||||
### 2.0.0-beta.1
|
||||
*2017-10-20*
|
||||
*2017-10-28*
|
||||
|
||||
#### 新特性
|
||||
- 综合
|
||||
- 新增 TypeScript 类型声明
|
||||
- 重绘了全部图标,并新增了部分图标
|
||||
- 为部分非兼容性更新增加控制台警告,方便迁移项目。当你在项目中使用了被移除或更名了的属性或事件时,控制台会出现一条警告,例如:
|
||||
```
|
||||
[Element Migrating][ElSwitch][Attribute]: on-color is renamed to active-color.
|
||||
```
|
||||
- 新增了一系列基于断点的工具类,用于当视口尺寸满足一定条件时隐藏元素
|
||||
- Layout
|
||||
- 新增断点 `xl`,适用于宽度大于 1920px 的视口
|
||||
- Table
|
||||
- 新增 `span-method` 属性,用于合并行或列
|
||||
- 新增 `clearSort` 方法,用于清空排序状态
|
||||
- 新增 `clearFilter` 方法,用于清空过滤状态
|
||||
- 对于可展开行,当该行展开时会获得一个 `.expanded` 类名,方便自定义样式
|
||||
- DatePicker
|
||||
- 新增 `unlink-panels` 属性,用于在选择日期范围时取消两个日期面板之间的联动
|
||||
- Select
|
||||
- 新增 `reserve-keyword` 属性,用于在选择某个选项后保留当前的搜索关键词
|
||||
- 修复 RadioButton 和 CheckboxButton 的样式问题,#7793
|
||||
- 修复 TimePicker 在某些情况下无法滚动的问题,#7811
|
||||
- 修复部分组件在按需引入时样式不完整的问题,#7811
|
||||
|
||||
#### 修复
|
||||
- Table
|
||||
- 修复 TableColumn 的 `header-align` 属性失效的问题
|
||||
- 修复 Table 在父元素从 `display: none` 变成其他状态时会隐藏的问题
|
||||
- 修复 Table 在父元素为 `display: flex` 时可能出现的宽度逐渐变大的问题
|
||||
- 修复 `append` 具名 slot 和固定列并存时,动态获取表格数据会导致固定列消失的问题
|
||||
- 修复 `expand-row-keys` 属性初始化无效的问题
|
||||
- 修复 `data` 改变时过滤条件失效的问题
|
||||
- 修复多级表头时固定列隐藏情况计算错误的问题
|
||||
### 2.0.0 Carbon
|
||||
|
||||
#### 非兼容性更新
|
||||
- Switch
|
||||
- 由于 `on-*` 属性在 JSX 中会被识别为事件,导致 Switch 所有 `on-*` 属性在 JSX 中无法正常工作,所以 `on-*` 属性更名为 `active-*`,对应地,`off-*` 属性更名为 `inactive-*`。受到影响的属性有:`on-icon-class`、`off-icon-class`、`on-text`、`off-text`、`on-color`、`off-color`、`on-value`、`off-value`
|
||||
- Table
|
||||
- `sort-method` 现在和 `Array.sort` 保持一致的逻辑,要求返回一个数字。
|
||||
|
||||
### 2.0.0-alpha.3
|
||||
*2017-10-16*
|
||||
|
||||
#### 新特性
|
||||
- 综合
|
||||
- 新增全局配置组件尺寸的功能:在引入 Element 时,配置 `size` 字段可以改变所有组件的默认尺寸。当完整引入 Element 时:
|
||||
```JS
|
||||
import Vue from 'vue'
|
||||
import Element from 'element-ui'
|
||||
Vue.use(Element, { size: 'small' })
|
||||
```
|
||||
当按需引入 Element 时:
|
||||
```JS
|
||||
import Vue from 'vue'
|
||||
import { Button } from 'element-ui'
|
||||
Vue.prototype.$ELEMENT = { size: 'small' }
|
||||
Vue.use(Button)
|
||||
```
|
||||
按照以上设置,项目中所有拥有 `size` 属性的组件的默认尺寸均为 'small'。
|
||||
- Loading
|
||||
- 配置对象新增 `spinner` 和 `background` 字段,支持自定义加载图标和背景色,#7390
|
||||
- Autocomplete
|
||||
- 新增 `debounce` 属性,#7413
|
||||
- Upload
|
||||
- 新增 `limit` 和 `on-exceed` 属性,支持对上传文件的个数进行限制,#7405
|
||||
- Menu
|
||||
- 新增 `open` 和 `close` 方法,支持手动打开和关闭 SubMenu,#7412
|
||||
- DatePicker
|
||||
- 新增 `value-format` 属性,支持对绑定值的格式进行自定义,#7367
|
||||
- TimePicker
|
||||
- 新增 `arrow-control` 属性,提供另一种交互形式,#7438
|
||||
- DateTimePicker
|
||||
- 新增 `time-arrow-control` 属性,用于开启时间选择器的 `arrow-control`,#7438
|
||||
- Form
|
||||
- Form 和 Form-item 新增 `size` 属性,用于控制表单内组件的尺寸,#7428
|
||||
- `validate` 方法在不传入 callback 的情况下返回 promise,#7405
|
||||
|
||||
#### 修复
|
||||
- 修复部分组件的 `Injection "elFormItem" not found` 报错
|
||||
|
||||
#### 非兼容性更新
|
||||
- DatePicker 的 `change` 事件参数现在为组件的绑定值,格式由 `value-format` 控制
|
||||
- Input 组件的 `change` 事件现在仅在输入框失去焦点或用户按下回车时触发,与原生 input 元素一致。如果需要实时响应用户的输入,可以使用 `input` 事件
|
||||
- 最低兼容 Vue 2.5.2 版本
|
||||
|
||||
### 2.0.0-alpha.2
|
||||
*2017-10-05*
|
||||
|
||||
- 修正 `theme-chalk` 的主色,#7351
|
||||
- 修复使用 Dropdown 时控制台报错的问题,#7322
|
||||
- 修复使用 Menu 时控制台报错的问题,#7321
|
||||
- ColorPicker 新增 `popper-class` 属性,#7351
|
||||
- 修复 Button 的 `disabled` 属性无效的问题,#7352
|
||||
|
||||
### 2.0.0-alpha.1
|
||||
*2017-09-30*
|
||||
*2017-10-27*
|
||||
|
||||
#### 新特性
|
||||
- 综合
|
||||
- 新增 `theme-chalk` 主题
|
||||
- 增强以下组件的可访问性:Alert、AutoComplete、Breadcrumb、Button、Checkbox、Collapse、Input、InputNumber、Menu、Progress、Radio、Rate、Slider、Switch 和 Upload
|
||||
- 新增布局组件 Container、Header、Aside、Main 和 Footer
|
||||
- 新增 TypeScript 类型声明
|
||||
- 重绘了全部图标,并新增了部分图标
|
||||
- 新增了一系列基于断点的工具类,用于当视口尺寸满足一定条件时隐藏元素
|
||||
- 新增全局配置组件尺寸的功能。在引入 Element 时,配置 `size` 字段可以改变所有组件的默认尺寸
|
||||
- Button
|
||||
- 新增 `round` 属性,用于圆角按钮 #6643
|
||||
- TimeSelect
|
||||
@@ -142,6 +41,7 @@
|
||||
- TimePicker
|
||||
- 可以用方向键导航,用 `Enter` 选中时间 #6050
|
||||
- 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169
|
||||
- 新增 `arrow-control` 属性,提供另一种交互形式,#7438
|
||||
- Tree
|
||||
- 子节点在首次被展开之前不进行渲染 #6257
|
||||
- 新增 `check-descendants` 属性,设置 `lazy` 模式下勾选节点时,是否完全展开整个子树 #6235
|
||||
@@ -150,11 +50,14 @@
|
||||
- Datepicker
|
||||
- type 为 `datetimerange` 时可以使用 `timeFormat` 格式化时间选择器 #6052
|
||||
- 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169
|
||||
- 新增 `value-format` 属性,支持对绑定值的格式进行自定义,#7367
|
||||
- 新增 `unlink-panels` 属性,用于在选择日期范围时取消两个日期面板之间的联动
|
||||
- MessageBox
|
||||
- 新增 `closeOnHashChange` 属性 #6043
|
||||
- 新增 `center` 属性,提供居中布局 #7029
|
||||
- 新增 `roundButton` 属性,使得内部按钮为圆角按钮 #7029
|
||||
- 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 支持传入 HTML 字符串<sup>*</sup> #6043
|
||||
- 新增 `inputType` 属性,用户指定内部输入框的类型,#7651
|
||||
- Dialog
|
||||
- 新增 `width`、`fullscreen`、`append-to-body` 属性,支持嵌套使用
|
||||
- 新增 `center` 属性,提供居中布局 #7042
|
||||
@@ -163,6 +66,7 @@
|
||||
- 增加手动输入色值的支持 #6167
|
||||
- 新增 `size` 属性,用于控制组件的大小 #7026
|
||||
- 新增 `disabled` 属性,用于禁用组件 #7026
|
||||
- 新增 `popper-class` 属性,#7351
|
||||
- Message
|
||||
- 图标部分使用 icon 代替图片,从而支持通过 CSS 修改图标背景色 #6207
|
||||
- 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 属性支持传入 HTML 字符串<sup>*</sup> #6207
|
||||
@@ -183,9 +87,13 @@
|
||||
- 新增 `center` 属性,提供居中布局 #6876
|
||||
- Menu
|
||||
- 新增 `background-color`、`text-color` 和 `active-text-color` 属性,分别用于设置菜单的背景色、菜单的文字颜色和当前激活菜单的文字颜色 #7064
|
||||
- 新增 `open` 和 `close` 方法,支持手动打开和关闭 SubMenu,#7412
|
||||
- Form
|
||||
- 新增 `inline-message` 属性,设置后校验信息会以行内样式显示 #7032
|
||||
- 新增 `status-icon` 属性,用于在输入框中显示校验结果反馈图标 #7032
|
||||
- Form 和 FormItem 新增 `size` 属性,用于控制表单内组件的尺寸,#7428
|
||||
- `validate` 方法在不传入 callback 的情况下返回 promise,#7405
|
||||
- 新增 `clearValidate` 方法,用于清空所有表单项的验证信息,#7623
|
||||
- Input
|
||||
- 新增 `suffix`、`prefix` 的 slot,以及 `suffixIcon`、`prefixIcon` 属性,用于给输入框内部增加前置和后置内容 #7032
|
||||
- Breadcrumb
|
||||
@@ -194,6 +102,33 @@
|
||||
- 新增 `simple` 属性,用于开启简洁风格的步骤条 #7274
|
||||
- Pagination
|
||||
- 新增 `prev-text` 和 `next-text` 属性,用于自定义上一页和下一页的文本 #7005
|
||||
- Loading
|
||||
- 配置对象新增 `spinner` 和 `background` 字段,支持自定义加载图标和背景色,#7390
|
||||
- Autocomplete
|
||||
- 新增 `debounce` 属性,#7413
|
||||
- Upload
|
||||
- 新增 `limit` 和 `on-exceed` 属性,支持对上传文件的个数进行限制,#7405
|
||||
- DateTimePicker
|
||||
- 新增 `time-arrow-control` 属性,用于开启时间选择器的 `arrow-control`,#7438
|
||||
- Layout
|
||||
- 新增断点 `xl`,适用于宽度大于 1920px 的视口
|
||||
- Table
|
||||
- 新增 `span-method` 属性,用于合并行或列
|
||||
- 新增 `clearSort` 方法,用于清空排序状态
|
||||
- 新增 `clearFilter` 方法,用于清空过滤状态
|
||||
- 对于可展开行,当该行展开时会获得一个 `.expanded` 类名,方便自定义样式
|
||||
- 新增 `size` 属性,用于控制表格尺寸
|
||||
- 新增 `toggleRowExpansion` 方法,用于手动展开或关闭行
|
||||
- 新增 `cell-class-name` 属性,用于指定单元格的类名
|
||||
- 新增 `cell-style` 属性,用于指定单元格的样式
|
||||
- 新增 `header-row-class-name` 属性,用于指定表头行的类名
|
||||
- 新增 `header-row-style` 属性,用于指定表头行的样式
|
||||
- 新增 `header-cell-class-name` 属性,用于指定表头单元格的类名
|
||||
- 新增 `header-cell-style` 属性,用于指定表头单元格的样式
|
||||
- TableColumn 的 `prop` 属性支持 `object[key]` 格式
|
||||
- TableColumn 新增 `index` 属性,用于自定义索引值
|
||||
- Select
|
||||
- 新增 `reserve-keyword` 属性,用于在选择某个选项后保留当前的搜索关键词
|
||||
|
||||
#### 修复
|
||||
- DatePicker
|
||||
@@ -208,12 +143,22 @@
|
||||
- 当含有下拉框时,下拉框的打开和关闭会造成文字虚晃的问题 #6088
|
||||
- Select
|
||||
- 提升性能,修复组件销毁时可能导致 Vue dev-tool 卡死的问题 #6151
|
||||
- Table
|
||||
- 修复 Table 在父元素从 `display: none` 变成其他状态时会隐藏的问题
|
||||
- 修复 Table 在父元素为 `display: flex` 时可能出现的宽度逐渐变大的问题
|
||||
- 修复 `append` 具名 slot 和固定列并存时,动态获取表格数据会导致固定列消失的问题
|
||||
- 修复 `expand-row-keys` 属性初始化无效的问题
|
||||
- 修复 `data` 改变时过滤条件失效的问题
|
||||
- 修复多级表头时固定列隐藏情况计算错误的问题
|
||||
- 修复 `max-height` 变更后无法恢复的问题
|
||||
- 修复一些样式上的计算错误
|
||||
|
||||
#### 非兼容性更新
|
||||
- 综合
|
||||
- 移除 `theme-default`
|
||||
- 最低兼容 Vue 2.5.2 和 IE 10
|
||||
- 表单组件的 `change` 事件和 Pagination 的 `current-change` 事件现在仅响应用户交互
|
||||
- Button 和表单组件的 `size` 属性不再接受 `large` 值,可接受 `medium`、`small` 和 `mini`
|
||||
- Button 和表单组件的 `size` 属性现在可接受 `medium`、`small` 和 `mini`
|
||||
- 为了方便使用第三方图标,Button 的 `icon` 属性、Input 的 `prefix-icon` 和 `suffix-icon` 属性、Steps 的 `icon` 属性现在需要传入完整的图标类名
|
||||
- Dialog
|
||||
- 移除 `size` 属性。现在 Dialog 的尺寸由 `width` 和 `fullscreen` 控制
|
||||
@@ -225,23 +170,30 @@
|
||||
- Transfer
|
||||
- `footer-format` 属性更名为 `format`
|
||||
- Switch
|
||||
- `on-text` 和 `off-text` 属性不再有默认值
|
||||
- 由于 `on-*` 属性在 JSX 中会被识别为事件,导致 Switch 所有 `on-*` 属性在 JSX 中无法正常工作,所以 `on-*` 属性更名为 `active-*`,对应地,`off-*` 属性更名为 `inactive-*`。受到影响的属性有:`on-icon-class`、`off-icon-class`、`on-text`、`off-text`、`on-color`、`off-color`、`on-value`、`off-value`
|
||||
- `active-text` 和 `inactive-text` 属性不再有默认值
|
||||
- Tag
|
||||
- `type` 属性现在支持 `success`、`info`、`warning` 和 `danger` 四个值
|
||||
- `close-transition` 属性更名为 `disable-transitions`
|
||||
- Menu
|
||||
- 移除 `theme` 属性。现在通过 `background-color`、`text-color` 和 `active-text-color` 属性进行颜色的自定义
|
||||
- Input
|
||||
- 移除 `icon` 属性。现在通过 `suffix-icon` 属性或者 `suffix` 具名 slot 来加入尾部图标
|
||||
- 移除 `on-icon-click` 属性和 `click` 事件。现在如果需要为输入框中的图标添加点击事件,请以具名 slot 的方式添加图标
|
||||
- `change` 事件现在仅在输入框失去焦点或用户按下回车时触发,与原生 input 元素一致。如果需要实时响应用户的输入,可以使用 `input` 事件
|
||||
- Autocomplete
|
||||
- 移除 `icon` 和 `on-icon-click` 属性。现在通过 `prefix` 和 `suffix` 具名 slot 来加入图标
|
||||
- 移除 `custom-item` 属性。现在通过 `scoped slot` 自定义输入建议列表项的内容
|
||||
- Table
|
||||
- 移除通过 `inline-template` 自定义列模板的功能
|
||||
- 移除 `props` 属性,现在使用 `value-key` 属性指定输入建议对象中用于显示的键名
|
||||
- Steps
|
||||
- 移除 `center` 属性
|
||||
- 现在步骤条将默认充满父容器
|
||||
- DatePicker
|
||||
- `change` 事件参数现在为组件的绑定值,格式由 `value-format` 控制
|
||||
- Table
|
||||
- 移除通过 `inline-template` 自定义列模板的功能
|
||||
- `sort-method` 现在和 `Array.sort` 保持一致的逻辑,要求返回一个数字
|
||||
- 将 `append` slot 移至 `tbody` 元素以外,以保证其只被渲染一次
|
||||
- `expand` 事件更名为 `expand-change`,以保证 API 的命名一致性
|
||||
- `row-class-name` 和 `row-style` 的函数参数改为对象,以保证 API 的一致性
|
||||
|
||||
##
|
||||
<i><sup>*</sup> 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。因此请在 `dangerouslyUseHTMLString` 打开的情况下,确保 `message` 的内容是可信的,**永远不要**将用户提交的内容赋值给 `message` 属性。</i>
|
||||
@@ -67,7 +67,7 @@ Vue.component(Button.name, Button)
|
||||
For more information, please refer to [Quick Start](http://element.eleme.io/#/en-US/component/quickstart) in our documentation.
|
||||
|
||||
## Browser Support
|
||||
Modern browsers and Internet Explorer 9+.
|
||||
Modern browsers and Internet Explorer 10+.
|
||||
|
||||
## Development
|
||||
Skip this part if you just want to use Element.
|
||||
|
||||
@@ -42,11 +42,10 @@ if [ "$TRAVIS_TAG" ]; then
|
||||
|
||||
SUB_FOLDER='2.0'
|
||||
mkdir $SUB_FOLDER
|
||||
# rm -rf *.js *.css *.map static
|
||||
rm -rf *.js *.css *.map static
|
||||
rm -rf $SUB_FOLDER/**
|
||||
# cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** $SUB_FOLDER/
|
||||
cp -rf ../../examples/element-ui/versions.json .
|
||||
git add -A .
|
||||
git commit -m "$TRAVIS_COMMIT_MSG"
|
||||
git push origin gh-pages
|
||||
|
||||
@@ -7,12 +7,12 @@ git clone -b gh-pages https://github.com/ElemeFE/element.git && cd element
|
||||
# build sub folder
|
||||
SUB_FOLDER='2.0'
|
||||
mkdir $SUB_FOLDER
|
||||
# rm -rf *.js *.css *.map static
|
||||
rm -rf *.js *.css *.map static
|
||||
rm -rf $SUB_FOLDER/**
|
||||
# cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** $SUB_FOLDER/
|
||||
cp -rf ../../examples/element-ui/versions.json .
|
||||
cd ../..
|
||||
|
||||
# deploy domestic site
|
||||
faas deploy alpha
|
||||
faas deploy alpha
|
||||
rm -rf temp_web
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
git checkout carbon
|
||||
git checkout dev
|
||||
|
||||
if test -n "$(git status --porcelain)"; then
|
||||
echo 'Unclean working tree. Commit or stash changes first.' >&2;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
git checkout master
|
||||
git merge dev
|
||||
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
echo "Enter release version: "
|
||||
@@ -16,7 +19,12 @@ then
|
||||
echo "Releasing theme-chalk $VERSION ..."
|
||||
cd packages/theme-chalk
|
||||
npm version $VERSION --message "[release] $VERSION"
|
||||
npm publish
|
||||
if [[ $VERSION =~ "beta" ]]
|
||||
then
|
||||
npm publish --tag beta
|
||||
else
|
||||
npm publish
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
# commit
|
||||
@@ -25,8 +33,16 @@ then
|
||||
npm version $VERSION --message "[release] $VERSION"
|
||||
|
||||
# publish
|
||||
git push eleme carbon
|
||||
git push eleme master
|
||||
git push eleme refs/tags/v$VERSION
|
||||
git checkout dev
|
||||
git rebase master
|
||||
git push eleme dev
|
||||
|
||||
npm publish --tag next
|
||||
if [[ $VERSION =~ "beta" ]]
|
||||
then
|
||||
npm publish --tag beta
|
||||
else
|
||||
npm publish
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -202,7 +202,10 @@
|
||||
},
|
||||
|
||||
watch: {
|
||||
lang() {
|
||||
lang(val) {
|
||||
if (val === 'zh-CN') {
|
||||
this.suggestJump();
|
||||
}
|
||||
this.localize();
|
||||
}
|
||||
},
|
||||
@@ -210,11 +213,57 @@
|
||||
methods: {
|
||||
localize() {
|
||||
use(this.lang === 'zh-CN' ? zhLocale : enLocale);
|
||||
},
|
||||
suggestJump() {
|
||||
const href = location.href;
|
||||
const preferGithub = localStorage.getItem('PREFER_GITHUB');
|
||||
if (href.indexOf('element-cn') > -1 || preferGithub) return;
|
||||
setTimeout(() => {
|
||||
this.$confirm('建议大陆用户访问部署在国内的站点,是否跳转?', '提示')
|
||||
.then(() => {
|
||||
location.href = location.href.replace('element.', 'element-cn.');
|
||||
})
|
||||
.catch(() => {
|
||||
localStorage.setItem('PREFER_GITHUB', true);
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.localize();
|
||||
if (this.lang === 'zh-CN') {
|
||||
this.suggestJump();
|
||||
}
|
||||
setTimeout(() => {
|
||||
const notified = localStorage.getItem('RELEASE_NOTIFIED');
|
||||
if (!notified) {
|
||||
const h = this.$createElement;
|
||||
const title = this.lang === 'zh-CN'
|
||||
? '2.0 正式发布'
|
||||
: '2.0 available now';
|
||||
const messages = this.lang === 'zh-CN'
|
||||
? ['点击', '这里', '查看详情']
|
||||
: ['Click ', 'here', ' to learn more'];
|
||||
this.$notify({
|
||||
title,
|
||||
duration: 0,
|
||||
message: h('span', [
|
||||
messages[0],
|
||||
h('a', {
|
||||
attrs: {
|
||||
target: '_blank',
|
||||
href: `https://github.com/ElemeFE/element/issues/${ this.lang === 'zh-CN' ? '7755' : '7756' }`
|
||||
}
|
||||
}, messages[1]),
|
||||
messages[2]
|
||||
]),
|
||||
onClose() {
|
||||
localStorage.setItem('RELEASE_NOTIFIED', 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 3500);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
|
||||
<script type="text/babel">
|
||||
import compoLang from '../i18n/component.json';
|
||||
import { version } from 'main/index.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -200,10 +201,10 @@
|
||||
goJsfiddle() {
|
||||
const { script, html, style } = this.jsfiddle;
|
||||
const resourcesTpl = '<scr' + 'ipt src="//unpkg.com/vue/dist/vue.js"></scr' + 'ipt>' +
|
||||
'\n<scr' + 'ipt src="//unpkg.com/element-ui@next/lib/index.js"></scr' + 'ipt>';
|
||||
'\n<scr' + `ipt src="//unpkg.com/element-ui@${ version }/lib/index.js"></scr` + 'ipt>';
|
||||
let jsTpl = (script || '').replace(/export default/, 'var Main =').trim();
|
||||
let htmlTpl = `${resourcesTpl}\n<div id="app">\n${html.trim()}\n</div>`;
|
||||
let cssTpl = `@import url("//unpkg.com/element-ui@next/lib/theme-chalk/index.css");\n${(style || '').trim()}\n`;
|
||||
let cssTpl = `@import url("//unpkg.com/element-ui@${ version }/lib/theme-chalk/index.css");\n${(style || '').trim()}\n`;
|
||||
jsTpl = jsTpl
|
||||
? jsTpl + '\nvar Ctor = Vue.extend(Main)\nnew Ctor().$mount(\'#app\')'
|
||||
: 'new Vue().$mount(\'#app\')';
|
||||
|
||||
@@ -390,7 +390,11 @@
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = _ => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
this.versions = JSON.parse(xhr.responseText);
|
||||
const versions = JSON.parse(xhr.responseText);
|
||||
this.versions = Object.keys(versions).slice(-2).reduce((prev, next) => {
|
||||
prev[next] = versions[next];
|
||||
return prev;
|
||||
}, {});
|
||||
}
|
||||
};
|
||||
xhr.open('GET', '/versions.json');
|
||||
|
||||
@@ -128,10 +128,27 @@
|
||||
}
|
||||
};
|
||||
|
||||
const shadeColor = (color, shade) => {
|
||||
let red = parseInt(color.slice(0, 2), 16);
|
||||
let green = parseInt(color.slice(2, 4), 16);
|
||||
let blue = parseInt(color.slice(4, 6), 16);
|
||||
|
||||
red = Math.round((1 - shade) * red);
|
||||
green = Math.round((1 - shade) * green);
|
||||
blue = Math.round((1 - shade) * blue);
|
||||
|
||||
red = red.toString(16);
|
||||
green = green.toString(16);
|
||||
blue = blue.toString(16);
|
||||
|
||||
return `#${ red }${ green }${ blue }`;
|
||||
};
|
||||
|
||||
const clusters = [theme];
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))));
|
||||
}
|
||||
clusters.push(shadeColor(theme, 0.1));
|
||||
return clusters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
if (!value) {
|
||||
return callback(new Error('Please input the age'));
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('Please input digits'));
|
||||
} else {
|
||||
if (value < 18) {
|
||||
callback(new Error('Age must be greater than 18'));
|
||||
setTimeout(() => {
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('Please input digits'));
|
||||
} else {
|
||||
callback();
|
||||
if (value < 18) {
|
||||
callback(new Error('Age must be greater than 18'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
@@ -338,7 +340,8 @@ When the vertical space is limited and the form is relatively simple, you can pu
|
||||
<el-option label="Zone one" value="shanghai"></el-option>
|
||||
<el-option label="Zone two" value="beijing"></el-option>
|
||||
</el-select>
|
||||
</el-form-item><el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Query</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -546,15 +549,17 @@ This example shows how to customize your own validation rules to finish a two-fa
|
||||
if (!value) {
|
||||
return callback(new Error('Please input the age'));
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('Please input digits'));
|
||||
} else {
|
||||
if (value < 18) {
|
||||
callback(new Error('Age must be greater than 18'));
|
||||
setTimeout(() => {
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('Please input digits'));
|
||||
} else {
|
||||
callback();
|
||||
if (value < 18) {
|
||||
callback(new Error('Age must be greater than 18'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
|
||||
@@ -4,21 +4,21 @@
|
||||
Installing with npm is recommended and it works seamlessly with [webpack](https://webpack.js.org/).
|
||||
|
||||
```shell
|
||||
npm i element-ui@next -S
|
||||
npm i element-ui -S
|
||||
```
|
||||
|
||||
### CDN
|
||||
Get the latest version from [unpkg.com/element-ui](https://unpkg.com/element-ui@next/) , and import JavaScript and CSS file in your page.
|
||||
Get the latest version from [unpkg.com/element-ui](https://unpkg.com/element-ui/) , and import JavaScript and CSS file in your page.
|
||||
|
||||
```html
|
||||
<!-- import CSS -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui@next/lib/theme-chalk/index.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||
<!-- import JavaScript -->
|
||||
<script src="https://unpkg.com/element-ui@next/lib/index.js"></script>
|
||||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||
```
|
||||
|
||||
### Hello world
|
||||
If you are using CDN, a hello-world page is easy with Element. [Online Demo](https://jsfiddle.net/leopoldthecuber/hzfpyvg6/1/)
|
||||
If you are using CDN, a hello-world page is easy with Element. [Online Demo](https://jsfiddle.net/hzfpyvg6/14/)
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
@@ -26,7 +26,7 @@ If you are using CDN, a hello-world page is easy with Element. [Online Demo](htt
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- import CSS -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui@next/lib/theme-chalk/index.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
@@ -39,7 +39,7 @@ If you are using CDN, a hello-world page is easy with Element. [Online Demo](htt
|
||||
<!-- import Vue before Element -->
|
||||
<script src="https://unpkg.com/vue/dist/vue.js"></script>
|
||||
<!-- import JavaScript -->
|
||||
<script src="https://unpkg.com/element-ui@next/lib/index.js"></script>
|
||||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
|
||||
@@ -4,125 +4,19 @@ This part walks you through the process of using Element in a webpack project.
|
||||
|
||||
### Use Starter Kit
|
||||
|
||||
Under construction.
|
||||
We provide a general [project template](https://github.com/ElementUI/element-starter) for you. For Laravel users, we also have a [template](https://github.com/ElementUI/element-in-laravel-starter). You can download and use them directly.
|
||||
|
||||
### Config files
|
||||
If you prefer not to use them, please read the following.
|
||||
|
||||
Create a new project, and its structure should be
|
||||
```text
|
||||
|- src/ --------------------- source code
|
||||
|- App.vue
|
||||
|- main.js -------------- entry
|
||||
|- .babelrc ----------------- babel config
|
||||
|- index.html --------------- HTML template
|
||||
|- package.json ------------- npm config
|
||||
|- README.md ---------------- readme
|
||||
|- webpack.config.js -------- webpack config
|
||||
```
|
||||
### Use vue-cli
|
||||
|
||||
Typical configurations for these config files are:
|
||||
We can also start a project using [vue-cli](https://github.com/vuejs/vue-cli):
|
||||
|
||||
**.babelrc**
|
||||
```json
|
||||
{
|
||||
"presets": ["vue-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
**package.json**
|
||||
```json
|
||||
{
|
||||
"name": "element-starter",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --port 8086",
|
||||
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"element-ui": "next",
|
||||
"vue": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "^6.0.0",
|
||||
"babel-preset-vue-app": "^1.2.0",
|
||||
"cross-env": "^1.0.6",
|
||||
"css-loader": "^0.23.1",
|
||||
"file-loader": "^0.8.5",
|
||||
"style-loader": "^0.13.1",
|
||||
"vue-loader": "^9.8.0",
|
||||
"webpack": "beta",
|
||||
"webpack-dev-server": "beta"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
**webpack.config.js**
|
||||
```javascript
|
||||
var path = require('path')
|
||||
var webpack = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/main.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, './dist'),
|
||||
publicPath: '/dist/',
|
||||
filename: 'build.js'
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'style-loader!css-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
|
||||
loader: 'file-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/,
|
||||
loader: 'file-loader',
|
||||
query: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
noInfo: true
|
||||
},
|
||||
devtool: '#eval-source-map'
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports.devtool = '#source-map'
|
||||
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
])
|
||||
}
|
||||
```shell
|
||||
> npm i -g vue-cli
|
||||
> mkdir my-project && cd my-project
|
||||
> vue init webpack
|
||||
> npm i && npm i element-ui
|
||||
```
|
||||
|
||||
### Import Element
|
||||
|
||||
@@ -1263,7 +1263,7 @@ You can also select multiple rows.
|
||||
|
||||
Sort the data to find or compare data quickly.
|
||||
|
||||
:::demo Set attribute `sortable` in a certain column to sort the data based on this column. It accepts `Boolean` with a default value `false`. Set table attribute `default-sort` to determine default sort column and order. To apply your own sorting rules, use `sort-method`. If you need remote sorting from backend, set `sortable` to `custom`, and listen to the `sort-change` event on Table. In the event handler, you have access to the sorting column and sorting order so that you can fetch sorted table data from API. In this example we use another attribute named `formatter` to format the value of certain columns. It accepts a function which has two parameters: `row` and `column`. You can handle it according to your own needs.
|
||||
:::demo Set attribute `sortable` in a certain column to sort the data based on this column. It accepts `Boolean` with a default value `false`. Set table attribute `default-sort` to determine default sort column and order. To apply your own sorting rules, use `sort-method` or `sort-by`. If you need remote sorting from backend, set `sortable` to `custom`, and listen to the `sort-change` event on Table. In the event handler, you have access to the sorting column and sorting order so that you can fetch sorted table data from API. In this example we use another attribute named `formatter` to format the value of certain columns. It accepts a function which has two parameters: `row` and `column`. You can handle it according to your own needs.
|
||||
```html
|
||||
<template>
|
||||
<el-table
|
||||
@@ -2010,6 +2010,7 @@ You can customize row index in `type=index` columns.
|
||||
| render-header | render function for table header of this column | Function(h, { column, $index }) | — | — |
|
||||
| sortable | whether column can be sorted. Remote sorting can be done by setting this attribute to 'custom' and listening to the `sort-change` event of Table | boolean, string | true, false, custom | false |
|
||||
| sort-method | sorting method, works when `sortable` is `true`. Should return a number, just like Array.sort | Function(a, b) | — | — |
|
||||
| sort-by | specify which property to sort by, works when `sortable` is `true` and `sort-method` is `undefined`. If set to an Array, the column will sequentially sort by the next property if the previous one is equal | Function(row, index)/String/Array | — | — |
|
||||
| resizable | whether column width can be resized, works when `border` of `el-table` is `true` | boolean | — | false |
|
||||
| formatter | function that formats cell content | Function(row, column, cellValue) | — | — |
|
||||
| show-overflow-tooltip | whether to hide extra content and show them in a tooltip when hovering on the cell | boolean | — | false |
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
if (!value) {
|
||||
return callback(new Error('年龄不能为空'));
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('请输入数字值'));
|
||||
} else {
|
||||
if (value < 18) {
|
||||
callback(new Error('必须年满18岁'));
|
||||
setTimeout(() => {
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('请输入数字值'));
|
||||
} else {
|
||||
callback();
|
||||
if (value < 18) {
|
||||
callback(new Error('必须年满18岁'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
@@ -331,7 +333,8 @@
|
||||
<el-option label="区域一" value="shanghai"></el-option>
|
||||
<el-option label="区域二" value="beijing"></el-option>
|
||||
</el-select>
|
||||
</el-form-item><el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -537,15 +540,17 @@
|
||||
if (!value) {
|
||||
return callback(new Error('年龄不能为空'));
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('请输入数字值'));
|
||||
} else {
|
||||
if (value < 18) {
|
||||
callback(new Error('必须年满18岁'));
|
||||
setTimeout(() => {
|
||||
if (!Number.isInteger(value)) {
|
||||
callback(new Error('请输入数字值'));
|
||||
} else {
|
||||
callback();
|
||||
if (value < 18) {
|
||||
callback(new Error('必须年满18岁'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
|
||||
@@ -4,21 +4,21 @@
|
||||
推荐使用 npm 的方式安装,它能更好地和 [webpack](https://webpack.js.org/) 打包工具配合使用。
|
||||
|
||||
```shell
|
||||
npm i element-ui@next -S
|
||||
npm i element-ui -S
|
||||
```
|
||||
|
||||
### CDN
|
||||
目前可以通过 [unpkg.com/element-ui](https://unpkg.com/element-ui@next/) 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。
|
||||
目前可以通过 [unpkg.com/element-ui](https://unpkg.com/element-ui/) 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。
|
||||
|
||||
```html
|
||||
<!-- 引入样式 -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui@next/lib/theme-chalk/index.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||
<!-- 引入组件库 -->
|
||||
<script src="https://unpkg.com/element-ui@next/lib/index.js"></script>
|
||||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||
```
|
||||
|
||||
### Hello world
|
||||
通过 CDN 的方式我们可以很容易地使用 Element 写出一个 Hello world 页面。[在线演示](https://jsfiddle.net/leopoldthecuber/hzfpyvg6/1/)
|
||||
通过 CDN 的方式我们可以很容易地使用 Element 写出一个 Hello world 页面。[在线演示](https://jsfiddle.net/hzfpyvg6/14/)
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
@@ -26,7 +26,7 @@ npm i element-ui@next -S
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- 引入样式 -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui@next/lib/theme-chalk/index.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
@@ -39,7 +39,7 @@ npm i element-ui@next -S
|
||||
<!-- 先引入 Vue -->
|
||||
<script src="https://unpkg.com/vue/dist/vue.js"></script>
|
||||
<!-- 引入组件库 -->
|
||||
<script src="https://unpkg.com/element-ui@next/lib/index.js"></script>
|
||||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
|
||||
@@ -4,125 +4,19 @@
|
||||
|
||||
### 使用 Starter Kit
|
||||
|
||||
整理中。
|
||||
我们提供了通用的[项目模板](https://github.com/ElementUI/element-starter),你可以直接使用。对于 Laravel 用户,我们也准备了相应的[模板](https://github.com/ElementUI/element-in-laravel-starter),同样可以直接下载使用。
|
||||
|
||||
### 配置文件
|
||||
如果不希望使用我们提供的模板,请继续阅读。
|
||||
|
||||
新建项目,项目结构为
|
||||
```text
|
||||
|- src/ --------------------- 项目源代码
|
||||
|- App.vue
|
||||
|- main.js -------------- 入口文件
|
||||
|- .babelrc ----------------- babel 配置文件
|
||||
|- index.html --------------- HTML 模板
|
||||
|- package.json ------------- npm 配置文件
|
||||
|- README.md ---------------- 项目帮助文档
|
||||
|- webpack.config.js -------- webpack 配置文件
|
||||
```
|
||||
### 使用 vue-cli
|
||||
|
||||
几个配置文件的典型配置如下:
|
||||
我们还可以使用 [vue-cli](https://github.com/vuejs/vue-cli) 初始化项目,命令如下:
|
||||
|
||||
**.babelrc**
|
||||
```json
|
||||
{
|
||||
"presets": ["vue-app"]
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
**package.json**
|
||||
```json
|
||||
{
|
||||
"name": "element-starter",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --inline --hot --port 8086",
|
||||
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"element-ui": "next",
|
||||
"vue": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "^6.0.0",
|
||||
"babel-preset-vue-app": "^1.2.0",
|
||||
"cross-env": "^1.0.6",
|
||||
"css-loader": "^0.23.1",
|
||||
"file-loader": "^0.8.5",
|
||||
"style-loader": "^0.13.1",
|
||||
"vue-loader": "^9.8.0",
|
||||
"webpack": "beta",
|
||||
"webpack-dev-server": "beta"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
**webpack.config.js**
|
||||
```javascript
|
||||
var path = require('path')
|
||||
var webpack = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/main.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, './dist'),
|
||||
publicPath: '/dist/',
|
||||
filename: 'build.js'
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: 'style-loader!css-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
|
||||
loader: 'file-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/,
|
||||
loader: 'file-loader',
|
||||
query: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
noInfo: true
|
||||
},
|
||||
devtool: '#eval-source-map'
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports.devtool = '#source-map'
|
||||
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
])
|
||||
}
|
||||
```shell
|
||||
> npm i -g vue-cli
|
||||
> mkdir my-project && cd my-project
|
||||
> vue init webpack
|
||||
> npm i && npm i element-ui
|
||||
```
|
||||
|
||||
### 引入 Element
|
||||
|
||||
@@ -298,10 +298,10 @@
|
||||
return row.tag === value;
|
||||
},
|
||||
|
||||
tableRowClassName({row, rowndex}) {
|
||||
if (rowndex === 1) {
|
||||
tableRowClassName({row, rowIndex}) {
|
||||
if (rowIndex === 1) {
|
||||
return 'warning-row';
|
||||
} else if (rowndex === 3) {
|
||||
} else if (rowIndex === 3) {
|
||||
return 'success-row';
|
||||
}
|
||||
return '';
|
||||
@@ -1303,7 +1303,7 @@
|
||||
|
||||
对表格进行排序,可快速查找或对比数据。
|
||||
|
||||
:::demo 在列中设置`sortable`属性即可实现以该列为基准的排序,接受一个`Boolean`,默认为`false`。可以通过 Table 的`default-sort`属性设置默认的排序列和排序顺序。可以使用`sort-method`使用自定义的排序规则。如果需要后端排序,需将`sortable`设置为`custom`,同时在 Table 上监听`sort-change`事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。在本例中,我们还使用了`formatter`属性,它用于格式化指定列的值,接受一个`Function`,会传入两个参数:`row`和`column`,可以根据自己的需求进行处理。
|
||||
:::demo 在列中设置`sortable`属性即可实现以该列为基准的排序,接受一个`Boolean`,默认为`false`。可以通过 Table 的`default-sort`属性设置默认的排序列和排序顺序。可以使用`sort-method`或者`sort-by`使用自定义的排序规则。如果需要后端排序,需将`sortable`设置为`custom`,同时在 Table 上监听`sort-change`事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。在本例中,我们还使用了`formatter`属性,它用于格式化指定列的值,接受一个`Function`,会传入两个参数:`row`和`column`,可以根据自己的需求进行处理。
|
||||
```html
|
||||
<template>
|
||||
<el-table
|
||||
@@ -2073,6 +2073,7 @@
|
||||
| render-header | 列标题 Label 区域渲染使用的 Function | Function(h, { column, $index }) | — | — |
|
||||
| sortable | 对应列是否可以排序,如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, 'custom' | false |
|
||||
| sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效,需返回一个数字,和 Array.sort 表现一致 | Function(a, b) | — | — |
|
||||
| sort-by | 指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推。 | String/Array/Function(row, index) | — | — |
|
||||
| resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |
|
||||
| formatter | 用来格式化内容 | Function(row, column, cellValue) | — | — |
|
||||
| show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | Boolean | — | false |
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"index": {
|
||||
"lang": "zh-CN",
|
||||
"titleSize": "34",
|
||||
"paraSize": "20",
|
||||
"paraSize": "18",
|
||||
"1": "网站快速成型工具",
|
||||
"2": "Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库",
|
||||
"3": "指南",
|
||||
@@ -97,7 +97,7 @@
|
||||
"index": {
|
||||
"lang": "en-US",
|
||||
"titleSize": "34",
|
||||
"paraSize": "20",
|
||||
"paraSize": "18",
|
||||
"theatreParam": "{ maxSpeed: 100 }",
|
||||
"typingFunc": ".addScene('product designers', 1800, -17, 800)\n .addScene('UI designers', 1800, -12, 800)\n .addScene('UX designers', 1800, -12, 800)\n .addScene('product managers', 1800, -16, 800)\n .addScene('FE developers', 1800, -13, 800)",
|
||||
"typingInvoke": ".addActor('line2', { speed: 1, accuracy: 1 })\n .addScene(2600)\n .addScene('line2:For ', 500)",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
font-size: <%= paraSize >px;
|
||||
line-height: 28px;
|
||||
color: #888;
|
||||
margin: 15px 0 0;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
}
|
||||
.jumbotron {
|
||||
@@ -245,6 +245,9 @@
|
||||
<div>
|
||||
<img class="jumbotron-plant-2" src="~examples/assets/images/plant-2.png" alt="">
|
||||
<img class="jumbotron-web" src="~examples/assets/images/web.png" alt="">
|
||||
<img class="jumbotron-plant-1" src="~examples/assets/images/plant-1.png" alt="">
|
||||
<img class="jumbotron-figure-1" src="~examples/assets/images/figure-1.png" alt="">
|
||||
<img class="jumbotron-figure-2" src="~examples/assets/images/figure-2.png" alt="">
|
||||
</div>
|
||||
<div data-hover-layer="0">
|
||||
<img class="jumbotron-cloud-1" src="~examples/assets/images/cloud-1.png" alt="">
|
||||
@@ -255,11 +258,6 @@
|
||||
<img class="jumbotron-compo-2" src="~examples/assets/images/compo-2.png" alt="">
|
||||
<img class="jumbotron-compo-3" src="~examples/assets/images/compo-3.png" alt="">
|
||||
</div>
|
||||
<div data-hover-layer="2">
|
||||
<img class="jumbotron-plant-1" src="~examples/assets/images/plant-1.png" alt="">
|
||||
<img class="jumbotron-figure-1" src="~examples/assets/images/figure-1.png" alt="">
|
||||
<img class="jumbotron-figure-2" src="~examples/assets/images/figure-2.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="cards">
|
||||
<ul class="container">
|
||||
@@ -309,17 +307,14 @@
|
||||
export default {
|
||||
mounted() {
|
||||
new Hover('.jumbotron', { // eslint-disable-line
|
||||
max: 1,
|
||||
max: 3,
|
||||
scale: 1,
|
||||
perspective: 700,
|
||||
layers: [{
|
||||
multiple: 0.01,
|
||||
reverseTranslate: true
|
||||
}, {
|
||||
multiple: 0.04,
|
||||
reverseTranslate: true
|
||||
}, {
|
||||
multiple: 0.015,
|
||||
multiple: 0.02,
|
||||
reverseTranslate: true
|
||||
}]
|
||||
});
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.8":"1.4","2.0.0-rc.1":"2.0"}
|
||||
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.8":"1.4","2.0.2":"2.0"}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "element-ui",
|
||||
"version": "2.0.0-rc.1",
|
||||
"version": "2.0.2",
|
||||
"description": "A Component Library for Vue.js.",
|
||||
"main": "lib/element-ui.common.js",
|
||||
"files": [
|
||||
@@ -57,7 +57,7 @@
|
||||
"throttle-debounce": "^1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.3.0"
|
||||
"vue": "^2.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"algoliasearch": "^3.24.5",
|
||||
|
||||
@@ -165,9 +165,15 @@
|
||||
}
|
||||
},
|
||||
handleChange(ev) {
|
||||
if (this.isLimitExceeded) return;
|
||||
let value;
|
||||
if (ev.target.checked) {
|
||||
value = this.trueLabel === undefined ? true : this.trueLabel;
|
||||
} else {
|
||||
value = this.falseLabel === undefined ? false : this.falseLabel;
|
||||
}
|
||||
this.$emit('change', value, ev);
|
||||
this.$nextTick(() => {
|
||||
if (this.isLimitExceeded) return;
|
||||
this.$emit('change', this.model, ev);
|
||||
if (this._checkboxGroup) {
|
||||
this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="el-checkbox-group" role="group" aria-label="checkbox-group">
|
||||
<div class="el-checkbox-group" role="group" aria-label="checkbox-group">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -176,9 +176,15 @@
|
||||
}
|
||||
},
|
||||
handleChange(ev) {
|
||||
if (this.isLimitExceeded) return;
|
||||
let value;
|
||||
if (ev.target.checked) {
|
||||
value = this.trueLabel === undefined ? true : this.trueLabel;
|
||||
} else {
|
||||
value = this.falseLabel === undefined ? false : this.falseLabel;
|
||||
}
|
||||
this.$emit('change', value, ev);
|
||||
this.$nextTick(() => {
|
||||
if (this.isLimitExceeded) return;
|
||||
this.$emit('change', this.model, ev);
|
||||
if (this.isGroup) {
|
||||
this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
tabindex="0"
|
||||
@keyup.space.enter.stop="handleEnterClick"
|
||||
:class="{'focusing': focusing}"
|
||||
@focus="focusing = true"
|
||||
@focus="handleFocus"
|
||||
@blur="focusing = false"
|
||||
>
|
||||
<i class="el-collapse-item__arrow el-icon-arrow-right"></i>
|
||||
@@ -58,7 +58,8 @@
|
||||
display: 'block'
|
||||
},
|
||||
contentHeight: 0,
|
||||
focusing: false
|
||||
focusing: false,
|
||||
isClick: false
|
||||
};
|
||||
},
|
||||
|
||||
@@ -84,9 +85,19 @@
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleFocus() {
|
||||
setTimeout(() => {
|
||||
if (!this.isClick) {
|
||||
this.focusing = true;
|
||||
} else {
|
||||
this.isClick = false;
|
||||
}
|
||||
}, 50);
|
||||
},
|
||||
handleHeaderClick() {
|
||||
this.dispatch('ElCollapse', 'item-click', this);
|
||||
this.focusing = false;
|
||||
this.isClick = true;
|
||||
},
|
||||
handleEnterClick() {
|
||||
this.dispatch('ElCollapse', 'item-click', this);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<template v-if="!arrowControl">
|
||||
<el-scrollbar
|
||||
@mouseenter.native="emitSelectRange('hours')"
|
||||
@mousemove.native="adjustCurrentSpinner('hours')"
|
||||
class="el-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="el-time-spinner__list"
|
||||
@@ -18,6 +19,7 @@
|
||||
</el-scrollbar>
|
||||
<el-scrollbar
|
||||
@mouseenter.native="emitSelectRange('minutes')"
|
||||
@mousemove.native="adjustCurrentSpinner('minutes')"
|
||||
class="el-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="el-time-spinner__list"
|
||||
@@ -33,6 +35,7 @@
|
||||
<el-scrollbar
|
||||
v-show="showSeconds"
|
||||
@mouseenter.native="emitSelectRange('seconds')"
|
||||
@mousemove.native="adjustCurrentSpinner('seconds')"
|
||||
class="el-time-spinner__wrapper"
|
||||
wrap-style="max-height: inherit;"
|
||||
view-class="el-time-spinner__list"
|
||||
@@ -196,16 +199,10 @@
|
||||
emitSelectRange(type) {
|
||||
if (type === 'hours') {
|
||||
this.$emit('select-range', 0, 2);
|
||||
this.adjustSpinner('minutes', this.minutes);
|
||||
this.adjustSpinner('seconds', this.seconds);
|
||||
} else if (type === 'minutes') {
|
||||
this.$emit('select-range', 3, 5);
|
||||
this.adjustSpinner('hours', this.hours);
|
||||
this.adjustSpinner('seconds', this.seconds);
|
||||
} else if (type === 'seconds') {
|
||||
this.$emit('select-range', 6, 8);
|
||||
this.adjustSpinner('minutes', this.minutes);
|
||||
this.adjustSpinner('hours', this.hours);
|
||||
}
|
||||
this.currentScrollbar = type;
|
||||
},
|
||||
@@ -237,6 +234,10 @@
|
||||
this.adjustSpinner('seconds', this.seconds);
|
||||
},
|
||||
|
||||
adjustCurrentSpinner(type) {
|
||||
this.adjustSpinner(type, this[type]);
|
||||
},
|
||||
|
||||
adjustSpinner(type, value) {
|
||||
if (this.arrowControl) return;
|
||||
const el = this.$refs[type].wrap;
|
||||
|
||||
@@ -89,19 +89,19 @@
|
||||
@click="leftPrevMonth"
|
||||
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
|
||||
<button
|
||||
type="button"
|
||||
@click="leftNextYear"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableYearArrow"
|
||||
:class="{ 'is-disabled': !enableYearArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||
type="button"
|
||||
@click="leftNextYear"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableYearArrow"
|
||||
:class="{ 'is-disabled': !enableYearArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||
<button
|
||||
type="button"
|
||||
@click="leftNextMonth"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableMonthArrow"
|
||||
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
|
||||
type="button"
|
||||
@click="leftNextMonth"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableMonthArrow"
|
||||
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
|
||||
<div>{{ leftLabel }}</div>
|
||||
</div>
|
||||
<date-table
|
||||
@@ -120,19 +120,19 @@
|
||||
<div class="el-picker-panel__content el-date-range-picker__content is-right">
|
||||
<div class="el-date-range-picker__header">
|
||||
<button
|
||||
type="button"
|
||||
@click="rightPrevYear"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableYearArrow"
|
||||
:class="{ 'is-disabled': !enableYearArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||
type="button"
|
||||
@click="rightPrevYear"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableYearArrow"
|
||||
:class="{ 'is-disabled': !enableYearArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||
<button
|
||||
type="button"
|
||||
@click="rightPrevMonth"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableMonthArrow"
|
||||
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
|
||||
type="button"
|
||||
@click="rightPrevMonth"
|
||||
v-if="unlinkPanels"
|
||||
:disabled="!enableMonthArrow"
|
||||
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
|
||||
<button
|
||||
type="button"
|
||||
@click="rightNextYear"
|
||||
@@ -336,7 +336,6 @@
|
||||
if (val && this.$refs.minTimePicker) {
|
||||
this.$refs.minTimePicker.date = val;
|
||||
this.$refs.minTimePicker.value = val;
|
||||
this.$refs.minTimePicker.adjustSpinners();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -344,7 +343,6 @@
|
||||
if (val && this.$refs.maxTimePicker) {
|
||||
this.$refs.maxTimePicker.date = val;
|
||||
this.$refs.maxTimePicker.value = val;
|
||||
this.$refs.maxTimePicker.adjustSpinners();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -406,7 +404,7 @@
|
||||
this.maxDate = null;
|
||||
this.leftDate = calcDefaultValue(this.defaultValue)[0];
|
||||
this.rightDate = nextMonth(this.leftDate);
|
||||
this.handleConfirm(false);
|
||||
this.$emit('pick', null);
|
||||
},
|
||||
|
||||
handleChangeRange(val) {
|
||||
@@ -484,6 +482,12 @@
|
||||
this.onPick && this.onPick(val);
|
||||
this.maxDate = val.maxDate;
|
||||
this.minDate = val.minDate;
|
||||
|
||||
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
|
||||
setTimeout(() => {
|
||||
this.maxDate = val.maxDate;
|
||||
this.minDate = val.minDate;
|
||||
}, 10);
|
||||
if (!close || this.showTime) return;
|
||||
this.handleConfirm();
|
||||
},
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
|
||||
handleClear() {
|
||||
this.date = this.defaultValue ? new Date(this.defaultValue) : new Date();
|
||||
this.$emit('pick');
|
||||
this.$emit('pick', null);
|
||||
},
|
||||
|
||||
emit(value, ...args) {
|
||||
|
||||
@@ -135,9 +135,6 @@
|
||||
this.maxDate = advanceTime(new Date(), 60 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
if (this.visible) {
|
||||
this.$nextTick(_ => this.adjustSpinners());
|
||||
}
|
||||
},
|
||||
|
||||
visible(val) {
|
||||
@@ -150,7 +147,7 @@
|
||||
|
||||
methods: {
|
||||
handleClear() {
|
||||
this.$emit('pick', []);
|
||||
this.$emit('pick', null);
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
|
||||
handleClear() {
|
||||
this.$emit('pick');
|
||||
this.$emit('pick', null);
|
||||
},
|
||||
|
||||
scrollToOption(selector = '.selected') {
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
if (val) {
|
||||
this.oldValue = this.value;
|
||||
this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'));
|
||||
} else {
|
||||
this.needInitAdjust = true;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -63,8 +65,9 @@
|
||||
}
|
||||
|
||||
this.date = date;
|
||||
if (this.visible) {
|
||||
if (this.visible && this.needInitAdjust) {
|
||||
this.$nextTick(_ => this.adjustSpinners());
|
||||
this.needInitAdjust = false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -90,7 +93,8 @@
|
||||
selectableRange: [],
|
||||
selectionRange: [0, 2],
|
||||
disabled: false,
|
||||
arrowControl: false
|
||||
arrowControl: false,
|
||||
needInitAdjust: true
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
:readonly="!editable || readonly"
|
||||
:disabled="disabled"
|
||||
:size="pickerSize"
|
||||
:id="id"
|
||||
:name="name"
|
||||
v-if="!ranged"
|
||||
v-clickoutside="handleClose"
|
||||
@@ -47,6 +48,8 @@
|
||||
:placeholder="startPlaceholder"
|
||||
:value="displayValue && displayValue[0]"
|
||||
:disabled="disabled"
|
||||
:id="id && id[0]"
|
||||
:name="name && name[0]"
|
||||
@input="handleStartInput"
|
||||
@change="handleStartChange"
|
||||
@focus="handleFocus"
|
||||
@@ -56,6 +59,8 @@
|
||||
:placeholder="endPlaceholder"
|
||||
:value="displayValue && displayValue[1]"
|
||||
:disabled="disabled"
|
||||
:id="id && id[1]"
|
||||
:name="name && name[1]"
|
||||
@input="handleEndInput"
|
||||
@change="handleEndChange"
|
||||
@focus="handleFocus"
|
||||
@@ -157,8 +162,14 @@ const TYPE_VALUE_RESOLVER_MAP = {
|
||||
},
|
||||
week: {
|
||||
formatter(value, format) {
|
||||
let date = formatDate(value, format);
|
||||
const week = getWeekNumber(value);
|
||||
let week = getWeekNumber(value);
|
||||
let month = value.getMonth();
|
||||
const trueDate = new Date(value);
|
||||
if (week === 1 && month === 11) {
|
||||
trueDate.setHours(0, 0, 0, 0);
|
||||
trueDate.setDate(trueDate.getDate() + 3 - (trueDate.getDay() + 6) % 7);
|
||||
}
|
||||
let date = formatDate(trueDate, format);
|
||||
|
||||
date = /WW/.test(date)
|
||||
? date.replace(/WW/, week < 10 ? '0' + week : week)
|
||||
@@ -266,6 +277,20 @@ const valueEquals = function(a, b) {
|
||||
return false;
|
||||
};
|
||||
|
||||
const isString = function(val) {
|
||||
return typeof val === 'string' || val instanceof String;
|
||||
};
|
||||
|
||||
const validator = function(val) {
|
||||
// either: String, Array of String, null / undefined
|
||||
return (
|
||||
val === null ||
|
||||
val === undefined ||
|
||||
isString(val) ||
|
||||
(Array.isArray(val) && val.length === 2 && val.every(isString))
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
mixins: [Emitter, NewPopper, Focus('reference')],
|
||||
|
||||
@@ -283,12 +308,19 @@ export default {
|
||||
placeholder: String,
|
||||
startPlaceholder: String,
|
||||
endPlaceholder: String,
|
||||
name: String,
|
||||
name: {
|
||||
default: '',
|
||||
validator
|
||||
},
|
||||
disabled: Boolean,
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
id: {
|
||||
default: '',
|
||||
validator
|
||||
},
|
||||
popperClass: String,
|
||||
editable: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -53,7 +53,10 @@
|
||||
label: String,
|
||||
labelWidth: String,
|
||||
prop: String,
|
||||
required: Boolean,
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: undefined
|
||||
},
|
||||
rules: [Object, Array],
|
||||
error: String,
|
||||
validateStatus: String,
|
||||
@@ -163,8 +166,9 @@
|
||||
},
|
||||
methods: {
|
||||
validate(trigger, callback = noop) {
|
||||
this.validateDisabled = false;
|
||||
var rules = this.getFilteredRule(trigger);
|
||||
if ((!rules || rules.length === 0) && !this._props.hasOwnProperty('required')) {
|
||||
if ((!rules || rules.length === 0) && this.required === undefined) {
|
||||
callback();
|
||||
return true;
|
||||
}
|
||||
@@ -215,7 +219,7 @@
|
||||
getRules() {
|
||||
var formRules = this.form.rules;
|
||||
var selfRules = this.rules;
|
||||
var requiredRule = this._props.hasOwnProperty('required') ? { required: !!this.required } : [];
|
||||
var requiredRule = this.required !== undefined ? { required: !!this.required } : [];
|
||||
|
||||
formRules = formRules ? formRules[this.prop] : [];
|
||||
|
||||
@@ -254,7 +258,7 @@
|
||||
|
||||
let rules = this.getRules();
|
||||
|
||||
if (rules.length || this._props.hasOwnProperty('required')) {
|
||||
if (rules.length || this.required !== undefined) {
|
||||
this.$on('el.form.blur', this.onFieldBlur);
|
||||
this.$on('el.form.change', this.onFieldChange);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,19 @@
|
||||
console.warn('[Element Warn][Form]model is required for validate to work!');
|
||||
return;
|
||||
}
|
||||
|
||||
let promise;
|
||||
// if no callback, return promise
|
||||
if (typeof callback !== 'function' && window.Promise) {
|
||||
promise = new window.Promise((resolve, reject) => {
|
||||
callback = function(valid) {
|
||||
valid ? resolve(valid) : reject(valid);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let valid = true;
|
||||
let count = 0;
|
||||
// 如果需要验证的fields为空,调用验证时立刻返回callback
|
||||
if (this.fields.length === 0 && callback) {
|
||||
callback(true);
|
||||
@@ -90,13 +102,14 @@
|
||||
if (errors) {
|
||||
valid = false;
|
||||
}
|
||||
if (typeof callback === 'function' && ++count === this.fields.length) {
|
||||
callback(valid);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback(valid);
|
||||
} else if (window.Promise) {
|
||||
return Promise[valid ? 'resolve' : 'reject'](valid); // eslint-disable-line
|
||||
if (promise) {
|
||||
return promise;
|
||||
}
|
||||
},
|
||||
validateField(prop, cb) {
|
||||
|
||||
@@ -208,6 +208,15 @@
|
||||
if (value === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.indexOf('.') === (value.length - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.indexOf('-') === (value.length - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newVal = Number(value);
|
||||
if (!isNaN(newVal)) {
|
||||
this.setCurrentValue(newVal);
|
||||
|
||||
@@ -39,14 +39,11 @@ exports.install = Vue => {
|
||||
if (el.domVisible) {
|
||||
el.instance.$on('after-leave', _ => {
|
||||
el.domVisible = false;
|
||||
if (binding.modifiers.fullscreen && el.originalOverflow !== 'hidden') {
|
||||
document.body.style.overflow = el.originalOverflow;
|
||||
}
|
||||
if (binding.modifiers.fullscreen || binding.modifiers.body) {
|
||||
document.body.style.position = el.originalPosition;
|
||||
} else {
|
||||
el.style.position = el.originalPosition;
|
||||
}
|
||||
const target = binding.modifiers.fullscreen || binding.modifiers.body
|
||||
? document.body
|
||||
: el;
|
||||
removeClass(target, 'el-loading-parent--relative');
|
||||
removeClass(target, 'el-loading-parent--hidden');
|
||||
});
|
||||
el.instance.visible = false;
|
||||
}
|
||||
@@ -59,10 +56,10 @@ exports.install = Vue => {
|
||||
});
|
||||
|
||||
if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
|
||||
parent.style.position = 'relative';
|
||||
addClass(parent, 'el-loading-parent--relative');
|
||||
}
|
||||
if (binding.modifiers.fullscreen && binding.modifiers.lock) {
|
||||
parent.style.overflow = 'hidden';
|
||||
addClass(parent, 'el-loading-parent--hidden');
|
||||
}
|
||||
el.domVisible = true;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
import loadingVue from './loading.vue';
|
||||
import { getStyle } from 'element-ui/src/utils/dom';
|
||||
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
|
||||
import merge from 'element-ui/src/utils/merge';
|
||||
|
||||
const LoadingConstructor = Vue.extend(loadingVue);
|
||||
@@ -23,14 +23,11 @@ LoadingConstructor.prototype.close = function() {
|
||||
fullscreenLoading = undefined;
|
||||
}
|
||||
this.$on('after-leave', _ => {
|
||||
if (this.fullscreen && this.originalOverflow !== 'hidden') {
|
||||
document.body.style.overflow = this.originalOverflow;
|
||||
}
|
||||
if (this.fullscreen || this.body) {
|
||||
document.body.style.position = this.originalPosition;
|
||||
} else {
|
||||
this.target.style.position = this.originalPosition;
|
||||
}
|
||||
const target = this.fullscreen || this.body
|
||||
? document.body
|
||||
: this.target;
|
||||
removeClass(target, 'el-loading-parent--relative');
|
||||
removeClass(target, 'el-loading-parent--hidden');
|
||||
if (this.$el && this.$el.parentNode) {
|
||||
this.$el.parentNode.removeChild(this.$el);
|
||||
}
|
||||
@@ -88,10 +85,10 @@ const Loading = (options = {}) => {
|
||||
|
||||
addStyle(options, parent, instance);
|
||||
if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed') {
|
||||
parent.style.position = 'relative';
|
||||
addClass(parent, 'el-loading-parent--relative');
|
||||
}
|
||||
if (options.fullscreen && options.lock) {
|
||||
parent.style.overflow = 'hidden';
|
||||
addClass(parent, 'el-loading-parent--hidden');
|
||||
}
|
||||
parent.appendChild(instance.$el);
|
||||
Vue.nextTick(() => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import ElSelect from 'element-ui/packages/select';
|
||||
import ElOption from 'element-ui/packages/option';
|
||||
import ElInput from 'element-ui/packages/input';
|
||||
import Locale from 'element-ui/src/mixins/locale';
|
||||
import { valueEquals } from 'element-ui/src/utils/util';
|
||||
|
||||
export default {
|
||||
name: 'ElPagination',
|
||||
@@ -147,9 +148,10 @@ export default {
|
||||
watch: {
|
||||
pageSizes: {
|
||||
immediate: true,
|
||||
handler(value) {
|
||||
if (Array.isArray(value)) {
|
||||
this.$parent.internalPageSize = value.indexOf(this.$parent.pageSize) > -1
|
||||
handler(newVal, oldVal) {
|
||||
if (valueEquals(newVal, oldVal)) return;
|
||||
if (Array.isArray(newVal)) {
|
||||
this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1
|
||||
? this.$parent.pageSize
|
||||
: this.pageSizes[0];
|
||||
}
|
||||
@@ -179,8 +181,7 @@ export default {
|
||||
|
||||
components: {
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElInput
|
||||
ElOption
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -202,6 +203,8 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
components: { ElInput },
|
||||
|
||||
methods: {
|
||||
handleFocus(event) {
|
||||
this.oldValue = event.target.value;
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
<input
|
||||
type="text"
|
||||
class="el-select__input"
|
||||
:class="`is-${ selectSize }`"
|
||||
@focus="visible = true"
|
||||
:class="[selectSize ? `is-${ selectSize }` : '']"
|
||||
:disabled="disabled"
|
||||
@keyup="managePlaceholder"
|
||||
@keydown="resetInputState"
|
||||
@@ -49,6 +48,7 @@
|
||||
type="text"
|
||||
:placeholder="currentPlaceholder"
|
||||
:name="name"
|
||||
:id="id"
|
||||
:size="selectSize"
|
||||
:disabled="disabled"
|
||||
:readonly="!filterable || multiple"
|
||||
@@ -113,6 +113,7 @@
|
||||
import { t } from 'element-ui/src/locale';
|
||||
import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
|
||||
import { getValueByPath } from 'element-ui/src/utils/util';
|
||||
import { valueEquals } from 'element-ui/src/utils/util';
|
||||
import NavigationMixin from './navigation-mixin';
|
||||
|
||||
const sizeMap = {
|
||||
@@ -121,18 +122,6 @@
|
||||
'mini': 28
|
||||
};
|
||||
|
||||
const valueEquals = (a, b) => {
|
||||
// see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
|
||||
if (a === b) return true;
|
||||
if (!(a instanceof Array)) return false;
|
||||
if (!(b instanceof Array)) return false;
|
||||
if (a.length !== b.length) return false;
|
||||
for (let i = 0; i !== a.length; ++i) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export default {
|
||||
mixins: [Emitter, Locale, Focus('reference'), NavigationMixin],
|
||||
|
||||
@@ -208,6 +197,7 @@
|
||||
|
||||
props: {
|
||||
name: String,
|
||||
id: String,
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
@@ -549,7 +539,7 @@
|
||||
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
|
||||
const tags = this.$refs.tags;
|
||||
input.style.height = this.selected.length === 0 && this.selectSize === 'mini'
|
||||
? sizeMap[this.selectSize]
|
||||
? sizeMap[this.selectSize] + 'px'
|
||||
: Math.max(tags ? (tags.clientHeight + 10) : 0, sizeMap[this.selectSize] || 40) + 'px';
|
||||
if (this.visible && this.emptyText !== false) {
|
||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||
|
||||
@@ -77,6 +77,7 @@ Vue.component('el-table-column', ElTableColumn)
|
||||
| render-header | 列标题 Label 区域渲染使用的 Function | Function(h, { column, $index }) | — | — |
|
||||
| sortable | 对应列是否可以排序,如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, 'custom' | false |
|
||||
| sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效 | Function(a, b) | — | — |
|
||||
| sort-by | 对数据进行排序的时候按照 sort-by 排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组,则先按照第 0 个排序,如果第 0 个相等,再按照第 1 个排序,以此类推。 | Function(row, index)/String/Array | — | — |
|
||||
| resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |
|
||||
| formatter | 用来格式化内容 | Function(row, column) | — | — |
|
||||
| show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | Boolean | — | false |
|
||||
|
||||
@@ -134,6 +134,7 @@ export default {
|
||||
default: false
|
||||
},
|
||||
sortMethod: Function,
|
||||
sortBy: [String, Function, Array],
|
||||
resizable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -234,6 +235,7 @@ export default {
|
||||
headerAlign: this.headerAlign ? 'is-' + this.headerAlign : (this.align ? 'is-' + this.align : null),
|
||||
sortable: this.sortable === '' ? true : this.sortable,
|
||||
sortMethod: this.sortMethod,
|
||||
sortBy: this.sortBy,
|
||||
resizable: this.resizable,
|
||||
showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow,
|
||||
formatter: this.formatter,
|
||||
|
||||
@@ -8,7 +8,7 @@ const sortData = (data, states) => {
|
||||
if (!sortingColumn || typeof sortingColumn.sortable === 'string') {
|
||||
return data;
|
||||
}
|
||||
return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod);
|
||||
return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod, sortingColumn.sortBy);
|
||||
};
|
||||
|
||||
const getKeysMap = function(array, rowKey) {
|
||||
|
||||
@@ -345,6 +345,7 @@
|
||||
this.updateScrollY();
|
||||
this.layout.update();
|
||||
this.$nextTick(() => {
|
||||
if (this.destroyed) return;
|
||||
if (this.height) {
|
||||
this.layout.setHeight(this.height);
|
||||
} else if (this.maxHeight) {
|
||||
@@ -355,7 +356,7 @@
|
||||
if (this.$el) {
|
||||
this.isHidden = this.$el.clientWidth === 0;
|
||||
if (this.isHidden && this.layout.bodyWidth) {
|
||||
setTimeout(() => this.doLayout());
|
||||
setTimeout(() => this.debouncedLayout());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -496,6 +497,7 @@
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.destroyed = true;
|
||||
if (this.windowResizeListener) removeResizeListener(this.$el, this.windowResizeListener);
|
||||
},
|
||||
|
||||
@@ -536,7 +538,8 @@
|
||||
resizeProxyVisible: false,
|
||||
// 是否拥有多级表头
|
||||
isGroup: false,
|
||||
scrollPosition: 'left'
|
||||
scrollPosition: 'left',
|
||||
destroyed: false
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,28 +17,61 @@ const isObject = function(obj) {
|
||||
return obj !== null && typeof obj === 'object';
|
||||
};
|
||||
|
||||
export const orderBy = function(array, sortKey, reverse, sortMethod) {
|
||||
if (typeof reverse === 'string') {
|
||||
reverse = reverse === 'descending' ? -1 : 1;
|
||||
}
|
||||
if (!sortKey && !sortMethod) {
|
||||
export const orderBy = function(array, sortKey, reverse, sortMethod, sortBy) {
|
||||
if (!sortKey && !sortMethod && (!sortBy || Array.isArray(sortBy) && !sortBy.length)) {
|
||||
return array;
|
||||
}
|
||||
const order = (reverse && reverse < 0) ? -1 : 1;
|
||||
|
||||
// sort on a copy to avoid mutating original array
|
||||
return array.slice().sort(sortMethod ? function(a, b) {
|
||||
const result = sortMethod(a, b);
|
||||
return result === 0 ? 0 : result > 0 ? order : -order;
|
||||
} : function(a, b) {
|
||||
if (sortKey !== '$key') {
|
||||
if (isObject(a) && '$value' in a) a = a.$value;
|
||||
if (isObject(b) && '$value' in b) b = b.$value;
|
||||
if (typeof reverse === 'string') {
|
||||
reverse = reverse === 'descending' ? -1 : 1;
|
||||
} else {
|
||||
reverse = (reverse && reverse < 0) ? -1 : 1;
|
||||
}
|
||||
const getKey = sortMethod ? null : function(value, index) {
|
||||
if (sortBy) {
|
||||
if (!Array.isArray(sortBy)) {
|
||||
sortBy = [sortBy];
|
||||
}
|
||||
return sortBy.map(function(by) {
|
||||
if (typeof by === 'string') {
|
||||
return getValueByPath(value, by);
|
||||
} else {
|
||||
return by(value, index, array);
|
||||
}
|
||||
});
|
||||
}
|
||||
a = isObject(a) ? getValueByPath(a, sortKey) : a;
|
||||
b = isObject(b) ? getValueByPath(b, sortKey) : b;
|
||||
return a === b ? 0 : a > b ? order : -order;
|
||||
});
|
||||
if (sortKey !== '$key') {
|
||||
if (isObject(value) && '$value' in value) value = value.$value;
|
||||
}
|
||||
return [isObject(value) ? getValueByPath(value, sortKey) : value];
|
||||
};
|
||||
const compare = function(a, b) {
|
||||
if (sortMethod) {
|
||||
return sortMethod(a.value, b.value);
|
||||
}
|
||||
for (let i = 0, len = a.key.length; i < len; i++) {
|
||||
if (a.key[i] < b.key[i]) {
|
||||
return -1;
|
||||
}
|
||||
if (a.key[i] > b.key[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
return array.map(function(value, index) {
|
||||
return {
|
||||
value: value,
|
||||
index: index,
|
||||
key: getKey ? getKey(value, index) : null
|
||||
};
|
||||
}).sort(function(a, b) {
|
||||
let order = compare(a, b);
|
||||
if (!order) {
|
||||
// make stable https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
|
||||
order = a.index - b.index;
|
||||
}
|
||||
return order * reverse;
|
||||
}).map(item => item.value);
|
||||
};
|
||||
|
||||
export const getColumnById = function(table, columnId) {
|
||||
|
||||
@@ -33,10 +33,16 @@
|
||||
return true;
|
||||
} else {
|
||||
tabSize = $el[`client${firstUpperCase(sizeName)}`];
|
||||
if (sizeName === 'width') {
|
||||
tabSize -= index === 0 ? 20 : 40;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (sizeName === 'width' && offset !== 0) {
|
||||
offset += 20;
|
||||
}
|
||||
const transform = `translate${firstUpperCase(sizeDir)}(${offset}px)`;
|
||||
style[sizeName] = tabSize + 'px';
|
||||
style.transform = transform;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "element-theme-chalk",
|
||||
"version": "2.0.0-rc.1",
|
||||
"version": "2.0.2",
|
||||
"description": "Element component chalk theme.",
|
||||
"main": "lib/index.css",
|
||||
"style": "lib/index.css",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@import "common/var";
|
||||
@import "./input.scss";
|
||||
@import "./scrollbar.scss";
|
||||
@import "./popper";
|
||||
|
||||
@include b(autocomplete) {
|
||||
position: relative;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "mixins/mixins";
|
||||
@import "./input.scss";
|
||||
@import "common/var";
|
||||
@import "./input.scss";
|
||||
@import "./popper";
|
||||
|
||||
@include b(cascader) {
|
||||
display: inline-block;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
@include b(checkbox) {
|
||||
color: $--checkbox-color;
|
||||
font-weight: $--checkbox-font-weight;
|
||||
font-size: $--font-size-base;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
@@ -339,3 +340,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include b(checkbox-group) {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
/* Transition
|
||||
-------------------------- */
|
||||
$--all-transition: all .3s cubic-bezier(.645,.045,.355,1);
|
||||
$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||
$--fade-linear-transition: opacity 200ms linear;
|
||||
$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
|
||||
$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1);
|
||||
$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1);
|
||||
$--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default;
|
||||
$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default;
|
||||
$--fade-linear-transition: opacity 200ms linear !default;
|
||||
$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms !default;
|
||||
$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default;
|
||||
$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default;
|
||||
|
||||
/* Colors
|
||||
-------------------------- */
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
@import "./date-picker/time-range-picker.scss";
|
||||
@import "./date-picker/time-picker.scss";
|
||||
@import "./input.scss";
|
||||
@import "./scrollbar.scss";
|
||||
@import "./scrollbar.scss";
|
||||
@import "./popper";
|
||||
@@ -15,14 +15,14 @@
|
||||
@include m((daterange, timerange)) {
|
||||
&.el-input,
|
||||
&.el-input__inner {
|
||||
width: 320px;
|
||||
width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@include m(datetimerange) {
|
||||
&.el-input,
|
||||
&.el-input__inner {
|
||||
width: 370px;
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 38%;
|
||||
width: 39%;
|
||||
text-align: center;
|
||||
font-size: $--font-size-base;
|
||||
color: $--color-text-regular;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@include b(time-spinner) {
|
||||
&.has-seconds {
|
||||
.el-time-spinner__wrapper {
|
||||
width: 33%;
|
||||
width: 33.3%;
|
||||
}
|
||||
|
||||
.el-time-spinner__wrapper:nth-child(2) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
@import "button";
|
||||
@import "./popper";
|
||||
|
||||
@include b(dropdown) {
|
||||
display: inline-block;
|
||||
|
||||
@@ -124,14 +124,15 @@
|
||||
|
||||
@include when(without-controls) {
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@include when(controls-right) {
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
padding-right: #{$--input-height + 10};
|
||||
padding-left: 15px;
|
||||
padding-right: #{$--input-height + 10};
|
||||
}
|
||||
|
||||
@include e((increase, decrease)) {
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
|
||||
@include b(loading-parent) {
|
||||
@include m(relative) {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
@include m(hidden) {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
@include b(loading-mask) {
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
&.el-input .el-input__inner {
|
||||
height: $--pagination-button-height;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
@import "./popper";
|
||||
|
||||
@include b(popover) {
|
||||
position: absolute;
|
||||
@@ -27,102 +28,3 @@
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@include b(popper) {
|
||||
.popper__arrow,
|
||||
.popper__arrow::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.popper__arrow {
|
||||
border-width: $--popover-arrow-size;
|
||||
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03))
|
||||
}
|
||||
|
||||
.popper__arrow::after {
|
||||
content: " ";
|
||||
border-width: $--popover-arrow-size;
|
||||
}
|
||||
|
||||
&[x-placement^="top"] {
|
||||
margin-bottom: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="top"] .popper__arrow {
|
||||
bottom: -$--popover-arrow-size;
|
||||
left: 50%;
|
||||
margin-right: #{$--tooltip-arrow-size / 2};
|
||||
border-top-color: $--popover-border-color;
|
||||
border-bottom-width: 0;
|
||||
|
||||
&::after {
|
||||
bottom: 1px;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-top-color: $--popover-fill;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] {
|
||||
margin-top: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] .popper__arrow {
|
||||
top: -$--popover-arrow-size;
|
||||
left: 50%;
|
||||
margin-right: #{$--tooltip-arrow-size / 2};
|
||||
border-top-width: 0;
|
||||
border-bottom-color: $--popover-border-color;
|
||||
|
||||
&::after {
|
||||
top: 1px;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-top-width: 0;
|
||||
border-bottom-color: $--popover-fill;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="right"] {
|
||||
margin-left: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="right"] .popper__arrow {
|
||||
top: 50%;
|
||||
left: -$--popover-arrow-size;
|
||||
margin-bottom: #{$--tooltip-arrow-size / 2};
|
||||
border-right-color: $--popover-border-color;
|
||||
border-left-width: 0;
|
||||
|
||||
&::after {
|
||||
bottom: -$--popover-arrow-size;
|
||||
left: 1px;
|
||||
border-right-color: $--popover-fill;
|
||||
border-left-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="left"] {
|
||||
margin-right: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="left"] .popper__arrow {
|
||||
top: 50%;
|
||||
right: -$--popover-arrow-size;
|
||||
margin-bottom: #{$--tooltip-arrow-size / 2};
|
||||
border-right-width: 0;
|
||||
border-left-color: $--popover-border-color;
|
||||
|
||||
&::after {
|
||||
right: 1px;
|
||||
bottom: -$--popover-arrow-size;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-right-width: 0;
|
||||
border-left-color: $--popover-fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
packages/theme-chalk/src/popper.scss
Normal file
101
packages/theme-chalk/src/popper.scss
Normal file
@@ -0,0 +1,101 @@
|
||||
@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
|
||||
@include b(popper) {
|
||||
.popper__arrow,
|
||||
.popper__arrow::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.popper__arrow {
|
||||
border-width: $--popover-arrow-size;
|
||||
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03))
|
||||
}
|
||||
|
||||
.popper__arrow::after {
|
||||
content: " ";
|
||||
border-width: $--popover-arrow-size;
|
||||
}
|
||||
|
||||
&[x-placement^="top"] {
|
||||
margin-bottom: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="top"] .popper__arrow {
|
||||
bottom: -$--popover-arrow-size;
|
||||
left: 50%;
|
||||
margin-right: #{$--tooltip-arrow-size / 2};
|
||||
border-top-color: $--popover-border-color;
|
||||
border-bottom-width: 0;
|
||||
|
||||
&::after {
|
||||
bottom: 1px;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-top-color: $--popover-fill;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] {
|
||||
margin-top: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] .popper__arrow {
|
||||
top: -$--popover-arrow-size;
|
||||
left: 50%;
|
||||
margin-right: #{$--tooltip-arrow-size / 2};
|
||||
border-top-width: 0;
|
||||
border-bottom-color: $--popover-border-color;
|
||||
|
||||
&::after {
|
||||
top: 1px;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-top-width: 0;
|
||||
border-bottom-color: $--popover-fill;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="right"] {
|
||||
margin-left: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="right"] .popper__arrow {
|
||||
top: 50%;
|
||||
left: -$--popover-arrow-size;
|
||||
margin-bottom: #{$--tooltip-arrow-size / 2};
|
||||
border-right-color: $--popover-border-color;
|
||||
border-left-width: 0;
|
||||
|
||||
&::after {
|
||||
bottom: -$--popover-arrow-size;
|
||||
left: 1px;
|
||||
border-right-color: $--popover-fill;
|
||||
border-left-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="left"] {
|
||||
margin-right: #{$--popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^="left"] .popper__arrow {
|
||||
top: 50%;
|
||||
right: -$--popover-arrow-size;
|
||||
margin-bottom: #{$--tooltip-arrow-size / 2};
|
||||
border-right-width: 0;
|
||||
border-left-color: $--popover-border-color;
|
||||
|
||||
&::after {
|
||||
right: 1px;
|
||||
bottom: -$--popover-arrow-size;
|
||||
margin-left: -$--popover-arrow-size;
|
||||
border-right-width: 0;
|
||||
border-left-color: $--popover-fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,4 +5,5 @@
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
outline: none;
|
||||
font-size: $--font-size-base;
|
||||
@include utils-user-select(none);
|
||||
|
||||
@include when(bordered) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
@import "./popper";
|
||||
|
||||
@include b(select-dropdown) {
|
||||
position: absolute;
|
||||
|
||||
@@ -206,6 +206,12 @@
|
||||
bottom: 0;
|
||||
left: 11px;
|
||||
}
|
||||
|
||||
@include e(icon) {
|
||||
@include when(icon) {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include when(center) {
|
||||
@@ -244,10 +250,6 @@
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
|
||||
@include when(icon) {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@include e(icon-inner) {
|
||||
|
||||
@@ -224,6 +224,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@include m((top, bottom)) {
|
||||
&:not(.el-tabs--border-card):not(.el-tabs--card) .el-tabs__item:nth-child(2) {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
@include m(bottom) {
|
||||
.el-tabs__header {
|
||||
margin-bottom: 0;
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
@import "./date-picker/time-picker.scss";
|
||||
@import "./input.scss";
|
||||
@import "./scrollbar.scss";
|
||||
@import "./popper";
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
@import "common/var";
|
||||
@import "./date-picker/picker.scss";
|
||||
@import "./date-picker/date-picker.scss";
|
||||
@import "common/var";
|
||||
@import "./scrollbar.scss";
|
||||
@import "./popper";
|
||||
|
||||
.time-select {
|
||||
margin: 5px 0;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
cursor: pointer;
|
||||
|
||||
& > .el-tree-node__expand-icon {
|
||||
margin: 0 8px;
|
||||
padding: 6px;
|
||||
}
|
||||
& > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
@@ -45,13 +45,8 @@
|
||||
|
||||
@include e(expand-icon) {
|
||||
cursor: pointer;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 10px;
|
||||
border: 3.5px solid transparent;
|
||||
border-right-width: 0;
|
||||
border-left-color: $--tree-expand-icon-color;
|
||||
border-left-width: 6px;
|
||||
color: $--tree-expand-icon-color;
|
||||
font-size: 12px;
|
||||
|
||||
transform: rotate(0deg);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
@@ -61,7 +56,7 @@
|
||||
}
|
||||
|
||||
&.is-leaf {
|
||||
border-color: transparent;
|
||||
color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +330,12 @@
|
||||
font-size: 20px;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
transition: opacity .3s;
|
||||
@include utils-vertical-center;
|
||||
&::after {
|
||||
display: inline-block;
|
||||
content: "";
|
||||
height: 100%;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
span {
|
||||
display: none;
|
||||
|
||||
@@ -54,6 +54,7 @@ export default class TreeStore {
|
||||
node.visible = allHidden === false;
|
||||
}
|
||||
}
|
||||
if (!value) return;
|
||||
|
||||
if (node.visible && !node.isLeaf) node.expand();
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="el-tree-node__content"
|
||||
:style="{ 'padding-left': (node.level - 1) * tree.indent + 'px' }">
|
||||
<span
|
||||
class="el-tree-node__expand-icon"
|
||||
class="el-tree-node__expand-icon el-icon-caret-right"
|
||||
@click.stop="handleExpandIconClick"
|
||||
:class="{ 'is-leaf': node.isLeaf, expanded: !node.isLeaf && expanded }">
|
||||
</span>
|
||||
|
||||
@@ -41,20 +41,20 @@
|
||||
:stroke-width="listType === 'picture-card' ? 6 : 2"
|
||||
:percentage="parsePercentage(file.percentage)">
|
||||
</el-progress>
|
||||
<span class="el-upload-list__item-actions" v-if="listType === 'picture-card'">
|
||||
<span class="el-upload-list__item-actions" v-if="listType === 'picture-card'">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
v-if="handlePreview && listType === 'picture-card'"
|
||||
@click="handlePreview(file)"
|
||||
>
|
||||
<i class="el-icon-view"></i>
|
||||
<i class="el-icon-zoom-in"></i>
|
||||
</span>
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="$emit('remove', file)"
|
||||
>
|
||||
<i class="el-icon-delete2"></i>
|
||||
<i class="el-icon-delete"></i>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
@@ -13,7 +13,8 @@ export default {
|
||||
interval = null;
|
||||
};
|
||||
|
||||
on(el, 'mousedown', () => {
|
||||
on(el, 'mousedown', (e) => {
|
||||
if (e.button !== 0) return;
|
||||
startTime = new Date();
|
||||
once(document, 'mouseup', clear);
|
||||
clearInterval(interval);
|
||||
|
||||
@@ -173,7 +173,7 @@ if (typeof window !== 'undefined' && window.Vue) {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
version: '2.0.0-rc.1',
|
||||
version: '2.0.2',
|
||||
locale: locale.use,
|
||||
i18n: locale.i18n,
|
||||
install,
|
||||
|
||||
@@ -49,6 +49,7 @@ export function getPropByPath(obj, path, strict) {
|
||||
let keyArr = path.split('.');
|
||||
let i = 0;
|
||||
for (let len = keyArr.length; i < len - 1; ++i) {
|
||||
if (!tempObj && !strict) break;
|
||||
let key = keyArr[i];
|
||||
if (key in tempObj) {
|
||||
tempObj = tempObj[key];
|
||||
@@ -62,7 +63,7 @@ export function getPropByPath(obj, path, strict) {
|
||||
return {
|
||||
o: tempObj,
|
||||
k: keyArr[i],
|
||||
v: tempObj[keyArr[i]]
|
||||
v: tempObj ? tempObj[keyArr[i]] : null
|
||||
};
|
||||
};
|
||||
|
||||
@@ -70,3 +71,14 @@ export const generateId = function() {
|
||||
return Math.floor(Math.random() * 10000);
|
||||
};
|
||||
|
||||
export const valueEquals = (a, b) => {
|
||||
// see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
|
||||
if (a === b) return true;
|
||||
if (!(a instanceof Array)) return false;
|
||||
if (!(b instanceof Array)) return false;
|
||||
if (a.length !== b.length) return false;
|
||||
for (let i = 0; i !== a.length; ++i) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -101,13 +101,14 @@ describe('DatePicker', () => {
|
||||
setTimeout(_ => {
|
||||
const $el = vm.$refs.compo.picker.$el;
|
||||
$el.querySelector('td.available').click();
|
||||
vm.$nextTick(_ => {
|
||||
vm.$el.querySelector('.el-input__icon').click();
|
||||
setTimeout(_ => {
|
||||
vm.$refs.compo.showClose = true;
|
||||
vm.$refs.compo.handleClickIcon({ stopPropagation: () => null });
|
||||
setTimeout(_ => {
|
||||
expect(vm.value).to.empty;
|
||||
expect(vm.value).to.equal(null);
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
@@ -1175,6 +1176,28 @@ describe('DatePicker', () => {
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('clear value', done => {
|
||||
vm = createVue({
|
||||
template: '<el-date-picker type="daterange" v-model="value" ref="compo" />',
|
||||
data() {
|
||||
return {
|
||||
value: [new Date(2000, 9, 1), new Date(2000, 9, 2)]
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
|
||||
vm.$el.querySelector('input').focus();
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$refs.compo.showClose = true;
|
||||
vm.$refs.compo.handleClickIcon({ stopPropagation: () => null });
|
||||
setTimeout(_ => {
|
||||
expect(vm.value).to.equal(null);
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
});
|
||||
|
||||
describe('type:datetimerange', () => {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { createVue, triggerEvent, triggerClick, destroyVM } from '../util';
|
||||
|
||||
const DELAY = 1;
|
||||
|
||||
describe('InputNumber', () => {
|
||||
let vm;
|
||||
afterEach(() => {
|
||||
@@ -263,30 +265,51 @@ describe('InputNumber', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
it('event:change', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input-number v-model="value" ref="input">
|
||||
</el-input-number>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
value: 1.5
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
describe('event:change', () => {
|
||||
let spy;
|
||||
|
||||
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
|
||||
const spy = sinon.spy();
|
||||
beforeEach(() => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input-number v-model="value" ref="compo" :min='2' :max='3' :step='1'>
|
||||
</el-input-number>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
value: 2
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
spy = sinon.spy();
|
||||
vm.$refs.compo.$on('change', spy);
|
||||
});
|
||||
|
||||
vm.$refs.input.$on('change', spy);
|
||||
it('emit on input', done => {
|
||||
vm.$refs.compo.handleInput('3');
|
||||
setTimeout(_ => {
|
||||
expect(spy.calledOnce).to.be.true;
|
||||
expect(spy.args[0][0]).to.equal(3);
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerClick(document, 'mouseup');
|
||||
it('emit on button', done => {
|
||||
const btnIncrease = vm.$el.querySelector('.el-input-number__increase');
|
||||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerClick(document, 'mouseup');
|
||||
setTimeout(_ => {
|
||||
expect(spy.calledOnce).to.be.true;
|
||||
expect(spy.args[0][0]).to.equal(3);
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(spy.withArgs(2.5, 1.5).calledOnce).to.be.true;
|
||||
done();
|
||||
it('does not emit on programatic change', done => {
|
||||
vm.value = 3;
|
||||
setTimeout(_ => {
|
||||
expect(spy.notCalled).to.be.true;
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
});
|
||||
it('event:focus & blur', done => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getStyle } from '../../../src/utils/dom';
|
||||
import { createVue, destroyVM } from '../util';
|
||||
import Vue from 'vue';
|
||||
import LoadingRaw from 'packages/loading';
|
||||
@@ -142,7 +143,7 @@ describe('Loading', () => {
|
||||
}
|
||||
}, true);
|
||||
Vue.nextTick(() => {
|
||||
expect(document.body.style.overflow).to.equal('hidden');
|
||||
expect(getStyle(document.body, 'overflow')).to.equal('hidden');
|
||||
vm.loading = false;
|
||||
document.body.removeChild(document.querySelector('.el-loading-mask'));
|
||||
document.body.removeChild(vm.$el);
|
||||
@@ -197,7 +198,7 @@ describe('Loading', () => {
|
||||
expect(mask.parentNode).to.equal(container);
|
||||
loadingInstance.close();
|
||||
setTimeout(() => {
|
||||
expect(container.style.position).to.equal('relative');
|
||||
expect(getStyle(container, 'position')).to.equal('relative');
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
@@ -243,7 +244,7 @@ describe('Loading', () => {
|
||||
|
||||
it('lock', () => {
|
||||
loadingInstance = Loading({ lock: true });
|
||||
expect(document.body.style.overflow).to.equal('hidden');
|
||||
expect(getStyle(document.body, 'overflow')).to.equal('hidden');
|
||||
});
|
||||
|
||||
it('text', () => {
|
||||
|
||||
@@ -995,7 +995,14 @@ describe('Table', () => {
|
||||
'sortable :sort-method="sortMethod"', '', '', '', {
|
||||
methods: {
|
||||
sortMethod(a, b) {
|
||||
return a.runtime < b.runtime;
|
||||
// sort method should return number
|
||||
if (a.runtime < b.runtime) {
|
||||
return 1;
|
||||
}
|
||||
if (a.runtime > b.runtime) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1013,6 +1020,46 @@ describe('Table', () => {
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('sortable by method', done => {
|
||||
const vm = createTable(
|
||||
'sortable :sort-by="sortBy"', '', '', '', {
|
||||
methods: {
|
||||
sortBy(a) {
|
||||
return -a.runtime;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(_ => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
elm.click();
|
||||
|
||||
setTimeout(_ => {
|
||||
const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
|
||||
expect(toArray(lastCells).map(node => node.textContent)).to.eql(['100', '95', '92', '92', '80']);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('sortable by property', done => {
|
||||
const vm = createTable(
|
||||
'sortable sort-by="runtime"', '', '', '', {});
|
||||
|
||||
setTimeout(_ => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
elm.click();
|
||||
|
||||
setTimeout(_ => {
|
||||
const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
|
||||
expect(toArray(lastCells).map(node => node.textContent)).to.eql(['80', '92', '92', '95', '100']);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('sort-change', done => {
|
||||
let result;
|
||||
const vm = createTable('sortable="custom"', '', '', '', {
|
||||
|
||||
8
types/carousel.d.ts
vendored
8
types/carousel.d.ts
vendored
@@ -36,18 +36,18 @@ export declare class ElCarousel extends ElementUIComponent {
|
||||
*
|
||||
* @param index Index of the slide to be switched to (starting from 0)
|
||||
*/
|
||||
setActiveItem (index: number)
|
||||
setActiveItem (index: number): void
|
||||
|
||||
/**
|
||||
* Manually switch slide by carousel item's name
|
||||
*
|
||||
* @param name The name of the corresponding `el-carousel-item`
|
||||
*/
|
||||
setActiveItem (name: string)
|
||||
setActiveItem (name: string): void
|
||||
|
||||
/** Switch to the previous slide */
|
||||
prev ()
|
||||
prev (): void
|
||||
|
||||
/** Switch to the next slide */
|
||||
next ()
|
||||
next (): void
|
||||
}
|
||||
|
||||
2
types/component.d.ts
vendored
2
types/component.d.ts
vendored
@@ -3,7 +3,7 @@ import Vue from 'vue'
|
||||
/** ElementUI component common definition */
|
||||
export declare class ElementUIComponent extends Vue {
|
||||
/** Install component into Vue */
|
||||
static install (vue: typeof Vue)
|
||||
static install (vue: typeof Vue): void
|
||||
}
|
||||
|
||||
/** Component size definition for button, input, etc */
|
||||
|
||||
4
types/index.d.ts
vendored
4
types/index.d.ts
vendored
@@ -77,7 +77,7 @@ declare namespace ElementUI {
|
||||
* Please do not invoke this method directly.
|
||||
* Call `Vue.use(ElementUI)` to install.
|
||||
*/
|
||||
export function install (vue: typeof Vue, options: ElementUI.InstallationOptions)
|
||||
export function install (vue: typeof Vue, options: ElementUI.InstallationOptions): void
|
||||
|
||||
/** ElementUI component common definition */
|
||||
export type Component = ElementUIComponent
|
||||
@@ -283,4 +283,4 @@ declare namespace ElementUI {
|
||||
export class Upload extends ElUpload {}
|
||||
}
|
||||
|
||||
export = ElementUI
|
||||
export default ElementUI
|
||||
|
||||
4
types/loading.d.ts
vendored
4
types/loading.d.ts
vendored
@@ -30,7 +30,7 @@ export interface LoadingServiceOptions {
|
||||
/** Loading Component */
|
||||
export declare class ElLoadingComponent extends Vue {
|
||||
/** Close the Loading instance */
|
||||
close ()
|
||||
close (): void
|
||||
}
|
||||
|
||||
/** Loading directive definition */
|
||||
@@ -46,7 +46,7 @@ export interface ElLoadingDirective extends VNodeDirective {
|
||||
/** Show animation while loading data */
|
||||
export interface ElLoading {
|
||||
/** Install Loading directive into Vue */
|
||||
install (vue: typeof Vue)
|
||||
install (vue: typeof Vue): void
|
||||
|
||||
/** If you do not have a specific DOM node to attach the Loading directive, or if you simply prefer not to use Loading as a directive, you can call this service with some configs to open a Loading instance. */
|
||||
service (options: LoadingServiceOptions): ElLoadingComponent
|
||||
|
||||
4
types/message-box.d.ts
vendored
4
types/message-box.d.ts
vendored
@@ -139,10 +139,10 @@ export interface ElMessageBox {
|
||||
prompt: ElMessageBoxShortcutMethod
|
||||
|
||||
/** Set default options of message boxes */
|
||||
setDefaults (defaults: ElMessageBoxOptions)
|
||||
setDefaults (defaults: ElMessageBoxOptions): void
|
||||
|
||||
/** Close current message box */
|
||||
close ()
|
||||
close (): void
|
||||
}
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
|
||||
2
types/message.d.ts
vendored
2
types/message.d.ts
vendored
@@ -5,7 +5,7 @@ export type MessageType = 'success' | 'warning' | 'info' | 'error'
|
||||
/** Message Component */
|
||||
export declare class ElMessageComponent extends Vue {
|
||||
/** Close the Loading instance */
|
||||
close ()
|
||||
close (): void
|
||||
}
|
||||
|
||||
export interface CloseEventHandler {
|
||||
|
||||
2
types/notification.d.ts
vendored
2
types/notification.d.ts
vendored
@@ -4,7 +4,7 @@ import { MessageType } from './message'
|
||||
/** Notification Component */
|
||||
export declare class ElNotificationComponent extends Vue {
|
||||
/** Close the Notification instance */
|
||||
close ()
|
||||
close (): void
|
||||
}
|
||||
|
||||
export interface ElNotificationOptions {
|
||||
|
||||
5
types/tree.d.ts
vendored
5
types/tree.d.ts
vendored
@@ -1,6 +1,5 @@
|
||||
import { CreateElement, VNode } from 'vue'
|
||||
import { ElementUIComponent } from './component'
|
||||
import {Tree} from "./index";
|
||||
|
||||
/** The node of the tree */
|
||||
export interface TreeNode {
|
||||
@@ -46,7 +45,7 @@ export declare class ElTree extends ElementUIComponent {
|
||||
props: object
|
||||
|
||||
/** Method for loading subtree data */
|
||||
load: (node: TreeNode, resolve) => void
|
||||
load: (node: TreeNode, resolve: Function) => void
|
||||
|
||||
/** Render function for tree node */
|
||||
renderContent: RenderContent
|
||||
@@ -128,7 +127,7 @@ export declare class ElTree extends ElementUIComponent {
|
||||
* @param checked Indicating the node checked or not
|
||||
* @param deep Indicating whether to checked state deeply or not
|
||||
*/
|
||||
setChecked (data: TreeNode | any, checked: boolean, deep: boolean)
|
||||
setChecked (data: TreeNode | any, checked: boolean, deep: boolean): void
|
||||
|
||||
/**
|
||||
* Return the highlight node's key (null if no node is highlighted)
|
||||
|
||||
Reference in New Issue
Block a user