Подскажите пожалуйста как реализовать такую возможность: Чтобы когда нажималась кнопка Войти в комнату, уже открытая комната закрывалась? Либо когда нажималась кнопка Войти в комнату, весь список скрывался, кроме выбранной комнаты?
Постарался в комментариях кода объяснить каким образом можно реализовать передачу свойств между компонентами. Это как один из вариантов.
Vue.component('rooms-list', {
template: `<div>
<h1 v-if="currentRoom">Вы в комнате № {{ currentRoom }}</h1>
<h1 v-else>Выберите комнату</h1>
<template v-for="room in rooms">
<room-row
v-bind="room"
:current.sync="currentRoom"
@update-room="onUpdateRoom" />
</template>
</div>`,
/**
* Эти свойства были переданы в этот компонент как v-bind="rooms".
*/
props: {
// Список всех комнат.
list: Array,
// Поле с номером текущей комнаты.
current: Number
},
data() {
return {
// Для работы с переданными свойствами задаём им локальный статус.
rooms: this.$props.list,
currentRoom: this.$props.current,
}
},
methods: {
/**
* Обновляем данные о комнатах.
* Данный метод вызывается из дочернего путем
* this.$emit('update-room', {...})
*/
onUpdateRoom(room) {
// Ищем индекс переданной `room` комнаты в списке.
const roomIndex = this.rooms
.findIndex(item => item.id === room.id)
// Обновляем информацию о комнатах.
this.rooms.splice(roomIndex, 1, room)
}
},
})
Vue.component('room-row', {
template: `<div>
<div v-if="isActiveRoom">
<button type="button" @click="cameOut">Выйти из комнаты №{{ id }}</button><br/>
<label><input type="checkbox" v-model="active" /> Лампочка {{ active | humanValue }}</label>
</div>
<div v-else-if="nonSelectedRoom">
<button type="button" @click="comeIn">Войти в комнату №{{ id }}</button>
</div>
</div>`,
props: {
id: Number,
activeLamp: Boolean,
// Поле с номером текущей комнаты, переданный с модификатором `.sync`
// Модификатор обеспечит двустороннюю привязку.
// При изменении его в одном из компонентов, остальные компоненты,
// через родительский будут об этом знать незамедлительно.
current: Number,
},
data() {
return {
// Определяем модель для состояния лампочки.
active: this.$props.activeLamp
}
},
computed: {
/**
* Мы находимся в этой комнате.
* Отобразим лампочку и создадим возможность выйти из комнаты.
*/
isActiveRoom() {
return this.current === this.id
},
/**
* Мы не в одной из комнат.
* Отобразим весь список комнат.
*/
nonSelectedRoom() {
return !this.current
}
},
filters: {
humanValue(value) {
return !!value ? 'включена' : 'выключена'
}
},
methods: {
/**
* Заходим в комнату.
*/
comeIn() {
// Оповещаем родительский компонент о том,
// что необходимо обновить данные о номере текущей комнаты.
this.$emit('update:current', this.id)
},
/**
* Выходим из комнаты.
*/
cameOut() {
// Хлопаем дверью.
this.$emit('update:current', 0)
// Обновляем данные о текущей комнате в родительском компоненте.
// Родительский элемент в свою очередь вызовет метод,
// записанный как `@update-room="onUpdateRoom"`
this.$emit('update-room', {
id: this.id,
activeLamp: this.active
})
},
}
})
const APP = new Vue({
el: '#app',
data: {
// Наша модель. Так сказать общага )
rooms: {
// Поле с номером текущей комнаты.
// По умолчанию мы никуда еще не вошли.
current: 0,
// Список всех комнат.
// Первое поле - это номер.
// Второе - отображает состояние выключателя
list: [{
id: 1,
activeLamp: false
},
{
id: 2,
activeLamp: false
},
{
id: 3,
activeLamp: false
},
{
id: 4,
activeLamp: false
},
{
id: 5,
activeLamp: false
},
]
}
},
})
<div id="app">
<!--
Передаём данные о комнатах - v-bind="rooms" как объект.
Эти данные определены при инициализации App в поле `data: {...}`.
Эта запись равнозначна записи
:current="rooms.current" :list="rooms.list"
НО: изменение объекта или массива внутри дочернего компонента
будет влиять на состояние родителя.
-->
<rooms-list v-bind="rooms"></rooms-list>
<pre>{{ rooms }}</pre>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
Ваша проблема в том, что вы описываете лампочку только одной переменной - id, при этом никак не озвучивая, что ещё у лампы есть состояние. Как только вы введёте состояние в виде реактивной переменной ваша жизнь многократно упростится:
<template>
<div>
<div>лампа # {{ this.lamp.id }}, состояние: {{ lamp.light ? 'включена' : 'выключена' }}</div>
<div>
<button v-on:click="changeState">CLICKME</button>
</div>
<div v-if="lamp.light">ещё какой-то блок для включенной лампы</div>
<div v-else>ещё какой-то блок для выключенной лампы</div>
</div>
</template>
<script>
export default {
name: "Lamp",
props: {
lamp: {
id: 0,
light: false
}
},
methods: {
changeState: function() {
this.lamp.light = !this.lamp.light;
}
}
};
</script>
Теперь в списке ламп можно указывать их начальное состояние:
<template>
<div>
<h1>Hello lampls</h1>
<lamp v-for="item in lamps" :key="item.id" :lamp="item"/>
</div>
</template>
<script>
import Lamp from "@/components/Lamp";
export default {
name: "Lamps",
components: { Lamp },
data() {
return {
lamps: [{ id: 1, light: false }, { id: 2, light: true }]
};
}
};
</script>
Проверяем работу:
<template>
<div>
<h1>Hello lampls</h1>
<lamps></lamps>
</div>
</template>
<script>
import Lamps from "@/components/Lamps";
export default {
name: "HelloWorld",
components: { Lamps }
};
</script>
Всё выводится, всё кликается:
В остальном ваша логика не очень понятна. "Вошёл в комнату - комната закрылась", это пожалуй так же нелогично как и "включил лампу - потекла вода из крана". В общем, оставляю вам описание условий что и от чего должно зависеть на самостоятельную проработку.
Я пытался понять логику, у меня получалось, что вам нужно описывать состояние на уровне комнаты, но дальше начались сплошные предположения и я решил, что это вам лучше самому разобрать.
Вероятнее всего (но это чисто мои предположения), вы хотели логику "только одна из комнат может быть в состоянии Open. При нажатии на кнопку войти в комнату все остальные должны закрываться". Если так, то вам на уровне блока rooms нужна одна реактивная переменная selected_room_id и отрисовка room в зависимости от значения этой переменной (в самом простом случае можно обойтись только навешиванием/скрыванием css класса selected и описанием css правил типа display:none)
И вот ещё. Вы сейчас думаете об этой функциональности, как о размещённой на одной странице, но вполне возможно, что стоило бы рассмотреть это как два разных url: на одной есть список всех комнат и напротив каждой комнаты ссылка на переход к странице управления выбранной комнатой, где отображать название комнаты, списки её лампочек и т.п. В этом случае скрытие всех других комнат у вас будет "из коробки".
Подумайте, возможно у вас сформулируется на основании этого новый вопрос с новыми правилами что и как переключать.
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
интересуют два меленьких вопроса, которые не хочется расписывать в двух разных вопросах!
Использую за основу этот проект: https://githubcom/cretueusebiu/laravel-vue-spa Так вот через axios нужно получить в виде json данные с другого сайта
Посоветуйте пожалуйста хорошую(-ие) книгу(-и) по JavascriptЯ новичок
На странице бутстраповский datetimepickerВ первый раз когда кликаю - все корректно