所以我最近开始使用 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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f191a0a2f5d415b415c" rel="noreferrer noopener nofollow">[email protected]</a>/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>
在上面您将看到单击彩色矩形会按预期添加内部子项。然而,当您按住 Shift 键并单击矩形时,它不仅会删除其子项,还会删除所有子项! (甚至是当前节点的父节点。)
最初我以为点击事件“渗透”到较低的元素,但是我确实创建了一个更复杂的测试,将元素位置偏移到不彼此之上,这仍然产生相同的奇怪行为。
任何有关理解/解决此问题的帮助将不胜感激。
最佳答案
问题是event bubbling :当目标子级收到点击并删除其子级时,如您所愿,该事件会冒泡到所有依次执行相同操作的父级。
幸运的是,Vue 可以轻松访问 event modifiers ,即 .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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92e4e7f7d2a0bca6bca1" rel="noreferrer noopener nofollow">[email protected]</a>/dist/vue.js"></script>
<div id="app">
<context></context>
</div>
关于javascript - Vue2.4+编译组件行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46193636/