
<template>
<div class="container">
<r-input
v-model="inputValue"
center
:disabled="disabled"
@change="handleChange"
>
<template v-slot:prepend>
<div @click="handleClick('decrease')" class="decrease" :class="{is_decrease_disbaled: decreaseDisabled }">-</div>
</template>
<template v-slot:append>
<div @click="handleClick('increase')" class="increase"
:class="{ is_increase_disbaled: increaseDisabled }">+</div>
</template>
</r-input>
</div>
</template>
<script>
export default {
name: 'input-number',
data(){
return {
}
},
props: {
value: {
type: [Number, String],
default: 0,
validator: (value) => {
return typeof(+value) === 'number'
}
},
step: {
type: Number,
default: 1,
},
max: {
type: Number,
},
min: {
type: Number
},
disabled: {
type: Boolean,
default: false,
},
precision: {
type: Number,
}
},
computed: {
inputValue: {
get(){
return this.value
},
set(value){
const _this = this
const rules = [
{validate(val){ return !_this.checkIsNumber(val) }, res: this.inputValue},
{validate(val){ return val > _this.max}, res: _this.max},
{validate(val){ return val < _this.min}, res: _this.min},
{validate(val){ return true}, res: value},
]
const _value = rules.find(item => item.validate(value)).res
this.precision ?
this.$emit('input', Number(_value).toFixed(this.precision))
: this.$emit('input', _value)
console.log('_value', _value);
console.log('inputValue', this.inputValue);
}
},
decreaseDisabled(){ return this.disabled || this.inputValue <= this.min },
increaseDisabled() { return this.disabled || this.inputValue >= this.max },
},
methods: {
handleClick(type) {
if(type === 'decrease') {
if(this.disabled) return
this.inputValue = Number(this.inputValue) - this.step
} else {
if (this.disabled) return
this.inputValue = Number(this.inputValue) + this.step
}
},
checkIsNumber(val) {
return !isNaN(val) && Object.prototype.toString.call(val) === '[object Number]'
},
handleChange(){
console.log('forceUpdate')
console.log(this.inputValue);
this.$forceUpdate()
}
}
}
</script>
<style lang="scss">
.container {
width: 300px;
margin: 0 auto;
}
.decrease,.increase {
width: 30px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.is_decrease_disbaled {
cursor: not-allowed;
}
.is_increase_disbaled {
cursor: not-allowed;
}
</style>
<template>
<div>
<input-number :value="initValue" @input="handle" :max="10" :min="1" disabled :precision="2"></input-number>
<input-number v-model="initValue" :precision="2" :step="0.2"></input-number>
{{ initValue }}
</div>
</template>
<script>
export default {
data (){
return {
initValue: 6,
}
},
methods: {
handle(value) {
console.log(value);
this.initValue = value
},
}
}
</script>
<template>
<div class="input-wrapper">
<template v-if="type === 'text'">
<div class="inline-block" :class="styleClass">
<div class="prepend" v-if="$slots.prepend" :class="equalHeight">
<slot name="prepend"></slot>
</div>
<div class="wrapper">
<input
:value="inputValue"
v-on="MyListeners"
v-bind="$attrs"
class="r-text"
:class="className"
:disabled="disabled"
/>
<span v-if="showClear"><r-icon name="qingkong" @click.native="clearContent"></r-icon></span>
</div>
<div class="append" v-if="$slots.append" :class="equalHeight">
<slot name="append"></slot>
</div>
</div>
</template>
<template v-else>
<textarea
:value="inputValue"
v-on="MyListeners"
v-bind="$attrs"
class="r-textarea"
:class="className"
:disabled="disabled"></textarea>
</template>
</div>
</template>
<script>
export default {
name: 'r-input',
props: {
value: {
type: [String, Number],
default: ''
},
type: {
type: String,
default: 'text',
validator(type) {
return ['text', 'textarea'].indexOf(type) > -1
}
},
size: {
type: String,
default: '',
validator (value) {
return ['', 'small', 'medium'].includes(value)
}
},
clearable: {
type: Boolean,
default: false,
},
center: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
}
},
computed: {
inputValue: {
get: function() {
return this.value
},
set (value) {
console.log(1111);
console.log('input', value);
this.$emit('input', value)
}
},
MyListeners() {
return Object.assign(this.$listeners, {
input: event => this.$emit("input", event.target.value)
});
},
className () {
return {
['r-input--' + this.size]: true,
'is-center': this.center
}
},
showClear() {
return this.clearable && this.inputValue !== ''
},
styleClass() {
return {
'has-append': this.$slots.append,
'has-prepend': this.$slots.prepend
}
},
equalHeight() {
return {
['r-input--' + this.size]: true,
}
}
},
methods: {
clearContent() {
this.inputValue = ''
}
},
mounted() {
}
}
</script>
<style lang="scss" scoped>
@import './style.scss'
</style>