javascript - Vue2.4+编译组件行为

标签 javascript vue.js vuejs2 vue-component

所以我最近开始使用 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/

相关文章:

javascript - 在 python 服务器上从 Fabric.js JSON 构造图像

javascript - Vue.js - 重置filterBy结果

javascript - 在窗口中保存经过身份验证的用户信息是否安全

javascript - VueJS : Filter array of objects when user search for something

javascript - 如何使用vue设置在选择字段中选择的选项?

Javascript - 如何从给定索引处的数组中删除项目

javascript - Gulp:如何读取文件夹名称?

javascript - 服务中的 Angular 存储变量

javascript - vue 的 .each() 方式

vue.js - 从 Vue 脚本中获取 Pug/Jade 混合参数