Merge pull request #1333 from QingWei-Li/fix/radio-checkox

Radio/Checkbox: fix radio-radiogroup checkbox-checkboxgroup nested bug fixed #1152
pull/1371/head
baiyaaaaa 2016-11-26 13:26:27 +08:00 committed by GitHub
commit a84926b117
8 changed files with 129 additions and 75 deletions

View File

@ -16,7 +16,12 @@
value(value) { value(value) {
this.$emit('change', value); this.$emit('change', value);
this.dispatch('form-item', 'el.form.change', [value]); this.dispatch('form-item', 'el.form.change', [value]);
this.broadcast('ElCheckbox', 'initData', [value]);
} }
},
mounted() {
this.broadcast('ElCheckbox', 'initData', [this.value]);
} }
}; };
</script> </script>

View File

@ -17,11 +17,10 @@
:disabled="disabled" :disabled="disabled"
:true-value="trueLabel" :true-value="trueLabel"
:false-value="falseLabel" :false-value="falseLabel"
v-model="_value" v-model="model"
@change="$emit('change', $event)"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false">
@change="handleChange"
ref="checkbox">
<input <input
v-else v-else
class="el-checkbox__original" class="el-checkbox__original"
@ -29,10 +28,10 @@
:disabled="disabled" :disabled="disabled"
:value="label" :value="label"
:name="name" :name="name"
v-model="_value" v-model="model"
@change="$emit('change', $event)"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false">
@change="handleChange">
</span> </span>
<span class="el-checkbox__label" v-if="$slots.default || label"> <span class="el-checkbox__label" v-if="$slots.default || label">
<slot></slot> <slot></slot>
@ -48,6 +47,34 @@
mixins: [Emitter], 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: { props: {
value: {}, value: {},
label: String, label: String,
@ -59,59 +86,30 @@
falseLabel: [String, Number] 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() { data() {
return { return {
focus: false, store: [],
wrapInGroup: this.$parent.$options.componentName === 'ElCheckboxGroup' 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: { methods: {
handleChange(ev) { addToStore() {
this.$emit('change', ev); if (Array.isArray(this.model)) {
this.model.indexOf(this.label) === -1 && this.model.push(this.label);
} else {
this.model = this.trueLabel || true;
} }
} }
},
created() {
this.checked && this.addToStore();
this.$on('initData', data => {
this.store = data;
this.isGroup = true;
this.checked && this.addToStore();
});
}
}; };
</script> </script>

View File

@ -4,7 +4,7 @@
export default { export default {
name: 'ElRadioGroup', name: 'ElRadioGroup',
componentName: 'radio-group', componentName: 'ElRadioGroup',
mixins: [Emitter], mixins: [Emitter],
@ -15,8 +15,12 @@
watch: { watch: {
value(value) { value(value) {
this.$emit('change', value); this.$emit('change', value);
this.broadcast('ElRadio', 'initData', value);
this.dispatch('form-item', 'el.form.change', [this.value]); this.dispatch('form-item', 'el.form.change', [this.value]);
} }
},
mounted() {
this.broadcast('ElRadio', 'initData', this.value);
} }
}; };
</script> </script>

View File

@ -4,14 +4,14 @@
<span class="el-radio__inner" <span class="el-radio__inner"
:class="{ :class="{
'is-disabled': disabled, 'is-disabled': disabled,
'is-checked': _value === label, 'is-checked': store === label,
'is-focus': focus 'is-focus': focus
}"></span> }"></span>
<input <input
class="el-radio__original" class="el-radio__original"
:value="label" :value="label"
type="radio" type="radio"
v-model="_value" v-model="store"
@focus="focus = true" @focus="focus = true"
@blur="focus = false" @blur="focus = false"
:name="name" :name="name"
@ -24,9 +24,15 @@
</label> </label>
</template> </template>
<script> <script>
import Emitter from 'element-ui/src/mixins/emitter';
export default { export default {
name: 'ElRadio', name: 'ElRadio',
mixins: [Emitter],
componentName: 'ElRadio',
props: { props: {
value: [String, Number], value: [String, Number],
label: { label: {
@ -36,24 +42,34 @@
disabled: Boolean, disabled: Boolean,
name: String name: String
}, },
data() { data() {
return { return {
focus: false focus: false,
isGroup: false,
store: this.value
}; };
}, },
computed: {
_value: { watch: {
get() { store(store) {
return this.value !== undefined ? this.value : this.$parent.value; if (this.isGroup) {
}, this.dispatch('ElRadioGroup', 'input', store);
set(newValue) {
if (this.value !== undefined) {
this.$emit('input', newValue);
} else { } else {
this.$parent.$emit('input', newValue); this.$emit('input', store);
}
} }
},
value(val) {
this.store = val;
} }
},
created() {
this.$on('initData', data => {
this.store = data;
this.isGroup = true;
});
} }
}; };
</script> </script>

View File

@ -40,6 +40,7 @@
<script type="text/jsx"> <script type="text/jsx">
import CollapseTransition from './transition'; import CollapseTransition from './transition';
import ElCheckbox from 'element-ui/packages/checkbox'
export default { export default {
name: 'el-tree-node', name: 'el-tree-node',
@ -55,6 +56,7 @@
}, },
components: { components: {
ElCheckbox,
CollapseTransition, CollapseTransition,
NodeContent: { NodeContent: {
props: { props: {

View File

@ -5,7 +5,7 @@ function broadcast(componentName, eventName, params) {
if (name === componentName) { if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params)); child.$emit.apply(child, [eventName].concat(params));
} else { } else {
broadcast.apply(child, [componentName, eventName].concat(params)); broadcast.apply(child, [componentName, eventName].concat([params]));
} }
}); });
} }

View File

@ -67,6 +67,33 @@ describe('Checkbox', () => {
done(); done();
}); });
}); });
it('nested group', done => {
vm = createVue({
template: `
<el-checkbox-group v-model="checkList">
<el-row>
<el-checkbox label="a" ref="a"></el-checkbox>
<el-checkbox label="b" ref="b"></el-checkbox>
<el-checkbox label="c" ref="c"></el-checkbox>
<el-checkbox label="d" ref="d"></el-checkbox>
</el-row>
</el-checkbox-group>
`,
data() {
return {
checkList: []
};
}
}, true);
expect(vm.checkList.length === 0).to.be.true;
vm.$refs.a.$el.click();
vm.$nextTick(_ => {
expect(vm.checkList.indexOf('a') !== -1).to.be.true;
done();
});
});
it('true false label', done => { it('true false label', done => {
vm = createVue({ vm = createVue({
template: ` template: `

View File

@ -65,6 +65,7 @@ describe('Radio', () => {
}; };
} }
}, true); }, true);
setTimeout(_ => {
expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok; expect(vm.$refs.radio1.$el.querySelector('.is-checked')).to.be.ok;
let radioElm = vm.$refs.radio2.$el; let radioElm = vm.$refs.radio2.$el;
radioElm.click(); radioElm.click();
@ -73,6 +74,7 @@ describe('Radio', () => {
expect(vm.radio === 6).to.be.true; expect(vm.radio === 6).to.be.true;
done(); done();
}); });
}, 50);
}); });
it('radio button', done => { it('radio button', done => {
vm = createVue({ vm = createVue({