Как сделать динамический popup на vue.js?

Пользователь

от nicolette.stoltenberg , в категории: JavaScript , 2 года назад

Как сделать динамический popup на vue.js?

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

2 ответа

Пользователь

от aaron_armstrong , 2 года назад

@nicolette.stoltenberg 

Для создания динамического popup на Vue.js можно использовать компоненты Vue.js и директиву v-if или v-show. Для начала, нужно создать компонент popup, который будет содержать все необходимые элементы. Например:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<template>
  <div class="popup" v-if="visible">
    <div class="popup-overlay"></div>
    <div class="popup-container">
      <div class="popup-header">
        <h2>{{ title }}</h2>
        <button @click="closePopup">X</button>
      </div>
      <div class="popup-content">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: String,
    visible: Boolean,
  },
  methods: {
    closePopup() {
      this.$emit('close');
    },
  },
};
</script>

<style>
.popup {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.popup-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

.popup-container {
  position: relative;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0px 0px 16px rgba(0, 0, 0, 0.5);
  padding: 16px;
  max-width: 80%;
  max-height: 80%;
  overflow: auto;
}

.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.popup-header h2 {
  margin: 0;
}

.popup-header button {
  background-color: transparent;
  border: none;
  font-size: 24px;
  cursor: pointer;
}

.popup-content {
  margin-top: 16px;
}
</style>


Затем можно создать родительский компонент, который будет содержать кнопку или другой элемент, который будет вызывать popup. В нем нужно создать методы, которые будут управлять видимостью popup и передавать данные в компонент popup через пропсы.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
  <div>
    <button @click="openPopup">Открыть popup</button>
    <popup :title="title" :visible="visible" @close="closePopup">
      <p>Контент popup</p>
    </popup>
  </div>
</template>

<script>
import Popup from './Popup.vue';

export default {
  components: {
    Popup,
  },
  data() {
    return {
      title: 'Popup заголовок',
      visible: false,
    };
  },
  methods: {
    openPopup() {
      this.visible = true;
    },
    closePopup() {
      this.visible = false;
    },
  },
};
</script>


Теперь при нажатии на кнопку будет отображаться popup с заданным контентом и заголовком. Кнопка закрытия popup вызывает метод closePopup, который скрывает popup.

Пользователь

от marc_zboncak , 8 месяцев назад

@nicolette.stoltenberg 

Дополнительно можно улучшить функционал попапа, добавив возможность передавать любой контент внутрь компонента popup через слоты. Например, такой компонент может выглядеть следующим образом:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<template>
  <div class="popup-overlay" @click="closePopup" v-if="visible">
    <div class="popup-container" @click.stop>
      <div class="popup-header">
        <h2>{{ title }}</h2>
        <button @click="closePopup">X</button>
      </div>
      <div class="popup-content">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: String,
    visible: Boolean
  },
  methods: {
    closePopup() {
      this.$emit('close');
    }
  }
};
</script>

<style>
.popup-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.popup-container {
  position: relative;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0px 0px 16px rgba(0, 0, 0, 0.5);
  padding: 16px;
  max-width: 80%;
  max-height: 80%;
  overflow: auto;
}

.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.popup-header h2 {
  margin: 0;
}

.popup-header button {
  background-color: transparent;
  border: none;
  font-size: 24px;
  cursor: pointer;
}

.popup-content {
  margin-top: 16px;
}
</style>


Данный компонент попапа принимает видимость, заголовок и отображает любой контент, переданный через слот. Теперь у компонента родителя можно передавать нужный контент внутрь попапа:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
  <div>
    <button @click="togglePopup">Открыть/закрыть попап</button>
    <popup :title="popupTitle" :visible="isPopupVisible" @close="closePopup">
      <p>Любой контент, передаваемый внутрь попапа через слоты</p>
    </popup>
  </div>
</template>

<script>
import Popup from './Popup.vue';

export default {
  components: {
    Popup
  },
  data() {
    return {
      popupTitle: 'Заголовок попапа',
      isPopupVisible: false
    };
  },
  methods: {
    togglePopup() {
      this.isPopupVisible = !this.isPopupVisible;
    },
    closePopup() {
      this.isPopupVisible = false;
    }
  }
};
</script>


Теперь при нажатии на кнопку "Открыть/закрыть попап" будет открываться и закрываться попап с переданным контентом и заголовком.