Vue.js로 수동으로 만든 RangeSlider
15746 단어 JavaScriptVue.js
완성
나는 그것을 해 보았다.
왜 하고 싶으세요?
나는 평소에 리액션을 쓴다.React도 Component 이외의 마우스 조작으로 화면을 업데이트하고 싶을 때가 있다.이 경우 바디 등
addEventListener
의 이벤트 설정에 대해ref
DOM에서left와width를 받아state를 업데이트합니다.Vue.제이스에서는 어떤 느낌일까요?
이루어지다
<template>
<div class="range_slider" :style="{width: width + 'px'}">
<div class="range_wrapper" ref="range" @mousedown="mousedown">
<div class="range" :style="{'background-color': color}"></div>
</div>
<div class="circle" :style="circleStyle" @mousedown="mousedown"></div>
</div>
</template>
<script>
export default {
name: 'RangeSlider',
props: {
color: {type: String, default: '#eee'},
width: {type: Number, default: 200},
value: {type: Number, default: 0},
max: {type: Number, default: 100},
min: {type: Number, default: 0}
},
data () {
return {
isMoving: false
}
},
methods: {
moveCircle (e) {
const width = this.$refs.range.getBoundingClientRect().width
const rangeLeft = this.$refs.range.getBoundingClientRect().left
const eventLeft = e.clientX
const left = eventLeft - rangeLeft
if (left <= 0) {
this.$emit('update:value', this.min)
}
if (width <= left) {
this.$emit('update:value', this.max)
}
if (left >= 0 && left <= width) {
const ratio = left / width
const value = (this.max - this.min) * ratio + this.min
this.$emit('update:value', Math.round(value))
}
},
mousedown (e) {
this.isMoving = true
this.moveCircle(e)
// mousedownしたタイミングでマウス操作に対するイベントを設定
document.body.addEventListener('mousemove', this.mousemove)
document.body.addEventListener('mouseup', this.mouseup)
},
mousemove (e) {
if (this.isMoving) {
this.moveCircle(e)
}
},
mouseup () {
this.isMoving = false
// ドラッグ操作が終わったタイミングでイベントを削除
document.body.removeEventListener('mousemove', this.mousemove)
document.body.removeEventListener('mouseup', this.mouseup)
}
},
computed: {
circleStyle () {
const ratio = (this.value - this.min) / (this.max - this.min)
const left = this.width * ratio
return {
left: `${left - 10}px`
}
}
}
}
</script>
<style scoped>
.range_slider {
height: 20px;
margin: 0 auto;
position: relative;
display: inline-block;
}
.range_wrapper {
position: relative;
height: 100%;
width: 100%;
}
.range {
height: 4px;
width: 100%;
background-color: #eee;
position: absolute;
top: calc(50% - 2px);
border-radius: 3px;
}
.circle {
width: 0;
height: 0;
top: 0;
border: 10px solid #DDD;
border-radius: 50%;
position: absolute;
}
</style>
보태다
리액트와 다른 점은 사용
this.$refs
이라는 점인가.리액트에서도 this.refs
얻는 방법이 있다고 생각하지만 리액트에서는 추천하지 않을 거예요.여기까지 이룬 아이디어는 HTML5를 사용하는 input의 range도 이런 점을 이룰 수 있을지도 모른다는 것이다.만약 위에 input의range보다 동그란 원을 덮어 이렇게 실현한다면 마우스 조작에 신경 쓸 필요가 없을 수도 있다.
Reference
이 문제에 관하여(Vue.js로 수동으로 만든 RangeSlider), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/shikazuki/items/f035167df64f74036856텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)