Skip to content

Instantly share code, notes, and snippets.

@iamspark1e
Created November 30, 2023 08:03
Show Gist options
  • Save iamspark1e/429ad72e7a31ad664b313dc6ec13b7ae to your computer and use it in GitHub Desktop.
Save iamspark1e/429ad72e7a31ad664b313dc6ec13b7ae to your computer and use it in GitHub Desktop.
My custom vue components
<template>
<div class="demo">
<button type="button" @click="minus" :disabled="value <= min">-</button>
<label>
<span v-show="!focused">{{ value }}{{ unit }}</span>
<input
type="number"
pattern="[0-9]*"
ref="realInput"
v-model.number="value"
v-show="focused"
@blur="blurHandler"
@click="focusHandler"
:style="`width:${inputWidth || 50}px`"
/>
</label>
<button type="button" @click="add" :disabled="value >= max">+</button>
</div>
</template>
<script>
const notNull = (val) => val !== null;
export default {
name: "demo",
data() {
return {
value: 1,
// unit: "人",
// max: 99,
// min: 1,
// stepSize: 1,
focused: false,
};
},
props: {
unit: {
type: String,
default: "",
},
max: {
type: Number,
default: null,
},
min: {
type: Number,
default: null,
},
stepSize: {
type: Number,
default: 1,
},
inputWidth: {
type: Number,
},
},
model: {
prop: "value",
event: "change",
},
methods: {
minus() {
if (notNull(this.min) && this.value <= this.min) return;
this.value -= this.stepSize;
this.$emit("change", this.value);
},
add() {
if (notNull(this.max) && this.value >= this.max) return;
this.value += this.stepSize;
this.$emit("change", this.value);
},
focusHandler() {
this.focused = true;
this.$refs.realInput.focus();
},
blurHandler() {
this.focused = false;
if (notNull(this.max) && notNull(this.min) && this.value < this.min) {
this.value = this.min;
} else if (
notNull(this.max) &&
notNull(this.min) &&
this.value > this.max
) {
this.value = this.max;
}
this.$emit("change", this.value);
},
},
};
</script>
<style lang="css" scoped>
.demo button {
display: inline-block;
vertical-align: middle;
border: none;
text-decoration: none;
background: transparent;
text-align: center;
appearance: none;
}
.demo label {
text-align: center;
}
.demo label input {
display: inline-block;
vertical-align: middle;
padding: 0 4px;
min-width: 0;
border: none;
text-align: center;
}
.demo label span {
display: inline-block;
vertical-align: middle;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment