Commit fc7ef072167e0e8598c51b2fa1203def11606281
1 parent
d47ea998
support Input
support Input
Showing
6 changed files
with
62 additions
and
152 deletions
Show diff stats
README.md
src/components/input/input.vue
| 1 | <template> | 1 | <template> |
| 2 | <div :class="wrapClasses"> | 2 | <div :class="wrapClasses"> |
| 3 | <template v-if="type !== 'textarea'"> | 3 | <template v-if="type !== 'textarea'"> |
| 4 | - <div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-show="slotReady" v-el:prepend><slot name="prepend"></slot></div> | 4 | + <div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-show="slotReady" ref="prepend"><slot name="prepend"></slot></div> |
| 5 | <i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon']" v-if="icon" @click="handleIconClick"></i> | 5 | <i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon']" v-if="icon" @click="handleIconClick"></i> |
| 6 | - <i class="ivu-icon ivu-icon-load-c ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" v-else transition="fade"></i> | 6 | + <transition name="fade"> |
| 7 | + <i class="ivu-icon ivu-icon-load-c ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" v-if="!icon"></i> | ||
| 8 | + </transition> | ||
| 7 | <input | 9 | <input |
| 8 | :type="type" | 10 | :type="type" |
| 9 | :class="inputClasses" | 11 | :class="inputClasses" |
| @@ -12,17 +14,17 @@ | @@ -12,17 +14,17 @@ | ||
| 12 | :maxlength="maxlength" | 14 | :maxlength="maxlength" |
| 13 | :readonly="readonly" | 15 | :readonly="readonly" |
| 14 | :name="name" | 16 | :name="name" |
| 15 | - v-model="value" | 17 | + :value="currentValue" |
| 16 | :number="number" | 18 | :number="number" |
| 17 | @keyup.enter="handleEnter" | 19 | @keyup.enter="handleEnter" |
| 18 | @focus="handleFocus" | 20 | @focus="handleFocus" |
| 19 | @blur="handleBlur" | 21 | @blur="handleBlur" |
| 20 | - @change="handleChange"> | ||
| 21 | - <div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady" v-el:append><slot name="append"></slot></div> | 22 | + @input="handleInput"> |
| 23 | + <div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady" ref="append"><slot name="append"></slot></div> | ||
| 22 | </template> | 24 | </template> |
| 23 | <textarea | 25 | <textarea |
| 24 | v-else | 26 | v-else |
| 25 | - v-el:textarea | 27 | + ref="textarea" |
| 26 | :class="textareaClasses" | 28 | :class="textareaClasses" |
| 27 | :style="textareaStyles" | 29 | :style="textareaStyles" |
| 28 | :placeholder="placeholder" | 30 | :placeholder="placeholder" |
| @@ -31,11 +33,11 @@ | @@ -31,11 +33,11 @@ | ||
| 31 | :maxlength="maxlength" | 33 | :maxlength="maxlength" |
| 32 | :readonly="readonly" | 34 | :readonly="readonly" |
| 33 | :name="name" | 35 | :name="name" |
| 34 | - v-model="value" | 36 | + :value="value" |
| 35 | @keyup.enter="handleEnter" | 37 | @keyup.enter="handleEnter" |
| 36 | @focus="handleFocus" | 38 | @focus="handleFocus" |
| 37 | @blur="handleBlur" | 39 | @blur="handleBlur" |
| 38 | - @change="handleChange"> | 40 | + @input="handleInput"> |
| 39 | </textarea> | 41 | </textarea> |
| 40 | </div> | 42 | </div> |
| 41 | </template> | 43 | </template> |
| @@ -55,8 +57,7 @@ | @@ -55,8 +57,7 @@ | ||
| 55 | }, | 57 | }, |
| 56 | value: { | 58 | value: { |
| 57 | type: [String, Number], | 59 | type: [String, Number], |
| 58 | - default: '', | ||
| 59 | -// twoWay: true | 60 | + default: '' |
| 60 | }, | 61 | }, |
| 61 | size: { | 62 | size: { |
| 62 | validator (value) { | 63 | validator (value) { |
| @@ -97,6 +98,7 @@ | @@ -97,6 +98,7 @@ | ||
| 97 | }, | 98 | }, |
| 98 | data () { | 99 | data () { |
| 99 | return { | 100 | return { |
| 101 | + currentValue: this.value, | ||
| 100 | prefixCls: prefixCls, | 102 | prefixCls: prefixCls, |
| 101 | prepend: true, | 103 | prepend: true, |
| 102 | append: true, | 104 | append: true, |
| @@ -146,11 +148,24 @@ | @@ -146,11 +148,24 @@ | ||
| 146 | }, | 148 | }, |
| 147 | handleBlur () { | 149 | handleBlur () { |
| 148 | this.$emit('on-blur'); | 150 | this.$emit('on-blur'); |
| 149 | - this.$dispatch('on-form-blur', this.value); | 151 | + // todo 事件 |
| 152 | +// this.$dispatch('on-form-blur', this.currentValue); | ||
| 150 | }, | 153 | }, |
| 151 | - handleChange (event) { | 154 | + handleInput (event) { |
| 155 | + const value = event.target.value; | ||
| 156 | + this.$emit('input', value); | ||
| 157 | + this.setCurrentValue(value); | ||
| 152 | this.$emit('on-change', event); | 158 | this.$emit('on-change', event); |
| 153 | }, | 159 | }, |
| 160 | + setCurrentValue (value) { | ||
| 161 | + if (value === this.currentValue) return; | ||
| 162 | + this.$nextTick(() => { | ||
| 163 | + this.resizeTextarea(); | ||
| 164 | + }); | ||
| 165 | + this.currentValue = value; | ||
| 166 | + // todo 事件 | ||
| 167 | +// this.$dispatch('on-form-change', value); | ||
| 168 | + }, | ||
| 154 | resizeTextarea () { | 169 | resizeTextarea () { |
| 155 | const autosize = this.autosize; | 170 | const autosize = this.autosize; |
| 156 | if (!autosize || this.type !== 'textarea') { | 171 | if (!autosize || this.type !== 'textarea') { |
| @@ -160,30 +175,24 @@ | @@ -160,30 +175,24 @@ | ||
| 160 | const minRows = autosize.minRows; | 175 | const minRows = autosize.minRows; |
| 161 | const maxRows = autosize.maxRows; | 176 | const maxRows = autosize.maxRows; |
| 162 | 177 | ||
| 163 | - this.textareaStyles = calcTextareaHeight(this.$els.textarea, minRows, maxRows); | ||
| 164 | - }, | ||
| 165 | - init () { | ||
| 166 | - if (this.type !== 'textarea') { | ||
| 167 | - this.prepend = this.$els.prepend.innerHTML !== ''; | ||
| 168 | - this.append = this.$els.append.innerHTML !== ''; | ||
| 169 | - } else { | ||
| 170 | - this.prepend = false; | ||
| 171 | - this.append = false; | ||
| 172 | - } | ||
| 173 | - this.slotReady = true; | ||
| 174 | - this.resizeTextarea(); | 178 | + this.textareaStyles = calcTextareaHeight(this.$refs.textarea, minRows, maxRows); |
| 175 | } | 179 | } |
| 176 | }, | 180 | }, |
| 177 | watch: { | 181 | watch: { |
| 178 | - value () { | ||
| 179 | - this.$nextTick(() => { | ||
| 180 | - this.resizeTextarea(); | ||
| 181 | - }); | ||
| 182 | - this.$dispatch('on-form-change', this.value); | 182 | + value (val) { |
| 183 | + this.setCurrentValue(val); | ||
| 183 | } | 184 | } |
| 184 | }, | 185 | }, |
| 185 | - compiled () { | ||
| 186 | - this.$nextTick(() => this.init()); | 186 | + mounted () { |
| 187 | + if (this.type !== 'textarea') { | ||
| 188 | + this.prepend = this.$slots.prepend !== undefined; | ||
| 189 | + this.append = this.$slots.append !== undefined; | ||
| 190 | + } else { | ||
| 191 | + this.prepend = false; | ||
| 192 | + this.append = false; | ||
| 193 | + } | ||
| 194 | + this.slotReady = true; | ||
| 195 | + this.resizeTextarea(); | ||
| 187 | } | 196 | } |
| 188 | }; | 197 | }; |
| 189 | </script> | 198 | </script> |
src/index.js
| @@ -17,7 +17,7 @@ import Button from './components/button'; | @@ -17,7 +17,7 @@ import Button from './components/button'; | ||
| 17 | // import Dropdown from './components/dropdown'; | 17 | // import Dropdown from './components/dropdown'; |
| 18 | // import Form from './components/form'; | 18 | // import Form from './components/form'; |
| 19 | import Icon from './components/icon'; | 19 | import Icon from './components/icon'; |
| 20 | -// import Input from './components/input'; | 20 | +import Input from './components/input'; |
| 21 | // import InputNumber from './components/input-number'; | 21 | // import InputNumber from './components/input-number'; |
| 22 | // import LoadingBar from './components/loading-bar'; | 22 | // import LoadingBar from './components/loading-bar'; |
| 23 | // import Menu from './components/menu'; | 23 | // import Menu from './components/menu'; |
| @@ -73,6 +73,7 @@ const iview = { | @@ -73,6 +73,7 @@ const iview = { | ||
| 73 | // Collapse, | 73 | // Collapse, |
| 74 | Icon, | 74 | Icon, |
| 75 | // iInput: Input, | 75 | // iInput: Input, |
| 76 | + Input, | ||
| 76 | // InputNumber, | 77 | // InputNumber, |
| 77 | // LoadingBar, | 78 | // LoadingBar, |
| 78 | // Menu, | 79 | // Menu, |
test/app.vue
| @@ -27,6 +27,7 @@ li + li { | @@ -27,6 +27,7 @@ li + li { | ||
| 27 | <li><router-link to="/affix">Affix</router-link></li> | 27 | <li><router-link to="/affix">Affix</router-link></li> |
| 28 | <li><router-link to="/grid">Grid</router-link></li> | 28 | <li><router-link to="/grid">Grid</router-link></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 | </ul> | 31 | </ul> |
| 31 | </nav> | 32 | </nav> |
| 32 | <router-view></router-view> | 33 | <router-view></router-view> |
test/main.js
| @@ -28,6 +28,10 @@ const router = new VueRouter({ | @@ -28,6 +28,10 @@ const router = new VueRouter({ | ||
| 28 | { | 28 | { |
| 29 | path: '/button', | 29 | path: '/button', |
| 30 | component: require('./routers/button.vue') | 30 | component: require('./routers/button.vue') |
| 31 | + }, | ||
| 32 | + { | ||
| 33 | + path: '/input', | ||
| 34 | + component: require('./routers/input.vue') | ||
| 31 | } | 35 | } |
| 32 | ] | 36 | ] |
| 33 | }); | 37 | }); |
test/routers/input.vue
| 1 | <template> | 1 | <template> |
| 2 | - <Input-number :max="10" :min="1" :value="1"></Input-number> | ||
| 3 | - <br><br> | ||
| 4 | - <i-input type="textarea" :autosize="true" placeholder="请输入..."></i-input> | ||
| 5 | - <i-input type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入..."></i-input> | ||
| 6 | - <i-input name="a" icon="ios-clock-outline" @on-focus="focus" @on-blur="blur" readonly style="width:200px;" :value.sync="v" @on-enter="enter" @on-click="iconclick" size="large" placeholder="请输入"></i-input> | ||
| 7 | - <i-input icon="ios-clock-outline" style="width:200px;" :value.sync="v" @on-enter="enter" placeholder="请输入"></i-input> | ||
| 8 | - <i-input name="b" icon="ios-clock-outline" style="width:200px;" :value.sync="v" @on-enter="enter" size="small" placeholder="请输入"></i-input> | ||
| 9 | - <br> | ||
| 10 | - <br> | ||
| 11 | - <i-input style="width:200px;" :value.sync="v" @on-enter="enter" size="large" placeholder="请输入"></i-input> | ||
| 12 | - <i-input style="width:200px;" :value.sync="v" @on-enter="enter" placeholder="请输入"></i-input> | ||
| 13 | - <i-input style="width:200px;" :value.sync="v" @on-enter="enter" @on-change="change" size="small" placeholder="请输入"></i-input> | ||
| 14 | - {{ v }} | ||
| 15 | - <br> | ||
| 16 | - <br> | ||
| 17 | - <i-input readonly placeholder="this is something" style="width:200px;" :value.sync="t" type="textarea" :autosize="autosize"></i-input> | ||
| 18 | - {{ t }} | ||
| 19 | - <br> | ||
| 20 | - <br> | ||
| 21 | - <div style="width: 400px"> | ||
| 22 | - <i-input :value.sync="v" type="password"> | ||
| 23 | - <span slot="prepend">http://</span> | ||
| 24 | - <span slot="append"> | ||
| 25 | - <i-button icon="ios-search"></i-button> | ||
| 26 | - </span> | ||
| 27 | - </i-input> | 2 | + <div> |
| 3 | + <Input v-model="value" placeholder="请输入..." style="width: 300px" icon="ios-clock-outline"></Input> | ||
| 4 | + <input type="text" v-model="value"> | ||
| 5 | + {{ value }} | ||
| 6 | + <!--<Input v-model="value">--> | ||
| 7 | + <!--<span slot="prepend">http://</span>--> | ||
| 8 | + <!--<span slot="append">.com</span>--> | ||
| 9 | + <!--</Input>--> | ||
| 28 | <br> | 10 | <br> |
| 29 | - <i-input :value.sync="v"> | ||
| 30 | - <span slot="prepend">http://</span> | ||
| 31 | - <span slot="append"><Icon type="ios-search"></Icon></span> | ||
| 32 | - </i-input> | 11 | + <Input type="textarea" v-model="value" placeholder="请输入..."></Input> |
| 12 | + <Input type="textarea" v-model="value" :rows="4" placeholder="请输入..."></Input> | ||
| 33 | <br> | 13 | <br> |
| 34 | - <i-input :value.sync="v" size="small"> | ||
| 35 | - <span slot="prepend">http://</span> | ||
| 36 | - <span slot="append"><Icon type="ios-search"></Icon></span> | ||
| 37 | - </i-input> | ||
| 38 | - | ||
| 39 | <br> | 14 | <br> |
| 40 | - <i-input :value.sync="v" size="large"> | ||
| 41 | - <i-select :model.sync="select1" slot="prepend" style="width: 80px"> | ||
| 42 | - <i-option value="http">http://</i-option> | ||
| 43 | - <i-option value="https">https://</i-option> | ||
| 44 | - </i-select> | ||
| 45 | - <i-select :model.sync="select2" slot="append" style="width: 70px"> | ||
| 46 | - <i-option value="com">.com</i-option> | ||
| 47 | - <i-option value="cn">.cn</i-option> | ||
| 48 | - <i-option value="net">.net</i-option> | ||
| 49 | - <i-option value="io">.io</i-option> | ||
| 50 | - </i-select> | ||
| 51 | - </i-input> | ||
| 52 | - <br> | ||
| 53 | - <i-input :value.sync="v"> | ||
| 54 | - <i-select :model.sync="select1" slot="prepend" style="width: 80px"> | ||
| 55 | - <i-option value="http">http://</i-option> | ||
| 56 | - <i-option value="https">https://</i-option> | ||
| 57 | - </i-select> | ||
| 58 | - <i-select :model.sync="select2" slot="append" style="width: 70px"> | ||
| 59 | - <i-option value="com">.com</i-option> | ||
| 60 | - <i-option value="cn">.cn</i-option> | ||
| 61 | - <i-option value="net">.net</i-option> | ||
| 62 | - <i-option value="io">.io</i-option> | ||
| 63 | - </i-select> | ||
| 64 | - </i-input> | ||
| 65 | - <br> | ||
| 66 | - <i-input :value.sync="v" size="small"> | ||
| 67 | - <i-select :model.sync="select1" slot="prepend" style="width: 80px"> | ||
| 68 | - <i-option value="http">http://</i-option> | ||
| 69 | - <i-option value="https">https://</i-option> | ||
| 70 | - </i-select> | ||
| 71 | - <i-select :model.sync="select2" slot="append" style="width: 70px"> | ||
| 72 | - <i-option value="com">.com</i-option> | ||
| 73 | - <i-option value="cn">.cn</i-option> | ||
| 74 | - <i-option value="net">.net</i-option> | ||
| 75 | - <i-option value="io">.io</i-option> | ||
| 76 | - </i-select> | ||
| 77 | - </i-input> | ||
| 78 | - <Input-number :value="2" size="small"></Input-number> | ||
| 79 | - <Input-number :value="2"></Input-number> | ||
| 80 | - <Input-number :value="2" size="large"></Input-number> | ||
| 81 | - <i-input type="password"></i-input> | 15 | + <Input type="textarea" v-model="value" :autosize="true" placeholder="请输入..."></Input> |
| 16 | + <Input type="textarea" v-model="value" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入..."></Input> | ||
| 82 | </div> | 17 | </div> |
| 83 | </template> | 18 | </template> |
| 84 | <script> | 19 | <script> |
| 85 | - import { iInput, Icon, iButton, iSelect, iOption, InputNumber } from 'iview'; | ||
| 86 | - | ||
| 87 | export default { | 20 | export default { |
| 88 | - components: { | ||
| 89 | - iInput, | ||
| 90 | - Icon, | ||
| 91 | - iButton, | ||
| 92 | - iSelect, | ||
| 93 | - iOption, | ||
| 94 | - InputNumber | ||
| 95 | - }, | ||
| 96 | - props: { | ||
| 97 | - | ||
| 98 | - }, | ||
| 99 | data () { | 21 | data () { |
| 100 | return { | 22 | return { |
| 101 | - v: 'hello', | ||
| 102 | - t: '', | ||
| 103 | - autosize: { | ||
| 104 | - minRows: 2, | ||
| 105 | - maxRows: 5 | ||
| 106 | - }, | ||
| 107 | - select1: 'http', | ||
| 108 | - select2: 'com' | ||
| 109 | - } | ||
| 110 | - }, | ||
| 111 | - computed: { | ||
| 112 | - | ||
| 113 | - }, | ||
| 114 | - methods: { | ||
| 115 | - enter () { | ||
| 116 | - console.log(123) | ||
| 117 | - }, | ||
| 118 | - iconclick () { | ||
| 119 | - console.log('iconclicked') | ||
| 120 | - }, | ||
| 121 | - change (val) { | ||
| 122 | - console.log(val) | ||
| 123 | - }, | ||
| 124 | - focus () { | ||
| 125 | - this.$Message.info('focus'); | ||
| 126 | - }, | ||
| 127 | - blur () { | ||
| 128 | - this.$Message.info('blur'); | 23 | + value: '' |
| 129 | } | 24 | } |
| 130 | } | 25 | } |
| 131 | } | 26 | } |
| 132 | -</script> | ||
| 133 | \ No newline at end of file | 27 | \ No newline at end of file |
| 28 | +</script> |