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 | 1 | <template> |
| 2 | 2 | <div :class="wrapClasses"> |
| 3 | 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 | 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 | 9 | <input |
| 8 | 10 | :type="type" |
| 9 | 11 | :class="inputClasses" |
| ... | ... | @@ -12,17 +14,17 @@ |
| 12 | 14 | :maxlength="maxlength" |
| 13 | 15 | :readonly="readonly" |
| 14 | 16 | :name="name" |
| 15 | - v-model="value" | |
| 17 | + :value="currentValue" | |
| 16 | 18 | :number="number" |
| 17 | 19 | @keyup.enter="handleEnter" |
| 18 | 20 | @focus="handleFocus" |
| 19 | 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 | 24 | </template> |
| 23 | 25 | <textarea |
| 24 | 26 | v-else |
| 25 | - v-el:textarea | |
| 27 | + ref="textarea" | |
| 26 | 28 | :class="textareaClasses" |
| 27 | 29 | :style="textareaStyles" |
| 28 | 30 | :placeholder="placeholder" |
| ... | ... | @@ -31,11 +33,11 @@ |
| 31 | 33 | :maxlength="maxlength" |
| 32 | 34 | :readonly="readonly" |
| 33 | 35 | :name="name" |
| 34 | - v-model="value" | |
| 36 | + :value="value" | |
| 35 | 37 | @keyup.enter="handleEnter" |
| 36 | 38 | @focus="handleFocus" |
| 37 | 39 | @blur="handleBlur" |
| 38 | - @change="handleChange"> | |
| 40 | + @input="handleInput"> | |
| 39 | 41 | </textarea> |
| 40 | 42 | </div> |
| 41 | 43 | </template> |
| ... | ... | @@ -55,8 +57,7 @@ |
| 55 | 57 | }, |
| 56 | 58 | value: { |
| 57 | 59 | type: [String, Number], |
| 58 | - default: '', | |
| 59 | -// twoWay: true | |
| 60 | + default: '' | |
| 60 | 61 | }, |
| 61 | 62 | size: { |
| 62 | 63 | validator (value) { |
| ... | ... | @@ -97,6 +98,7 @@ |
| 97 | 98 | }, |
| 98 | 99 | data () { |
| 99 | 100 | return { |
| 101 | + currentValue: this.value, | |
| 100 | 102 | prefixCls: prefixCls, |
| 101 | 103 | prepend: true, |
| 102 | 104 | append: true, |
| ... | ... | @@ -146,11 +148,24 @@ |
| 146 | 148 | }, |
| 147 | 149 | handleBlur () { |
| 148 | 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 | 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 | 169 | resizeTextarea () { |
| 155 | 170 | const autosize = this.autosize; |
| 156 | 171 | if (!autosize || this.type !== 'textarea') { |
| ... | ... | @@ -160,30 +175,24 @@ |
| 160 | 175 | const minRows = autosize.minRows; |
| 161 | 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 | 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 | 198 | </script> | ... | ... |
src/index.js
| ... | ... | @@ -17,7 +17,7 @@ import Button from './components/button'; |
| 17 | 17 | // import Dropdown from './components/dropdown'; |
| 18 | 18 | // import Form from './components/form'; |
| 19 | 19 | import Icon from './components/icon'; |
| 20 | -// import Input from './components/input'; | |
| 20 | +import Input from './components/input'; | |
| 21 | 21 | // import InputNumber from './components/input-number'; |
| 22 | 22 | // import LoadingBar from './components/loading-bar'; |
| 23 | 23 | // import Menu from './components/menu'; |
| ... | ... | @@ -73,6 +73,7 @@ const iview = { |
| 73 | 73 | // Collapse, |
| 74 | 74 | Icon, |
| 75 | 75 | // iInput: Input, |
| 76 | + Input, | |
| 76 | 77 | // InputNumber, |
| 77 | 78 | // LoadingBar, |
| 78 | 79 | // Menu, | ... | ... |
test/app.vue
| ... | ... | @@ -27,6 +27,7 @@ li + li { |
| 27 | 27 | <li><router-link to="/affix">Affix</router-link></li> |
| 28 | 28 | <li><router-link to="/grid">Grid</router-link></li> |
| 29 | 29 | <li><router-link to="/button">Button</router-link></li> |
| 30 | + <li><router-link to="/input">Input</router-link></li> | |
| 30 | 31 | </ul> |
| 31 | 32 | </nav> |
| 32 | 33 | <router-view></router-view> | ... | ... |
test/main.js
test/routers/input.vue
| 1 | 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 | 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 | 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 | 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 | 17 | </div> |
| 83 | 18 | </template> |
| 84 | 19 | <script> |
| 85 | - import { iInput, Icon, iButton, iSelect, iOption, InputNumber } from 'iview'; | |
| 86 | - | |
| 87 | 20 | export default { |
| 88 | - components: { | |
| 89 | - iInput, | |
| 90 | - Icon, | |
| 91 | - iButton, | |
| 92 | - iSelect, | |
| 93 | - iOption, | |
| 94 | - InputNumber | |
| 95 | - }, | |
| 96 | - props: { | |
| 97 | - | |
| 98 | - }, | |
| 99 | 21 | data () { |
| 100 | 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 | 27 | \ No newline at end of file |
| 28 | +</script> | ... | ... |