Vue组件内部存在Vue组件,作用域似乎会冲突。

3

我有一个简单的下拉组件,它可以让我隐藏和显示一些HTML内容,非常基础。

但是如果我在组件内部再次使用同样的组件,点击“测试2”的下拉切换将会折叠第一个下拉...

<dropdown>
    <li slot-scope="{ display, toggleDisplay }" @click="toggleDisplay()" :class="{ active: display }">
        Test
        <ul>
            <dropdown>
                <li slot-scope="{ display, toggleDisplay }" @click="toggleDisplay()" :class="{ active: display }">
                    Test 2
                </li>
            </dropdown>
        </ul>
    </li>
</dropdown>

为什么会这样呢?此外,我应该能够在单击事件中只执行display = !display来切换它,而不是使用一个函数?
该组件:
<script>
    export default {
        props: [ 'expanded' ],
        data: function() {
            return {
                display: !!(this.expanded)
            }
        },
        render() {
            return this.$scopedSlots.default({
                display: this.display,
                toggleDisplay: this.toggleDisplay
            })
        },
        methods: {
            toggleDisplay() {
                this.display = !this.display;
            }
        }
    }
</script>
1个回答

2
这被称为“事件冒泡”,要防止它,请使用“stopPropagation();”。(https://javascript.info/bubbling-and-capturing)。我已经删除了括号(@click="toggleDisplay")以自动设置$event。你也可以写成:@click="toggleDisplay($event)"。最初的回答。

Vue.component("dropdown", {
    props: ["expanded"],
    data: function() {
        return {
            display: !!this.expanded
        };
    },
    render() {
        return this.$scopedSlots.default({
            display: this.display,
            toggleDisplay: this.toggleDisplay
        });
    },
    methods: {
        toggleDisplay(e) {
            e.stopPropagation(); // this line
            this.display = !this.display;
        }
    }
});

new Vue().$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.10/vue.js"></script>

<div id="app">
  <dropdown>
    <li slot-scope="{ display, toggleDisplay }" @click="toggleDisplay" :class="{ active: display }">
      {{ display }}
      Test
      <ul>
        <dropdown>
          <li slot-scope="{ display, toggleDisplay }" @click="toggleDisplay" :class="{ active: display }">
            {{ display }}
            Test 2
          </li>
        </dropdown>
      </ul>
    </li>
  </dropdown>
</div>


该死,这么简单和基础的解决方案。我没想到在Vue中会有这个问题,所以没有尝试过。 - Martyn Ball

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接