diff --git a/README.md b/README.md index 099ffdca5..77186f604 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ - [Home Page](http://element.eleme.io/) - [Docs](http://element.eleme.io/#/component) - [FAQ](./FAQ.md) +- [Customize Theme](http://element.eleme.io/#/en-US/component/custom-theme) - Starter Kit - [element-starter](https://github.com/ElementUI/element-starter) - [element-cooking-starter](https://github.com/ElementUI/element-cooking-starter) diff --git a/examples/docs/en-US/custom-theme.md b/examples/docs/en-US/custom-theme.md index 19df6cf52..a5f49959d 100644 --- a/examples/docs/en-US/custom-theme.md +++ b/examples/docs/en-US/custom-theme.md @@ -1,10 +1,10 @@ ## Custom theme -Element uses BEM-styled CSS so that you can override styles easily. But if you need to replace styles at a large scale, e.g. change the theme color from blue to orange or green, maybe overriding them one by one is not a good idea, and this is where our theme customization tool kicks in. +Element uses BEM-styled CSS so that you can override styles easily. But if you need to replace styles at a large scale, e.g. change the theme color from blue to orange or green, maybe overriding them one by one is not a good idea, and this is where our theme customization tool kicks in. ### Install related tool First install the theme generator globally or locally. Local install is recommended because in this way, when others clone your project, npm will automatically install it for them. ```shell -npm i element-theme -D +npm i element-theme -g ``` Then install the default theme from npm or GitHub. @@ -20,7 +20,7 @@ npm i https://github.com/ElementUI/theme-default -D After successfully installing the above packages, a command named `et` is available in CLI (if the packages are installed locally, use `node_modules/.bin/et` instead). Run `-i` to initialize the variable file which outputs to `element-variables.css` by default. And you can specify its output directory as you will. ```shell -node_modules/.bin/et -i [custom output directory] +et -i [custom output directory] > ✔ Generator variables file ``` @@ -53,7 +53,7 @@ Just edit `element-variables.css`, e.g. changing the theme color to red: ### Build theme After saving the variable file, use `et` to build your theme. You can activate `watch` mode by adding a parameter `-w`: ```shell -node_modules/.bin/et +et > ✔ build theme font > ✔ build element theme diff --git a/examples/docs/en-US/form.md b/examples/docs/en-US/form.md index 8025311b3..3945f2f37 100644 --- a/examples/docs/en-US/form.md +++ b/examples/docs/en-US/form.md @@ -6,10 +6,10 @@ return callback(new Error('Please input the age')); } setTimeout(() => { - if (!Number.isInteger(age)) { + if (!Number.isInteger(value)) { callback(new Error('Please input digits')); - } else{ - if (age < 18) { + } else { + if (value < 18) { callback(new Error('Age must be greater than 18')); } else { callback(); @@ -117,7 +117,7 @@ { validator: validaePass2, trigger: 'blur' } ], age: [ - { validator: checkAge, trigger: 'change', trigger: 'blur' } + { validator: checkAge, trigger: 'blur' } ] }, dynamicForm: { @@ -172,6 +172,9 @@ handleReset2() { this.$refs.ruleForm2.resetFields(); }, + handleReset3() { + this.$refs.dynamicForm.resetFields(); + }, handleValidate(prop, errorMsg) { console.log(prop, errorMsg); }, @@ -632,7 +635,7 @@ Form component allows you to verify your data, helping you find and correct erro - + Submit @@ -647,10 +650,10 @@ Form component allows you to verify your data, helping you find and correct erro return callback(new Error('Please input the age')); } setTimeout(() => { - if (!Number.isInteger(age)) { + if (!Number.isInteger(value)) { callback(new Error('Please input digits')); - } else{ - if (age < 18) { + } else { + if (value < 18) { callback(new Error('Age must be greater than 18')); } else { callback(); @@ -691,7 +694,7 @@ Form component allows you to verify your data, helping you find and correct erro { validator: validaePass2, trigger: 'blur' } ], age: [ - { validator: checkAge, trigger: 'change', trigger: 'blur' } + { validator: checkAge, trigger: 'blur' } ] } }; @@ -729,12 +732,9 @@ Form component allows you to verify your data, helping you find and correct erro v-for="(domain, index) in dynamicForm.domains" :label="'Domain' + index" :key="domain.key" - :prop="'domains:' + index" + :prop="'domains.' + index + '.value'" :rules="{ - type: 'object', required: true, - fields: { - value: { required: true, message: 'domain can not be null', trigger: 'blur' } - } + required: true, message: 'domain can not be null', trigger: 'blur' }" > Delete @@ -742,6 +742,7 @@ Form component allows you to verify your data, helping you find and correct erro Submit New domain + Reset ``` -If you are using npm and wish to apply webpack, please continue to the next page: Quick Start. \ No newline at end of file +If you are using npm and wish to apply webpack, please continue to the next page: Quick Start. diff --git a/examples/docs/en-US/menu.md b/examples/docs/en-US/menu.md index 8d0ad6072..8694dba26 100644 --- a/examples/docs/en-US/menu.md +++ b/examples/docs/en-US/menu.md @@ -22,7 +22,7 @@ Menu that provides navigation for your website. Top bar NavMenu can be used in a variety of scenarios. -::: demo +::: demo By default Menu is vertical, but you can change it to horizontal by setting the mode prop to 'horizontal'. In addition, you can use the submenu component to create a second level menu. ```html Processing Center @@ -62,7 +62,7 @@ Top bar NavMenu can be used in a variety of scenarios. Vertical NavMenu with sub-menus. -::: demo +::: demo You can use the el-menu-item-group component to create a menu group, and the name of the group is determined by the title prop or a named slot. ```html diff --git a/examples/docs/en-US/radio.md b/examples/docs/en-US/radio.md index 9a7be7c33..3702ca1ec 100644 --- a/examples/docs/en-US/radio.md +++ b/examples/docs/en-US/radio.md @@ -137,5 +137,7 @@ change | triggers when the bound value changes | the label value of the chosen r ---- | ---- | ---- | ---- | ---- label | the value of radio | string/number | — | — disabled | whether radio is disabled | boolean | — | false +fill | border and background color when button is active | string | — | #20a0ff | +text-color | font color when button is active | string | — | #ffffff | diff --git a/examples/docs/en-US/table.md b/examples/docs/en-US/table.md index a17dfd055..0a85151c4 100644 --- a/examples/docs/en-US/table.md +++ b/examples/docs/en-US/table.md @@ -1183,7 +1183,8 @@ Customize table column so it can be integrated with other components. | fit | whether width of column automatically fits its container | boolean | — | true | | show-header | whether table header is visible | boolean | - | true | | highlight-current-row | whether current row is highlighted | boolean | — | false | -| row-class-name | function that returns custom class names for a row | Function(row, index) | — | — | +| row-class-name | function that returns custom class names for a row, or a string assigning class names for every row | Function(row, index)/String | — | — | +| row-style | function that returns custom style for a row, or a string assigning custom style for every row | Function(row, index)/Object | — | — | | row-key | key of row data, used for optimizing rendering. Required if `reserve-selection` is on | Function(row)/String | — | — | | context | context of Table, e.g. `_self` refers to the current context, `$parent` parent context, `$root` root context, can be overridden by `context` in `el-table-column` | Object | - | current context where Table lies | diff --git a/examples/docs/en-US/upload.md b/examples/docs/en-US/upload.md index c676cc1f8..e6d9d4752 100644 --- a/examples/docs/en-US/upload.md +++ b/examples/docs/en-US/upload.md @@ -1,5 +1,10 @@ diff --git a/packages/checkbox/src/checkbox.vue b/packages/checkbox/src/checkbox.vue index 4d67e7f78..5b1e8c4f2 100644 --- a/packages/checkbox/src/checkbox.vue +++ b/packages/checkbox/src/checkbox.vue @@ -17,11 +17,10 @@ :disabled="disabled" :true-value="trueLabel" :false-value="falseLabel" - v-model="_value" + v-model="model" + @change="$emit('change', $event)" @focus="focus = true" - @blur="focus = false" - @change="handleChange" - ref="checkbox"> + @blur="focus = false"> + @blur="focus = false"> @@ -48,9 +47,37 @@ mixins: [Emitter], + componentName: 'ElCheckbox', + + computed: { + model: { + get() { + return this.isGroup ? this.store : this.value; + }, + + set(val) { + if (this.isGroup) { + this.dispatch('ElCheckboxGroup', 'input', [val]); + } else { + this.$emit('input', val); + } + } + }, + + isChecked() { + if ({}.toString.call(this.model) === '[object Boolean]') { + return this.model; + } else if (Array.isArray(this.model)) { + return this.model.indexOf(this.label) > -1; + } else if (this.model !== null && this.model !== undefined) { + return this.model === this.trueLabel; + } + } + }, + props: { value: {}, - label: String, + label: {}, indeterminate: Boolean, disabled: Boolean, checked: Boolean, @@ -59,59 +86,30 @@ falseLabel: [String, Number] }, - computed: { - _value: { - get() { - return !this.wrapInGroup ? this.value : this.$parent.value; - }, - set(newValue) { - if (!this.wrapInGroup) { - this.$emit('input', newValue); - } else { - this.$parent.$emit('input', newValue); - } - } - }, - isChecked() { - var type = Object.prototype.toString.call(this._value); - - if (type === '[object Boolean]') { - return this._value; - } else if (type === '[object Array]') { - return this._value.indexOf(this.label) > -1; - } else if (type === '[object String]' || type === '[object Number]') { - return this._value === this.trueLabel; - } - } - }, - data() { return { - focus: false, - wrapInGroup: this.$parent.$options.componentName === 'ElCheckboxGroup' + store: [], + isGroup: false }; }, - watch: { - checked: { - immediate: true, - handler(value) { - if (value) { - let type = Object.prototype.toString.call(this._value); - if (type !== '[object Array]') { - this._value = this.trueLabel || true; - } else { - this._value.push(this.label); - } - } + methods: { + addToStore() { + if (Array.isArray(this.model)) { + this.model.indexOf(this.label) === -1 && this.model.push(this.label); + } else { + this.model = this.trueLabel || true; } } }, - methods: { - handleChange(ev) { - this.$emit('change', ev); - } + created() { + this.checked && this.addToStore(); + this.$on('initData', data => { + this.store = data; + this.isGroup = true; + this.checked && this.addToStore(); + }); } }; diff --git a/packages/date-picker/src/basic/year-table.vue b/packages/date-picker/src/basic/year-table.vue index c2075d5c4..0bc1827df 100644 --- a/packages/date-picker/src/basic/year-table.vue +++ b/packages/date-picker/src/basic/year-table.vue @@ -50,9 +50,7 @@ props: { disabledDate: {}, date: {}, - year: { - type: Number - } + year: {} }, computed: { @@ -86,7 +84,7 @@ const target = event.target; if (target.tagName === 'A') { if (hasClass(target.parentNode, 'disabled')) return; - const year = parseInt(target.textContent || target.innerText, 10); + const year = target.textContent || target.innerText; this.$emit('pick', year); } } diff --git a/packages/date-picker/src/panel/date.vue b/packages/date-picker/src/panel/date.vue index 1a6799edb..9547bf1fe 100644 --- a/packages/date-picker/src/panel/date.vue +++ b/packages/date-picker/src/panel/date.vue @@ -20,7 +20,7 @@ @click="handleShortcutClick(shortcut)">{{ shortcut.text }}
-
+
1 - ? model[temp[0]][temp[1]] - : model[this.prop]; + return getPropByPath(model, path).v; } } }, @@ -124,13 +148,19 @@ let model = this.form.model; let value = this.fieldValue; + let path = this.prop; + if (path.indexOf(':') !== -1) { + path = path.replace(/:/, '.'); + } + + let prop = getPropByPath(model, path); if (Array.isArray(value) && value.length > 0) { this.validateDisabled = true; - model[this.prop] = []; + prop.o[prop.k] = []; } else if (value) { this.validateDisabled = true; - model[this.prop] = this.initialValue; + prop.o[prop.k] = this.initialValue; } }, getRules() { @@ -162,10 +192,10 @@ }, mounted() { if (this.prop) { - this.dispatch('form', 'el.form.addField', [this]); + this.dispatch('ElForm', 'el.form.addField', [this]); Object.defineProperty(this, 'initialValue', { - value: this.form.model[this.prop] + value: this.fieldValue }); let rules = this.getRules(); @@ -183,7 +213,7 @@ } }, beforeDestroy() { - this.dispatch('form', 'el.form.removeField', [this]); + this.dispatch('ElForm', 'el.form.removeField', [this]); } }; diff --git a/packages/form/src/form.vue b/packages/form/src/form.vue index edd7f1263..b00634e44 100644 --- a/packages/form/src/form.vue +++ b/packages/form/src/form.vue @@ -10,7 +10,7 @@ export default { name: 'ElForm', - componentName: 'form', + componentName: 'ElForm', props: { model: Object, @@ -23,51 +23,50 @@ }, inline: Boolean }, + watch: { + rules() { + this.validate(); + } + }, data() { return { - fields: {}, - fieldLength: 0 + fields: [] }; }, created() { this.$on('el.form.addField', (field) => { - this.fields[field.prop] = field; - this.fieldLength++; + if (field) { + this.fields.push(field); + } }); /* istanbul ignore next */ this.$on('el.form.removeField', (field) => { - if (this.fields[field.prop]) { - delete this.fields[field.prop]; - this.fieldLength--; + if (field.prop) { + this.fields.splice(this.fields.indexOf(field), 1); } }); }, methods: { resetFields() { - for (let prop in this.fields) { - let field = this.fields[prop]; + this.fields.forEach(field => { field.resetField(); - } + }); }, validate(callback) { - var count = 0; - var valid = true; - - for (let prop in this.fields) { - let field = this.fields[prop]; + let valid = true; + this.fields.forEach((field, index) => { field.validate('', errors => { if (errors) { valid = false; } - - if (++count === this.fieldLength) { + if (typeof callback === 'function' && index === this.fields.length - 1) { callback(valid); } }); - } + }); }, validateField(prop, cb) { - var field = this.fields[prop]; + var field = this.fields.filter(field => field.prop === prop)[0]; if (!field) { throw new Error('must call validateField with valid prop string!'); } field.validate('', cb); diff --git a/packages/input/src/input.vue b/packages/input/src/input.vue index ef8cce329..f6a828863 100644 --- a/packages/input/src/input.vue +++ b/packages/input/src/input.vue @@ -68,6 +68,8 @@ export default { name: 'ElInput', + componentName: 'ElInput', + mixins: [emitter], props: { @@ -105,7 +107,7 @@ methods: { handleBlur(event) { this.$emit('blur', event); - this.dispatch('form-item', 'el.form.blur', [this.currentValue]); + this.dispatch('ElFormItem', 'el.form.blur', [this.currentValue]); }, inputSelect() { this.$refs.input.select(); @@ -148,7 +150,7 @@ computed: { validating() { - return this.$parent.validating; + return this.$parent.validateState === 'validating'; } }, @@ -162,7 +164,7 @@ }); this.$emit('input', val); this.$emit('change', val); - this.dispatch('form-item', 'el.form.change', [val]); + this.dispatch('ElFormItem', 'el.form.change', [val]); } } }; diff --git a/packages/menu/src/menu-item-group.vue b/packages/menu/src/menu-item-group.vue index 7fbcc2f91..200edcae1 100644 --- a/packages/menu/src/menu-item-group.vue +++ b/packages/menu/src/menu-item-group.vue @@ -6,8 +6,7 @@ props: { title: { - type: String, - required: true + type: String } }, data() { @@ -39,7 +38,10 @@ diff --git a/packages/select/src/option-group.vue b/packages/select/src/option-group.vue index 6073ed84a..9308625d3 100644 --- a/packages/select/src/option-group.vue +++ b/packages/select/src/option-group.vue @@ -27,13 +27,13 @@ watch: { disabled(val) { - this.broadcast('option', 'handleGroupDisabled', val); + this.broadcast('ElOption', 'handleGroupDisabled', val); } }, mounted() { if (this.disabled) { - this.broadcast('option', 'handleGroupDisabled', this.disabled); + this.broadcast('ElOption', 'handleGroupDisabled', this.disabled); } } }; diff --git a/packages/select/src/option.vue b/packages/select/src/option.vue index 9b26cf27a..6d1a748e4 100644 --- a/packages/select/src/option.vue +++ b/packages/select/src/option.vue @@ -19,7 +19,7 @@ name: 'el-option', - componentName: 'option', + componentName: 'ElOption', props: { value: { @@ -50,6 +50,10 @@ return this.label || ((typeof this.value === 'string' || typeof this.value === 'number') ? this.value : ''); }, + currentValue() { + return this.value || this.label || ''; + }, + parent() { let result = this.$parent; while (!result.isSelect) { @@ -74,7 +78,7 @@ watch: { currentSelected(val) { if (val === true) { - this.dispatch('select', 'addOptionToValue', this); + this.dispatch('ElSelect', 'addOptionToValue', this); } } }, @@ -92,7 +96,7 @@ selectOptionClick() { if (this.disabled !== true && this.groupDisabled !== true) { - this.dispatch('select', 'handleOptionClick', this); + this.dispatch('ElSelect', 'handleOptionClick', this); } }, @@ -119,7 +123,7 @@ this.index = this.parent.options.indexOf(this); if (this.currentSelected === true) { - this.dispatch('select', 'addOptionToValue', [this, true]); + this.dispatch('ElSelect', 'addOptionToValue', [this, true]); } this.$on('queryChange', this.queryChange); @@ -128,7 +132,7 @@ }, beforeDestroy() { - this.dispatch('select', 'onOptionDestroy', this); + this.dispatch('ElSelect', 'onOptionDestroy', this); } }; diff --git a/packages/select/src/select-dropdown.vue b/packages/select/src/select-dropdown.vue index 8660bcff2..90c470665 100644 --- a/packages/select/src/select-dropdown.vue +++ b/packages/select/src/select-dropdown.vue @@ -13,7 +13,7 @@ export default { name: 'el-select-dropdown', - componentName: 'select-dropdown', + componentName: 'ElSelectDropdown', mixins: [Popper], diff --git a/packages/select/src/select.vue b/packages/select/src/select.vue index 842b819b0..9879a03d3 100644 --- a/packages/select/src/select.vue +++ b/packages/select/src/select.vue @@ -82,7 +82,7 @@ name: 'ElSelect', - componentName: 'select', + componentName: 'ElSelect', computed: { iconClass() { @@ -97,16 +97,19 @@ let criteria = this.clearable && this.inputHovering && !this.multiple && this.options.indexOf(this.selected) > -1; if (!this.$el) return false; - let icon = this.$el.querySelector('.el-input__icon'); - if (icon) { - if (criteria) { - icon.addEventListener('click', this.deleteSelected); - addClass(icon, 'is-show-close'); - } else { - icon.removeEventListener('click', this.deleteSelected); - removeClass(icon, 'is-show-close'); + this.$nextTick(() => { + let icon = this.$el.querySelector('.el-input__icon'); + if (icon) { + if (criteria) { + icon.addEventListener('click', this.deleteSelected); + addClass(icon, 'is-show-close'); + } else { + icon.removeEventListener('click', this.deleteSelected); + removeClass(icon, 'is-show-close'); + } } - } + }); + return criteria; }, @@ -239,7 +242,7 @@ this.$emit('input', result); this.$emit('change', result); - this.dispatch('form-item', 'el.form.change', val); + this.dispatch('ElFormItem', 'el.form.change', val); if (this.filterable) { this.query = ''; this.hoverIndex = -1; @@ -259,7 +262,7 @@ query(val) { this.$nextTick(() => { - this.broadcast('select-dropdown', 'updatePopper'); + this.broadcast('ElSelectDropdown', 'updatePopper'); }); if (this.multiple && this.filterable) { this.resetInputHeight(); @@ -268,12 +271,12 @@ this.hoverIndex = -1; this.remoteMethod(val); this.voidRemoteQuery = val === ''; - this.broadcast('option', 'resetIndex'); + this.broadcast('ElOption', 'resetIndex'); } else if (typeof this.filterMethod === 'function') { this.filterMethod(val); } else { this.filteredOptionsCount = this.optionsCount; - this.broadcast('option', 'queryChange', val); + this.broadcast('ElOption', 'queryChange', val); } }, @@ -283,7 +286,7 @@ if (this.$el.querySelector('.el-input__icon')) { removeClass(this.$el.querySelector('.el-input__icon'), 'is-reverse'); } - this.broadcast('select-dropdown', 'destroyPopper'); + this.broadcast('ElSelectDropdown', 'destroyPopper'); if (this.$refs.input) { this.$refs.input.blur(); } @@ -301,13 +304,13 @@ if (icon && !hasClass(icon, 'el-icon-circle-close')) { addClass(this.$el.querySelector('.el-input__icon'), 'is-reverse'); } - this.broadcast('select-dropdown', 'updatePopper'); + this.broadcast('ElSelectDropdown', 'updatePopper'); if (this.filterable) { this.query = this.selectedLabel; if (this.multiple) { this.$refs.input.focus(); } else { - this.broadcast('input', 'inputSelect'); + this.broadcast('ElInput', 'inputSelect'); } } if (!this.dropdownUl) { @@ -395,7 +398,7 @@ let inputChildNodes = this.$refs.reference.$el.childNodes; let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0]; input.style.height = Math.max(this.$refs.tags.clientHeight + 6, this.size === 'small' ? 28 : 36) + 'px'; - this.broadcast('select-dropdown', 'updatePopper'); + this.broadcast('ElSelectDropdown', 'updatePopper'); }); }, @@ -421,7 +424,7 @@ } else { let optionIndex = -1; this.selected.forEach((item, index) => { - if (item === option || item.currentLabel === option.currentLabel) { + if (item === option || item.currentValue === option.currentValue) { optionIndex = index; } }); @@ -522,7 +525,7 @@ if (index > -1) { this.options.splice(index, 1); } - this.broadcast('option', 'resetIndex'); + this.broadcast('ElOption', 'resetIndex'); }, resetInputWidth() { diff --git a/packages/table/src/table-body.js b/packages/table/src/table-body.js index 64d32a107..de60f5834 100644 --- a/packages/table/src/table-body.js +++ b/packages/table/src/table-body.js @@ -10,6 +10,7 @@ export default { required: true }, rowClassName: [String, Function], + rowStyle: [Object, Function], fixed: String, highlight: Boolean }, @@ -33,6 +34,7 @@ export default { { this._l(this.data, (row, $index) => this.handleClick($event, row) } on-mouseenter={ _ => this.handleMouseEnter($index) } @@ -140,6 +142,14 @@ export default { } }, + getRowStyle(row, index) { + const rowStyle = this.rowStyle; + if (typeof rowStyle === 'function') { + return rowStyle.call(null, row, index); + } + return rowStyle; + }, + getRowClass(row, index) { const classes = []; @@ -147,7 +157,7 @@ export default { if (typeof rowClassName === 'string') { classes.push(rowClassName); } else if (typeof rowClassName === 'function') { - classes.push(rowClassName.apply(null, [row, index]) || ''); + classes.push(rowClassName.call(null, row, index) || ''); } return classes.join(' '); diff --git a/packages/table/src/table.vue b/packages/table/src/table.vue index 250535209..a30fbf968 100644 --- a/packages/table/src/table.vue +++ b/packages/table/src/table.vue @@ -24,6 +24,7 @@ :store="store" :layout="layout" :row-class-name="rowClassName" + :row-style="rowStyle" :highlight="highlightCurrentRow" :style="{ width: layout.bodyWidth ? layout.bodyWidth - (layout.scrollY ? layout.gutterWidth : 0 ) + 'px' : '' }"> @@ -56,6 +57,7 @@ :layout="layout" :highlight="highlightCurrentRow" :row-class-name="rowClassName" + :row-style="rowStyle" :style="{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }">
@@ -85,6 +87,7 @@ :store="store" :layout="layout" :row-class-name="rowClassName" + :row-style="rowStyle" :highlight="highlightCurrentRow" :style="{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }"> @@ -145,6 +148,8 @@ rowClassName: [String, Function], + rowStyle: [Object, Function], + highlightCurrentRow: Boolean, emptyText: { diff --git a/packages/theme-default/src/form.css b/packages/theme-default/src/form.css index 1bb37fb12..9e19cbd0d 100644 --- a/packages/theme-default/src/form.css +++ b/packages/theme-default/src/form.css @@ -60,11 +60,6 @@ top: 100%; left: 0; } - & .el-button + .el-button, - & .el-checkbox + .el-checkbox, - & .el-radio + .el-radio { - margin-left: 10px; - } @when required { .el-form-item__label:before { diff --git a/packages/theme-default/src/input.css b/packages/theme-default/src/input.css index 292a29b76..c467f7cd3 100644 --- a/packages/theme-default/src/input.css +++ b/packages/theme-default/src/input.css @@ -40,6 +40,7 @@ width: 35px; height: 100%; right: 0; + top: 0; text-align: center; color: var(--input-icon-color); diff --git a/packages/theme-default/src/radio.css b/packages/theme-default/src/radio.css index 0756f2f79..b48c70bb4 100644 --- a/packages/theme-default/src/radio.css +++ b/packages/theme-default/src/radio.css @@ -160,15 +160,6 @@ z-index: -1; left: -999px; - &:checked { - & + .el-radio-button__inner { - z-index: 1; - background-color: var(--color-primary); - border-color: @background-color; - color: #fff; - } - } - &:disabled { & + .el-radio-button__inner { color: var(--button-disabled-color); diff --git a/packages/theme-default/src/upload.css b/packages/theme-default/src/upload.css index 026a35a80..574a827ef 100644 --- a/packages/theme-default/src/upload.css +++ b/packages/theme-default/src/upload.css @@ -145,7 +145,7 @@ & img { display: block; width: 100%; - height: auto; + height: 100%; } @e progress { diff --git a/packages/tree/src/model/node.js b/packages/tree/src/model/node.js index 7163e468d..edc51e122 100644 --- a/packages/tree/src/model/node.js +++ b/packages/tree/src/model/node.js @@ -97,15 +97,7 @@ export default class Node { const defaultExpandedKeys = store.defaultExpandedKeys; const key = store.key; if (key && defaultExpandedKeys && defaultExpandedKeys.indexOf(this.key) !== -1) { - if (store.autoExpandParent) { - let parent = this.parent; - while (parent.level > 0) { - parent.expanded = true; - parent = parent.parent; - } - } - - this.expand(); + this.expand(null, store.autoExpandParent); } if (store.lazy) { @@ -213,17 +205,27 @@ export default class Node { } } - expand(callback) { + expand(callback, expandParent) { + const done = () => { + if (expandParent) { + let parent = this.parent; + while (parent.level > 0) { + parent.expanded = true; + parent = parent.parent; + } + } + this.expanded = true; + if (callback) callback(); + }; + if (this.shouldLoadData()) { this.loadData((data) => { if (data instanceof Array) { - this.expanded = true; - if (callback) callback(); + done(); } }); } else { - this.expanded = true; - if (callback) callback(); + done(); } } diff --git a/packages/tree/src/model/tree-store.js b/packages/tree/src/model/tree-store.js index 93108789a..54971e0e7 100644 --- a/packages/tree/src/model/tree-store.js +++ b/packages/tree/src/model/tree-store.js @@ -66,30 +66,30 @@ export default class TreeStore { } } - getNodeByData(data) { - const key = typeof data === 'string' ? data : getNodeKey(this.key, data); + getNode(data) { + const key = typeof data !== 'object' ? data : getNodeKey(this.key, data); return this.nodesMap[key]; } insertBefore(data, refData) { - const refNode = this.getNodeByData(refData); + const refNode = this.getNode(refData); refNode.parent.insertBefore({ data }, refNode); } insertAfter(data, refData) { - const refNode = this.getNodeByData(refData); + const refNode = this.getNode(refData); refNode.parent.insertAfter({ data }, refNode); } remove(data) { - const node = this.getNodeByData(data); + const node = this.getNode(data); if (node) { node.parent.removeChild(node); } } append(data, parentData) { - const parentNode = parentData ? this.getNodeByData(parentData) : this.root; + const parentNode = parentData ? this.getNode(parentData) : this.root; if (parentNode) { parentNode.insertChild({ data }); @@ -206,6 +206,7 @@ export default class TreeStore { } setCheckedKeys(keys, leafOnly = true) { + this.defaultCheckedKeys = keys; const key = this.key; const checkedKeys = {}; keys.forEach((key) => { @@ -214,4 +215,14 @@ export default class TreeStore { this._setCheckedKeys(key, leafOnly, checkedKeys); } + + setDefaultExpandedKeys(keys) { + keys = keys || []; + this.defaultExpandedKeys = keys; + + keys.forEach((key) => { + const node = this.getNode(key); + if (node) node.expand(null, this.autoExpandParent); + }); + } }; diff --git a/packages/tree/src/tree-node.vue b/packages/tree/src/tree-node.vue index a135bb2e0..38509592e 100644 --- a/packages/tree/src/tree-node.vue +++ b/packages/tree/src/tree-node.vue @@ -40,6 +40,7 @@