Vue组件中的Vue组件,范围似乎存在冲突

时间:2019-05-02 15:48:25

标签: javascript vue.js

我有一个简单的下拉组件,它仅允许我隐藏和显示一些HTML,这是非常基本的。

但是,如果我在内部使用相同的组件,则单击Test 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 个答案:

答案 0 :(得分:2)

这称为event bubblinghttps://javascript.info/bubbling-and-capturing),为了防止使用stopPropagation();

我删除了括号(@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>