Vue2. 4+ поведение компонента компиляции
Так что я недавно начал работать с Vue js. Я пытаюсь динамически добавлять и удалять узлы Vue. Это немного трудно описать проблему, поэтому я создал демо, чтобы проиллюстрировать ее.
Vue.component('context', {
data() {
return {
test: '<context></context>', //Dummy recursive data to illustrate issue
child: ''
}
},
methods: {
addChild() {
this.child = this.test
},
removeChild() {
this.child = ''
}
},
computed: {
dynamic() {
return Vue.compile(this.child)
},
style() {
return {
'background-color': '#' + randHex(6)
}
}
},
template: `
<div :style="style" @click="addChild" @click.shift="removeChild">
<component :is="dynamic"></component>
</div>
`
})
new Vue({
el: '#app'
})
function randHex(digits) {
let hex = Math.floor(Math.random() * Math.pow(16, digits)).toString(16)
return '0'.repeat(digits - hex.length) + hex
}
html,
body {
height: 100%;
overflow: hidden;
}
div {
width: 90%;
height: 90%;
}
<script src="https://unpkg.com/vue@2.4.3/dist/vue.js"></script>
<p>Click on the block to add, Shift-Click ro remove. Why does shift clicking always remove all inner blocks and not just the ones as children to the shift clicked block?</p>
<div id="app">
<context></context>
</div>
Выше вы увидите, что щелчок по цветным прямоугольникам добавляет внутреннего ребенка, как и было задумано. Однако, когда вы нажимаете на прямоугольник, он удаляет не только своих детей, но и всех детей! (Даже те, которые являются родителями для текущего узел.)
Первоначально я думал, что событие щелчка "истекает" к нижним элементам, однако я создал немного более сложный тест, который смещал положение элементов, чтобы не быть выше друг друга, это все еще производило то же самое странное поведение.
Любая помощь в понимании / разрешении этого вопроса будет весьма признательна.
1 ответ:
Проблема в том, чтособытие пузырится : в то время как целевой ребенок получает щелчок и удаляет своих детей, как вы и предполагали, событие пузырится до всех родителей, которые делают то же самое по очереди.
К счастью, Vue предлагает легкий доступ к модификаторам событий , а именно.stop
остановит дальнейшее распространение события.Кроме того, кажется, что вы делаете это излишне сложным, если я не упускаю из виду требование, которое вы не изложили в вопросе? Тебе это не нужно. перекомпилируйте дочерний компонент, и вам не понадобится вычисляемое свойство.
Я обновил ваш пример кода с учетом вышеперечисленных проблем:
Vue.component('context', { data() { return { hasChild: false, style: { 'background-color': '#' + randHex(6) } } }, methods: { addChild() { this.hasChild = true }, removeChild() { this.hasChild = false } }, template: ` <div :style="style" @click="addChild" @click.shift.stop="removeChild"> <context v-if="hasChild"></context> </div> ` }) new Vue({ el: '#app' }) function randHex(digits) { let hex = Math.floor(Math.random() * Math.pow(16, digits)).toString(16) return '0'.repeat(digits - hex.length) + hex }
html, body { height: 100%; overflow: hidden; } div { width: 90%; height: 90%; }
<script src="https://unpkg.com/vue@2.4.3/dist/vue.js"></script> <div id="app"> <context></context> </div>