본문 바로가기
vue

클릭시 상단 push

by uni:D 2024. 8. 2.

vue3 script setup

1. 하단 리스트의 목록에 한 아이템을 선택하면 상단에 그 아이템이 표시되고 목록에선 사라짐

2. 상단에 아이템에 삭제를 선택하면 다시 목록으로 돌아감

ref 로했을때

https://vuetifyjs.com/en/components/chips/#custom-list

 

Chip component — Vuetify

The chip component allows a user to enter information, make selections, filter content or trigger actions.

vuetifyjs.com

 

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
<template>
  <div>
    <!-- 상단 선택된 항목 표시 -->
    <div v-if="selectedItem" class="selected-item">
      <span>{{ selectedItem.text }}</span>
      <button @click="removeSelectedItem">삭제</button>
    </div>
 
    <!-- 항목 목록 표시 -->
    <ul>
      <li v-for="item in filteredItems" :key="item.text">
        <span>{{ item.text }}</span>
        <button @click="selectItem(item)">선택</button>
      </li>
    </ul>
  </div>
</template>
 
<script setup>
import { ref, computed } from 'vue'
 
const items = ref([
  { text: 'Nature', icon: 'mdi-nature' },
  { text: 'Nightlife', icon: 'mdi-glass-wine' },
  { text: 'November', icon: 'mdi-calendar-range' },
  { text: 'Portland', icon: 'mdi-map-marker' },
  { text: 'Biking', icon: 'mdi-bike' }
])
 
const selectedItem = ref(null)
 
// 항목을 선택하면 selectedItem에 저장하고 목록에서 제거
const selectItem = (item) => {
  selectedItem.value = item
  items.value = items.value.filter(i => i !== item)
}
 
// 선택된 항목을 삭제하면 다시 목록으로 추가
const removeSelectedItem = () => {
  if (selectedItem.value) {
    items.value.push(selectedItem.value)
    selectedItem.value = null
  }
}
 
// 필터링된 항목 목록을 계산 (여기서는 모든 항목을 반환)
const filteredItems = computed(() => items.value)
</script>
 
<style>
.selected-item {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
 
.selected-item span {
  margin-right: 8px;
}
</style>
cs

reactiv 로했을때

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
<template>
  <div>
    <!-- 상단 선택된 항목 표시 -->
    <div v-if="state.selectedItem" class="selected-item">
      <span>{{ state.selectedItem.text }}</span>
      <button @click="removeSelectedItem">삭제</button>
    </div>
 
    <!-- 항목 목록 표시 -->
    <ul>
      <li v-for="item in filteredItems" :key="item.text">
        <span>{{ item.text }}</span>
        <button @click="selectItem(item)">선택</button>
      </li>
    </ul>
  </div>
</template>
 
<script setup>
import { reactive, computed } from 'vue'
 
// 반응형 상태 정의
const state = reactive({
  items: [
    { text: 'Nature', icon: 'mdi-nature' },
    { text: 'Nightlife', icon: 'mdi-glass-wine' },
    { text: 'November', icon: 'mdi-calendar-range' },
    { text: 'Portland', icon: 'mdi-map-marker' },
    { text: 'Biking', icon: 'mdi-bike' }
  ],
  selectedItem: null
})
 
// 항목을 선택하면 selectedItem에 저장하고 목록에서 제거
const selectItem = (item) => {
  state.selectedItem = item
  state.items = state.items.filter(i => i !== item)
}
 
// 선택된 항목을 삭제하면 다시 목록으로 추가
const removeSelectedItem = () => {
  if (state.selectedItem) {
    state.items.push(state.selectedItem)
    state.selectedItem = null
  }
}
 
// 필터링된 항목 목록을 계산 (여기서는 모든 항목을 반환)
const filteredItems = computed(() => state.items)
</script>
 
<style>
.selected-item {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
 
.selected-item span {
  margin-right: 8px;
}
</style>
cs

 

 

ref와 reactive는 Vue 3에서 반응형 상태를 관리하는 두 가지 주요 방법입니다. 이 두 가지는 각기 다른 상황에 따라 유용합니다. 아래는 ref와 reactive의 차이점과, 이 경우 어느 것이 더 적합한지에 대한 설명입니다:

ref와 reactive의 차이

  • ref:
    • 기본 타입(문자열, 숫자, 불리언 등) 또는 객체를 반응형으로 만드는 데 사용됩니다.
    • ref는 단일 값 또는 객체의 래퍼(wrapper)로서 사용되며, 주로 단일 값 또는 간단한 객체를 다룰 때 유용합니다.
    • ref를 사용할 때는 .value 속성으로 값을 읽고 설정해야 합니다.
  • reactive:
    • 복잡한 객체 또는 배열을 반응형으로 만들 때 사용됩니다.
    • reactive는 객체의 모든 속성과 배열의 요소가 반응형이 되도록 만듭니다.
    • reactive를 사용할 때는 .value 속성 없이 직접 객체의 속성에 접근할 수 있습니다.

 

 

추가될때 앞으로 추가되게하고 추가될때 이전것이 오른쪽으로 밀리는 transition css효과

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
84
85
86
87
88
89
<template>
  <div>
    <!-- 상단 선택된 항목 표시 -->
    <div v-if="state.selectedItem" class="selected-item">
      <span>{{ state.selectedItem.text }}</span>
      <button @click="removeSelectedItem">삭제</button>
    </div>
 
    <!-- 항목 목록 표시, transition-group을 사용하여 트랜지션 효과 적용 -->
    <transition-group name="list" tag="ul">
      <li v-for="item in filteredItems" :key="item.text" class="list-item">
        <span>{{ item.text }}</span>
        <button @click="selectItem(item)">선택</button>
      </li>
    </transition-group>
  </div>
</template>
 
<script setup>
import { reactive, computed } from 'vue'
 
// 반응형 상태 정의
const state = reactive({
  items: [
    { text: 'Nature', icon: 'mdi-nature' },
    { text: 'Nightlife', icon: 'mdi-glass-wine' },
    { text: 'November', icon: 'mdi-calendar-range' },
    { text: 'Portland', icon: 'mdi-map-marker' },
    { text: 'Biking', icon: 'mdi-bike' }
  ],
  selectedItem: null
})
 
// 항목을 선택하면 selectedItem에 저장하고 목록에서 제거
const selectItem = (item) => {
  state.selectedItem = item
  state.items = state.items.filter(i => i !== item)
}
 
// 선택된 항목을 삭제하면 다시 목록으로 추가
const removeSelectedItem = () => {
  if (state.selectedItem) {
    state.items.push(state.selectedItem)
    state.selectedItem = null
  }
}
 
// 필터링된 항목 목록을 계산
const filteredItems = computed(() => state.items)
</script>
 
<style>
.selected-item {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
 
.selected-item span {
  margin-right: 8px;
}
 
/* 리스트 항목의 기본 스타일 */
.list-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px;
  background-color: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 4px;
  position: relative; /* for absolute positioning */
}
 
/* 추가될 때의 트랜지션 효과 */
.list-enter-active, .list-leave-active {
  transition: transform 0.5s ease;
}
 
/* 추가될 때 왼쪽에서 오른쪽으로 나타나는 애니메이션 */
.list-enter {
  transform: translateX(-100%);
}
 
/* 제거될 때 오른쪽에서 왼쪽으로 사라지는 애니메이션 */
.list-leave-to {
  transform: translateX(100%);
}
</style>
cs

'vue' 카테고리의 다른 글

레이어팝업  (0) 2024.08.02
방향에 따른 툴팁 tooltip  (0) 2024.08.02
vuetify3 클릭시 아이콘변경 show 구조  (0) 2024.08.02
v-model  (0) 2024.08.01
vue3 페이지 몇초후 이동  (0) 2024.07.29