Commit cbe03a12b2f4a79311b6e7a95d13811ae3a41a92
1 parent
06322514
support Checkbox
support Checkbox
Showing
10 changed files
with
146 additions
and
29 deletions
Show diff stats
CHANGE.md
@@ -4,3 +4,7 @@ | @@ -4,3 +4,7 @@ | ||
4 | 使用 v-model | 4 | 使用 v-model |
5 | ### Radio | 5 | ### Radio |
6 | value 改为了 label,使用 v-model,废弃 checked | 6 | value 改为了 label,使用 v-model,废弃 checked |
7 | +### Checkbox | ||
8 | +使用 v-model | ||
9 | +### CheckboxGroup | ||
10 | +value 改为了 label,使用 v-model,废弃 checked | ||
7 | \ No newline at end of file | 11 | \ No newline at end of file |
README.md
src/components/checkbox/checkbox-group.vue
@@ -9,42 +9,49 @@ | @@ -9,42 +9,49 @@ | ||
9 | export default { | 9 | export default { |
10 | name: 'checkboxGroup', | 10 | name: 'checkboxGroup', |
11 | props: { | 11 | props: { |
12 | - model: { | 12 | + value: { |
13 | type: Array, | 13 | type: Array, |
14 | default () { | 14 | default () { |
15 | return []; | 15 | return []; |
16 | } | 16 | } |
17 | } | 17 | } |
18 | }, | 18 | }, |
19 | + data () { | ||
20 | + return { | ||
21 | + currentValue: this.value | ||
22 | + }; | ||
23 | + }, | ||
19 | computed: { | 24 | computed: { |
20 | classes () { | 25 | classes () { |
21 | return `${prefixCls}`; | 26 | return `${prefixCls}`; |
22 | } | 27 | } |
23 | }, | 28 | }, |
24 | - compiled () { | 29 | + mounted () { |
25 | this.updateModel(true); | 30 | this.updateModel(true); |
26 | }, | 31 | }, |
27 | methods: { | 32 | methods: { |
28 | updateModel (update) { | 33 | updateModel (update) { |
29 | - const model = this.model; | 34 | + const value = this.value; |
30 | 35 | ||
31 | this.$children.forEach((child) => { | 36 | this.$children.forEach((child) => { |
32 | - child.model = model; | 37 | + child.model = value; |
33 | 38 | ||
34 | if (update) { | 39 | if (update) { |
35 | - child.selected = model.indexOf(child.value) >= 0; | 40 | + child.currentValue = value.indexOf(child.label) >= 0; |
36 | child.group = true; | 41 | child.group = true; |
37 | } | 42 | } |
38 | }); | 43 | }); |
39 | }, | 44 | }, |
40 | change (data) { | 45 | change (data) { |
41 | - this.model = data; | 46 | + this.currentValue = data; |
47 | + this.$emit('input', data); | ||
42 | this.$emit('on-change', data); | 48 | this.$emit('on-change', data); |
43 | - this.$dispatch('on-form-change', data); | 49 | + // todo 事件 |
50 | +// this.$dispatch('on-form-change', data); | ||
44 | } | 51 | } |
45 | }, | 52 | }, |
46 | watch: { | 53 | watch: { |
47 | - model () { | 54 | + value () { |
48 | this.updateModel(true); | 55 | this.updateModel(true); |
49 | } | 56 | } |
50 | } | 57 | } |
src/components/checkbox/checkbox.vue
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | type="checkbox" | 7 | type="checkbox" |
8 | :class="inputClasses" | 8 | :class="inputClasses" |
9 | :disabled="disabled" | 9 | :disabled="disabled" |
10 | - :value="value" | 10 | + :value="label" |
11 | v-model="model" | 11 | v-model="model" |
12 | @change="change"> | 12 | @change="change"> |
13 | <input | 13 | <input |
@@ -15,28 +15,29 @@ | @@ -15,28 +15,29 @@ | ||
15 | type="checkbox" | 15 | type="checkbox" |
16 | :class="inputClasses" | 16 | :class="inputClasses" |
17 | :disabled="disabled" | 17 | :disabled="disabled" |
18 | - v-model="checked" | 18 | + :checked="currentValue" |
19 | @change="change"> | 19 | @change="change"> |
20 | </span> | 20 | </span> |
21 | - <slot v-if="showSlot"><span v-el:slot>{{ value }}</span></slot> | 21 | + <slot v-if="showSlot"><span ref="slot">{{ label }}</span></slot> |
22 | </label> | 22 | </label> |
23 | </template> | 23 | </template> |
24 | <script> | 24 | <script> |
25 | const prefixCls = 'ivu-checkbox'; | 25 | const prefixCls = 'ivu-checkbox'; |
26 | 26 | ||
27 | export default { | 27 | export default { |
28 | + name: 'Checkbox', | ||
28 | props: { | 29 | props: { |
29 | disabled: { | 30 | disabled: { |
30 | type: Boolean, | 31 | type: Boolean, |
31 | default: false | 32 | default: false |
32 | }, | 33 | }, |
33 | value: { | 34 | value: { |
34 | - type: [String, Number, Boolean] | ||
35 | - }, | ||
36 | - checked: { | ||
37 | type: Boolean, | 35 | type: Boolean, |
38 | default: false | 36 | default: false |
39 | }, | 37 | }, |
38 | + label: { | ||
39 | + type: [String, Number, Boolean] | ||
40 | + }, | ||
40 | indeterminate: { | 41 | indeterminate: { |
41 | type: Boolean, | 42 | type: Boolean, |
42 | default: false | 43 | default: false |
@@ -45,7 +46,7 @@ | @@ -45,7 +46,7 @@ | ||
45 | data () { | 46 | data () { |
46 | return { | 47 | return { |
47 | model: [], | 48 | model: [], |
48 | - selected: false, | 49 | + currentValue: this.value, |
49 | group: false, | 50 | group: false, |
50 | showSlot: true | 51 | showSlot: true |
51 | }; | 52 | }; |
@@ -56,7 +57,7 @@ | @@ -56,7 +57,7 @@ | ||
56 | `${prefixCls}-wrapper`, | 57 | `${prefixCls}-wrapper`, |
57 | { | 58 | { |
58 | [`${prefixCls}-group-item`]: this.group, | 59 | [`${prefixCls}-group-item`]: this.group, |
59 | - [`${prefixCls}-wrapper-checked`]: this.selected, | 60 | + [`${prefixCls}-wrapper-checked`]: this.currentValue, |
60 | [`${prefixCls}-wrapper-disabled`]: this.disabled | 61 | [`${prefixCls}-wrapper-disabled`]: this.disabled |
61 | } | 62 | } |
62 | ]; | 63 | ]; |
@@ -65,7 +66,7 @@ | @@ -65,7 +66,7 @@ | ||
65 | return [ | 66 | return [ |
66 | `${prefixCls}`, | 67 | `${prefixCls}`, |
67 | { | 68 | { |
68 | - [`${prefixCls}-checked`]: this.selected, | 69 | + [`${prefixCls}-checked`]: this.currentValue, |
69 | [`${prefixCls}-disabled`]: this.disabled, | 70 | [`${prefixCls}-disabled`]: this.disabled, |
70 | [`${prefixCls}-indeterminate`]: this.indeterminate | 71 | [`${prefixCls}-indeterminate`]: this.indeterminate |
71 | } | 72 | } |
@@ -78,11 +79,12 @@ | @@ -78,11 +79,12 @@ | ||
78 | return `${prefixCls}-input`; | 79 | return `${prefixCls}-input`; |
79 | } | 80 | } |
80 | }, | 81 | }, |
81 | - ready () { | 82 | + mounted () { |
83 | + // todo 使用 while向上查找 | ||
82 | if (this.$parent && this.$parent.$options.name === 'checkboxGroup') this.group = true; | 84 | if (this.$parent && this.$parent.$options.name === 'checkboxGroup') this.group = true; |
83 | if (!this.group) { | 85 | if (!this.group) { |
84 | this.updateModel(); | 86 | this.updateModel(); |
85 | - if (this.$els.slot && this.$els.slot.innerHTML === '') { | 87 | + if (this.$refs.slot && this.$refs.slot.innerHTML === '') { |
86 | this.showSlot = false; | 88 | this.showSlot = false; |
87 | } | 89 | } |
88 | } | 90 | } |
@@ -93,21 +95,24 @@ | @@ -93,21 +95,24 @@ | ||
93 | return false; | 95 | return false; |
94 | } | 96 | } |
95 | 97 | ||
96 | - this.selected = event.target.checked; | 98 | + const checked = event.target.checked; |
99 | + this.currentValue = checked; | ||
100 | + this.$emit('input', checked); | ||
97 | 101 | ||
98 | if (this.group) { | 102 | if (this.group) { |
99 | this.$parent.change(this.model); | 103 | this.$parent.change(this.model); |
100 | } else { | 104 | } else { |
101 | - this.$emit('on-change', this.checked); | ||
102 | - this.$dispatch('on-form-change', this.checked); | 105 | + this.$emit('on-change', checked); |
106 | + // todo 事件 | ||
107 | +// this.$dispatch('on-form-change', checked); | ||
103 | } | 108 | } |
104 | }, | 109 | }, |
105 | updateModel () { | 110 | updateModel () { |
106 | - this.selected = this.checked; | 111 | + this.currentValue = this.value; |
107 | } | 112 | } |
108 | }, | 113 | }, |
109 | watch: { | 114 | watch: { |
110 | - checked () { | 115 | + value () { |
111 | this.updateModel(); | 116 | this.updateModel(); |
112 | } | 117 | } |
113 | } | 118 | } |
src/components/radio/radio-group.vue
src/components/radio/radio.vue
@@ -63,6 +63,7 @@ | @@ -63,6 +63,7 @@ | ||
63 | } | 63 | } |
64 | }, | 64 | }, |
65 | mounted () { | 65 | mounted () { |
66 | + // todo 使用 while向上查找 | ||
66 | if (this.$parent && this.$parent.$options.name === 'radioGroup') this.group = true; | 67 | if (this.$parent && this.$parent.$options.name === 'radioGroup') this.group = true; |
67 | if (!this.group) { | 68 | if (!this.group) { |
68 | this.updateValue(); | 69 | this.updateValue(); |
src/index.js
@@ -10,7 +10,7 @@ import Button from './components/button'; | @@ -10,7 +10,7 @@ import Button from './components/button'; | ||
10 | // import Card from './components/card'; | 10 | // import Card from './components/card'; |
11 | // import Carousel from './components/carousel'; | 11 | // import Carousel from './components/carousel'; |
12 | // import Cascader from './components/cascader'; | 12 | // import Cascader from './components/cascader'; |
13 | -// import Checkbox from './components/checkbox'; | 13 | +import Checkbox from './components/checkbox'; |
14 | // import Circle from './components/circle'; | 14 | // import Circle from './components/circle'; |
15 | // import Collapse from './components/collapse'; | 15 | // import Collapse from './components/collapse'; |
16 | // import DatePicker from './components/date-picker'; | 16 | // import DatePicker from './components/date-picker'; |
@@ -60,8 +60,8 @@ const iview = { | @@ -60,8 +60,8 @@ const iview = { | ||
60 | // Carousel, | 60 | // Carousel, |
61 | // CarouselItem: Carousel.Item, | 61 | // CarouselItem: Carousel.Item, |
62 | // Cascader, | 62 | // Cascader, |
63 | - // Checkbox, | ||
64 | - // CheckboxGroup: Checkbox.Group, | 63 | + Checkbox, |
64 | + CheckboxGroup: Checkbox.Group, | ||
65 | // Circle, | 65 | // Circle, |
66 | // DatePicker, | 66 | // DatePicker, |
67 | // Dropdown, | 67 | // Dropdown, |
test/app.vue
@@ -29,6 +29,7 @@ li + li { | @@ -29,6 +29,7 @@ li + li { | ||
29 | <li><router-link to="/button">Button</router-link></li> | 29 | <li><router-link to="/button">Button</router-link></li> |
30 | <li><router-link to="/input">Input</router-link></li> | 30 | <li><router-link to="/input">Input</router-link></li> |
31 | <li><router-link to="/radio">Radio</router-link></li> | 31 | <li><router-link to="/radio">Radio</router-link></li> |
32 | + <li><router-link to="/checkbox">Checkbox</router-link></li> | ||
32 | </ul> | 33 | </ul> |
33 | </nav> | 34 | </nav> |
34 | <router-view></router-view> | 35 | <router-view></router-view> |
test/main.js
@@ -36,6 +36,10 @@ const router = new VueRouter({ | @@ -36,6 +36,10 @@ const router = new VueRouter({ | ||
36 | { | 36 | { |
37 | path: '/radio', | 37 | path: '/radio', |
38 | component: require('./routers/radio.vue') | 38 | component: require('./routers/radio.vue') |
39 | + }, | ||
40 | + { | ||
41 | + path: '/checkbox', | ||
42 | + component: require('./routers/checkbox.vue') | ||
39 | } | 43 | } |
40 | ] | 44 | ] |
41 | }); | 45 | }); |
1 | +<template> | ||
2 | + <div> | ||
3 | + <Checkbox v-model="single" @on-change="s">Checkbox</Checkbox> | ||
4 | + {{ single }} | ||
5 | + <div @click="single = !single">single-change</div> | ||
6 | + <br> | ||
7 | + {{ social }} | ||
8 | + <Checkbox-group v-model="social" @on-change="s"> | ||
9 | + <Checkbox label="twitter"> | ||
10 | + <Icon type="social-twitter"></Icon> | ||
11 | + <span>Twitter</span> | ||
12 | + </Checkbox> | ||
13 | + <Checkbox label="facebook"> | ||
14 | + <Icon type="social-facebook"></Icon> | ||
15 | + <span>Facebook</span> | ||
16 | + </Checkbox> | ||
17 | + <Checkbox label="github"> | ||
18 | + <Icon type="social-github"></Icon> | ||
19 | + <span>Github</span> | ||
20 | + </Checkbox> | ||
21 | + <Checkbox label="snapchat"> | ||
22 | + <Icon type="social-snapchat"></Icon> | ||
23 | + <span>Snapchat</span> | ||
24 | + </Checkbox> | ||
25 | + </Checkbox-group> | ||
26 | + <br> | ||
27 | + <div @click="c">修改1</div> | ||
28 | + {{ fruit }} | ||
29 | + <Checkbox-group v-model="fruit"> | ||
30 | + <Checkbox label="香蕉"></Checkbox> | ||
31 | + <Checkbox label="苹果"></Checkbox> | ||
32 | + <Checkbox label="西瓜"></Checkbox> | ||
33 | + </Checkbox-group> | ||
34 | + <br><br> | ||
35 | + <div style="border-bottom: 1px solid #e9e9e9;padding-bottom:6px;margin-bottom:6px;"> | ||
36 | + <Checkbox | ||
37 | + :indeterminate="indeterminate" | ||
38 | + v-model="checkAll" | ||
39 | + @click.prevent.native="handleCheckAll">全选</Checkbox> | ||
40 | + </div> | ||
41 | + <Checkbox-group v-model="checkAllGroup" @on-change="checkAllGroupChange"> | ||
42 | + <Checkbox label="香蕉"></Checkbox> | ||
43 | + <Checkbox label="苹果"></Checkbox> | ||
44 | + <Checkbox label="西瓜"></Checkbox> | ||
45 | + </Checkbox-group> | ||
46 | + </div> | ||
47 | +</template> | ||
48 | +<script> | ||
49 | + export default { | ||
50 | + data () { | ||
51 | + return { | ||
52 | + social: ['facebook', 'github'], | ||
53 | + fruit: ['苹果'], | ||
54 | + single: false, | ||
55 | + indeterminate: true, | ||
56 | + checkAll: false, | ||
57 | + checkAllGroup: ['香蕉', '西瓜'] | ||
58 | + } | ||
59 | + }, | ||
60 | + methods: { | ||
61 | + c () { | ||
62 | + this.social.splice(0, 1) | ||
63 | + }, | ||
64 | + s (d) { | ||
65 | + console.log(d) | ||
66 | + }, | ||
67 | + handleCheckAll () { | ||
68 | + if (this.indeterminate) { | ||
69 | + this.checkAll = false; | ||
70 | + } else { | ||
71 | + this.checkAll = !this.checkAll; | ||
72 | + } | ||
73 | + this.indeterminate = false; | ||
74 | + | ||
75 | + if (this.checkAll) { | ||
76 | + this.checkAllGroup = ['香蕉', '苹果', '西瓜']; | ||
77 | + } else { | ||
78 | + this.checkAllGroup = []; | ||
79 | + } | ||
80 | + }, | ||
81 | + checkAllGroupChange (data) { | ||
82 | + if (data.length === 3) { | ||
83 | + this.indeterminate = false; | ||
84 | + this.checkAll = true; | ||
85 | + } else if (data.length > 0) { | ||
86 | + this.indeterminate = true; | ||
87 | + this.checkAll = false; | ||
88 | + } else { | ||
89 | + this.indeterminate = false; | ||
90 | + this.checkAll = false; | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + } | ||
95 | +</script> |