Пару недель назад я сделал первый из этих 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` под весь существующий код и проверьте. У нас есть три кнопки переключения, каждая из которых работает независимо! Я намеренно оставил там исходный код, чтобы вы могли видеть, что компонент фактически инкапсулирован и использует отдельную область видимости от остальной части страницы.
Это всего лишь верхушка айсберга, но хорошее место, чтобы остановиться и переварить то, что мы узнали, прежде чем разбираться в свойствах, данных шаблонов и всех других вещах, которые мы можем использовать, чтобы сделать их действительно эффективными.
Надеюсь, это помогло!