Компонент Vue, переключение данных

Думаю, я лажаю, это очень простые вещи, но, похоже, они не работают ...

Обычно щелчок по ссылке должен переключать 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 = true" просто всегда устанавливает значение true. @click = "display = !display", возможно?
ceejayoz 30.11.2018 20:34

Все, что вам нужно, это @click = "display = !display"

Moumen Soliman 30.11.2018 20:39

В соответствии с вашим обновлением в теперь удаленном ответе попробуйте @click.prevent.

ceejayoz 30.11.2018 20:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Одним из решений может быть реализация 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 30.11.2018 21:36

Спасибо, @thanksd, за разъяснения. Я соответственно обновил свой ответ.

Roy J 30.11.2018 21:56

Ах, теперь это имеет смысл, спасибо. Я думал, что вы можете напрямую изменить свойство данных из слота, поскольку я уверен, что видел это где-то раньше, однако я могу ошибаться. Единственная причина, по которой я хотел повлиять на это напрямую, заключалась в том, чтобы избежать создания метода, если в этом нет необходимости.

Martyn Ball 02.12.2018 14:37

Если бы свойство данных было объектом, вы могли бы изменить его члены и отразить эти изменения в исходном объекте (поскольку копии объектов являются псевдонимами).

Roy J 02.12.2018 16:18

Другие вопросы по теме