Vue.js를 실험 중이며 일부 하위 구성 요소가있는 상위 구성 요소가 있습니다. 내가 할 수있는 것은 "클릭 및 드래그"되는 구성 요소를 추적하는 것입니다.
지금까지 내가 가진 것은 사용자가 mousedown
부모 구성 요소 에서 이벤트를 시작 mouseover
하여 자식 구성 요소 의 리스너 를 조건부로 활성화하여 어떤 자식 구성 요소가 이동되는지 추적하는 것입니다. 사용자가 마우스 버튼을 놓으면 mouseover
리스너가 제거됩니다.
이 메서드를 사용하여 이벤트 리스너를 조건부로 추가 할 수있었습니다 . 문제는 초기 mousedown
이벤트가 실행될 때 하위 구성 요소가 mouseover
이벤트를 트리거 하지 않으므로 추적되지 않으며 mouseover
하위 구성 요소에 대한 후속은 다음 과 같이 추적됩니다. 예상됩니다. 또한 "클릭 앤 드래그"를 시작할 때 마우스가 놓인 하위 구성 요소를 추적 할 수 있기를 원합니다.
이 문제를 해결하려면, 나는 점점 오전 event.target.__vue__
의 mousedown
하위 구성 요소에 액세스 명시 적으로 추적 방법을 호출하는 이벤트를. (예제에서 App.vue의 25 행)
내 질문은 : 사용하는 것 외에 mousedown
부모에서 발생 하는 이니셜 아래에있는 자식 구성 요소에서 추적 메서드를 트리거하는 더 Vue.js 적절한 방법이 event.target.__vue__
있습니까? 또는 일반적으로 "클릭 및 드래그"되는 하위 구성 요소를 추적하는 더 좋은 방법이 있습니까?
부모 구성 요소와 자식 구성 요소가 강한 관계가있는 경우 (예 : 자식 구성 요소가 부모 구성 요소 내에 배치되어야 함) Vue provide & inject 를 시도하고 싶을 것입니다 .
부모 구성 요소는 자식이 트랙을 등록한 다음을 사용 provide
하여 (데모 아래에서 this
키워드로 인스턴스를 전달 ) 자식 에게 전달할 수있는 한 가지 방법을 제공합니다 .
각 하위 구성 요소는 해당 메서드를 호출하여 상위에 트랙을 업로드하기 만하면됩니다.
그러나 제공 / 주입의 경우 다음 사항에주의하십시오.
참고 : 제공 및 삽입 바인딩은 반응이 없습니다. 이것은 의도적 인 것입니다. 그러나 관찰 된 객체를 전달하면 해당 객체의 속성은 계속 반응합니다.
다음은 간단한 데모입니다 .
Vue.config.productionTip = false
Vue.component('so-parent', {
provide() {
return {
_tracker: this
}
},
template: `
<div @mousedown="toggleTrack(true)" @mouseup="toggleTrack(false)"><h3>children count: {{children.length}} - tracking: {{trackState}}</h3><h3>{{tracks}}</h3><slot></slot></div>
`,
data() {
return {
children: [],
tracks: [],
trackState: false
}
},
methods: {
_registerChild(child) {
this.children.push(child)
},
_registerTracks(track) {
if (this.trackState) this.tracks.push(track)
},
toggleTrack: function(state) {
this.trackState = state
if(!this.trackState) {
this.tracks = []
}
}
}
})
Vue.component('so-child', {
inject: {
_tracker: {
default () {
console.error('so-child must be child of so-parent')
}
}
},
data() {
return {
childState: false,
childSeq: 0
}
},
props: ['cid'],
render(h) {
return h('div', {
class: 'child',
on: {
mouseover: () => this._tracker._registerTracks(this.cid)
}
}, [this.childSeq + ' Child Component ' + this.cid, this.$slots.default])
},
mounted() {
this.childSeq = this._tracker.children.length
this._tracker._registerChild(this)
}
})
new Vue({
el: '#app'
})
div.child {
border: 1px solid;
display: inline-block;
padding: .5em 1em;
margin: 0 0.5em 1em;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&:hover {
background: #b2bde3;
cursor: pointer;
color: white;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<so-parent>
<so-child cid="A"></so-child>
<so-child cid="B"></so-child>
<so-child cid="C"></so-child>
<so-child cid="D"></so-child>
</so-parent>
</div>
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다