Пару недель назад я сделал первый из этих Vue.js Simple Tuts, где мы рассмотрели создание простого переключателя. Вы увидите, что весь код повторяется здесь, но если вы хотите начать с самого начала, посмотрите Vue.js Simple Tuts: Toggling

Когда мы остановились, у нас есть следующий код:

<!-- index.html -->
<div id="app">
    <button @click='toggle()'>Open/Close</button>
    <span  v-show="isOpen">Toggle info</span>
</div>

<!-- app.js -->
new Vue({
    el: '#app',
    data: {
        isOpen: false
    },
    methods:{
        toggle: function(){
            this.isOpen = !this.isOpen
        }
    }
});

Это симпатичный маленький набор переключателей. Настолько хорошо, что я бы хотел, чтобы у меня на странице было их три. Так что вперед - скопируйте / вставьте кнопку, растяните еще два раза и посмотрите.

Ой. Когда я нажимаю одну кнопку, они все открываются и закрываются. Я не этого хочу. Очевидно, проблема в том, что все они используют переменную isOpen, и объект Vue не может узнать, к какому диапазону применить функцию.

В jQuery это просто - мы можем перемещаться вверх и вниз по DOM с помощью серии кода типа parent (). Children (‘span’) `или добавлять совпадающие нумерованные идентификаторы, такие как` data-id-1`. Это потому, что jQuery использует DOM в качестве своего контейнера. В Vue.js нам нужно всегда взаимодействовать с другими компонентами через класс Vue. Давай попробуем.

Мы хотим, чтобы два элемента (кнопка и диапазон) работали вместе как единый набор многократно используемого инкапсулированного кода, называемого Component в фреймворках javascript (который, я уверен, вы уже догадались) . Давайте откроем наш файл app.js и создадим его.

<!-- app.js -->
<!-- put this ABOVE your new Vue() declaration -->
Vue.component('toggle-component', {
    template: "<button @click='toggle()'>Open/Close</button>
               <span v-show=\"isOpen\">Toggle info</span>"
});

Это глобальная регистрация компонента, что идеально подходит для сегодняшнего урока. Мы создаем свои собственные элементы, как пользовательские div или span, как мы увидим ниже:

<!-- index.html -->
<div id="app">
    <button @click='toggle()'>Open/Close</button>
    <span  v-show="isOpen">Toggle info</span>
</div>
<toggle-component></toggle-component>

Включите Firebug или Dev Tools и обновите страницу. Вы видите две кнопки, но красное предупреждающее сообщение:

[Vue warn]: шаблон компонента должен содержать ровно один корневой элемент:

Что он пытается нам сказать? На самом деле это характерно для всех фреймворков javascript, с которыми я работал - я впервые увидел это с React.js. Помните, когда мы думали о том, как это сделать с помощью jQuery, мы сказали: «Хорошо, parent ()…». Ну, у нас здесь нет родителей. У нас нет единого элемента, выступающего в качестве контейнера для этого компонента - у нас есть «множественные корни». Другими словами, наши экземпляры Vue не знают, должны ли они взаимодействовать с «кнопкой» или «диапазоном». Легко исправить это, просто добавив обертку «div» следующим образом:

Vue.component('toggle-component', {
    template: "<div>
          <button @click='toggle()'>Open/Close</button>
          <span  v-show=\"isOpen\">Toggle info</span>
       </div>"
});

обновить и… новая ошибка! Прогресс!

[Vue warn]: свойство или метод isOpen не определены в экземпляре, но используются во время рендеринга. Обязательно объявите реактивные свойства данных в параметре данных.

Мы столкнулись с этим в предыдущем руководстве, где мы построили саму логику переключения. В этом контексте переменная isOpen не была объявлена, поэтому мы добавили переменную data. Здесь то же самое; в пределах нашей области видимости компонента isOpen не объявляется. Давайте исправим это:

Vue.component('toggle-component', {
    template: "<div>
          <button @click='toggle()'>Open/Close</button>
          <span  v-show=\"isOpen\">Toggle info</span>
       </div>",
    data: {
        isOpen: false
    }
});

ГАХХ! Больше ошибок!

[Предупреждение Vue]: параметр «данные» должен быть функцией, которая возвращает значение для каждого экземпляра в определениях компонентов.

Это немного странно, пока вы не поймете, почему так должно быть. Ключ находится во второй части сообщения - значение для каждого экземпляра. Короче говоря, вот как мы можем использовать несколько экземпляров `toggle-component`, чтобы каждый из них имел собственное состояние. Прочтите замечательный пример из документации, чтобы лучше понять пример кода: https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

Vue.component('toggle-component', {
    template: "<div>
          <button @click='toggle()'>Open/Close</button>
          <span  v-show=\"isOpen\">Toggle info</span>
       </div>",
    data: function () {
        return {
            isOpen: false
        }
    }
});

Если вы обновитесь сейчас, сообщений об ошибках больше не будет! То есть, пока вы не нажмете кнопку. Но на этот раз сообщение должно быть довольно ясным - мы не определили `toggle ()` для нашего компонента.

Vue.component('toggle-component', {
    template: "<div>
          <button @click='toggle()'>Open/Close</button>
          <span  v-show=\"isOpen\">Toggle info</span>
        </div>",
    data: function () {
        return {
            isOpen: false
        }
    },
    methods:{
        toggle: function(){
            this.isOpen = !this.isOpen
        }
    }
});

Идите вперед и добавьте еще один `toggle-component` под весь существующий код и проверьте. У нас есть три кнопки переключения, каждая из которых работает независимо! Я намеренно оставил там исходный код, чтобы вы могли видеть, что компонент фактически инкапсулирован и использует отдельную область видимости от остальной части страницы.

Это всего лишь верхушка айсберга, но хорошее место, чтобы остановиться и переварить то, что мы узнали, прежде чем разбираться в свойствах, данных шаблонов и всех других вещах, которые мы можем использовать, чтобы сделать их действительно эффективными.

Надеюсь, это помогло!