Думаю, я лажаю, это очень простые вещи, но, похоже, они не работают ...
Обычно щелчок по ссылке должен переключать display между истинным и ложным, но это не так.
Vue.component('dropdown', {
props: [ 'expanded' ],
data: function() {
return {
display: !!(this.expanded)
}
},
template: '<div><transition name = "expand"><slot :display = "display"></slot></transition></div>'
});
window.app = new Vue({
el: '#app'
});<script src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id = "app">
<dropdown>
<div slot-scope = "{ display }">
<a href = "javascript:void(0)" @click = "display = !display">Toggle {{ display }}</a>
<div v-if = "display">
Dropdown content
</div>
</div>
</dropdown>
</div>Редактировать:
Обновленный код, я забыл, что изменил это, у меня действительно было событие щелчка как display = !display. Но даже с учетом сказанного, если бы вы попытались нажать кнопку, вы бы увидели, что это тоже не меняет истину ...
Все, что вам нужно, это @click = "display = !display"
В соответствии с вашим обновлением в теперь удаленном ответе попробуйте @click.prevent.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Одним из решений может быть реализация v-model для компонента dropdown, который позволит вам двусторонним образом привязать свойство display к свойству в родительском элементе. Таким образом, вам не нужно будет ничего передавать через slot-scope.
Вот пример этого:
Vue.component('dropdown', {
props: [ 'value' ],
data() {
return {
display: !!(this.value)
}
},
watch: {
value(value) {
this.$emit('input', value);
}
},
template: '<div><transition name = "expand"><slot></slot></transition></div>'
});
new Vue({
el: '#app',
data() {
return { dropdownToggle: false }
}
});<script src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id = "app">
<dropdown v-model = "dropdownToggle">
<div>
<a href = "javascript:void(0)" @click = "dropdownToggle = !dropdownToggle">
Toggle {{ dropdownToggle }}
</a>
<div v-if = "dropdownToggle">
Dropdown content
</div>
</div>
</dropdown>
</div>Обновление после исправляющего комментария от Спасибо д. Я наткнулся на правильный ответ, толком его не поняв.
Проблема в том, что в слоте display ссылается на элемент в объекте слот-области. При его обновлении фактическая исходная переменная не обновляется. Если вы перейдете и вызовете функцию, соответствующая переменная будет обновлена.
Vue.component('dropdown', {
props: ['expanded'],
data: function() {
return {
display: Boolean(this.expanded)
}
},
methods: {
toggle() {
this.display = !this.display;
}
},
template: '<div><transition name = "expand"><slot :display = "display" :toggle = "toggle"></slot></transition></div>'
});
new Vue({
el: '#app'
});<script src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id = "app">
<dropdown>
<div slot-scope = "{display, toggle}">
<a href = "javascript:void(0)" @click = "toggle">Toggle {{ display }}</a>
<div v-if = "display">
Dropdown content
</div>
</div>
</dropdown>
</div>Я думаю, что это лучшее решение, хотя нет необходимости называть объект слота с ограниченной областью видимости, если вы используете деструктуризацию объекта, как это делает Мартин в своем примере. Итак, slot-scope = "ss" может быть slot-scope = "{ display, toggle }". Ключ к вашему ответу заключается в том, что добавление метода toggle и передача его через slot-scope позволяет родительской области косвенно обновлять свойство display экземпляра раскрывающегося компонента. Проблема с примером Мартина заключается в том, что он обновляет свойство переменной в слоте области видимости, что не то же самое, что обновление связанного свойства в экземпляре.
Спасибо, @thanksd, за разъяснения. Я соответственно обновил свой ответ.
Ах, теперь это имеет смысл, спасибо. Я думал, что вы можете напрямую изменить свойство данных из слота, поскольку я уверен, что видел это где-то раньше, однако я могу ошибаться. Единственная причина, по которой я хотел повлиять на это напрямую, заключалась в том, чтобы избежать создания метода, если в этом нет необходимости.
Если бы свойство данных было объектом, вы могли бы изменить его члены и отразить эти изменения в исходном объекте (поскольку копии объектов являются псевдонимами).
@click = "display = true"просто всегда устанавливает значение true.@click = "display = !display", возможно?