์ด์ „๊ธ€๋ณด๊ธฐ


1. Vuex ์ถ”๊ฐ€ํ•˜๊ธฐ

vue add vuex

์„œ๋ฒ„๊ฐ€ ์ผœ์ ธ์žˆ๋‹ค๋ฉด ์„œ๋ฒ„๋ฅผ ์ข…๋ฃŒ์‹œํ‚ค๊ณ (VSCode ๋‹จ์ถ•ํ‚ค : Ctrl + c)

ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์— vuex๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

 

์„ฑ๊ณต์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๊ณ ๋‚˜๋ฉด src ํด๋” ์•„๋ž˜์— store ํด๋”๊ฐ€ ์ƒˆ๋กœ ์ƒ๊ฒจ์žˆ๋‹ค.

์ด์ œ ํ”„๋กœ์ ํŠธ์—์„œ ์ƒํƒœ๊ด€๋ฆฌ๋Š” ์ด store๋กœ ํ•˜๋ฉด ๋œ๋‹ค!

๐Ÿค” vuex๋„ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค ๐Ÿค”

 

 

2. Vuex ํ™œ์šฉํ•˜๊ธฐ

src/store/index.js์˜ ๊ธฐ๋ณธ ํ˜•ํƒœ๋Š” ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ๋‹ค.

 

ํšŒ์‚ฌ์—์„œ๋Š” ๊ด€๋ฆฌํ•ด์•ผ ํ•  ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„์„œ ๋”ฐ๋กœ ๋ชจ๋“ˆ๋กœ ๋นผ์„œ

index.js๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰์ค‘์ด์ง€๋งŒ,

์ง€๊ธˆ์€ ๊ด€๋ฆฌ ํ•  ๋ฐ์ดํ„ฐ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์ง€์•Š์œผ๋‹ˆ ํ•œ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.

 

 

// index.js state
state: {
    todos: [
      {
        id: 1,
        title: 'One'
      },
      {
        id: 2,
        title: 'Two'
      },
      {
        id: 3,
        title: 'Three'
      }
    ]
  }

state์— ๋ฏธ๋ฆฌ ๋‹ด๊ฒจ์žˆ์„ 3๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ,

 

 

// index.js getters, mutations, actions
getters: {
  allTodos: (state) => state.todos,
},
mutations: {
  mutationsAddTodo(state, todo) {
    state.todos.push(todo);
    console.log(state.todos);
  }
},
actions: {
  actionsAddTodo({commit}, todo) {
    commit('mutationsAddTodo', todo);
  }
}

getters์—๋Š” state์— ์ €์žฅ๋œ ๋ชจ๋“  todos๋ฅผ ๊ฐ€์ ธ์˜ฌ allTodos๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

mutations์—๋Š” actions์—์„œ ๋„˜์–ด์˜จ ๋ฐ์ดํ„ฐ๋ฅผ state์— pushํ•  mutationsAddTodo๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

actions์—๋Š” vue ์†Œ์Šค์—์„œ ์ด๊ฑฐ ์ €์žฅ์‹œ์ผœ!ํ•˜๊ณ  ํ˜ธ์ถœ๋  actionsAddTodo๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

commit('mutationsAddTodo', todo)๋ฅผ ์‹คํ–‰ํ•˜๋ฉด mutations์— ํ•ด๋‹น ์ด๋ฆ„์˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.

- mutations์—๋Š” ์ˆœ์ฐจ์ ์ธ ๋กœ์ง์„ ์ž‘์„ฑํ•˜๊ณ ,

  actions์—๋Š” ๋น„์ˆœ์ฐจ์  ๋˜๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์ž‘์„ฑํ•œ๋‹ค.

  ์ด ๋ถ€๋ถ„๋„ vuex ์ •๋ฆฌํ•˜๋ฉด์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •!

 

ํ•จ์ˆ˜ ์•ž์— mutations์™€ actions๋Š” ์•Œ์•„๋ณด๊ธฐ ์‰ฝ๊ฒŒ ๋ถ™์—ฌ๋†“์€๊ฒƒ์ด๋ฏ€๋กœ ์ƒ๋žตํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

 

 

<!-- src/components/TodoInput.vue -->
<template>
    <v-container fluid>
        <v-row class="mt-6" justify="center">
            <v-col cols="4">
                <v-text-field outlined></v-text-field>
            </v-col>
            <v-col cols="1">
                <v-btn @click="actionsAddTodo('12345')" block x-large color="primary">Add</v-btn>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
import { mapActions } from 'vuex';

export default {
    methods: {
        ...mapActions(['actionsAddTodo'])
    },
}
</script>

TodoInput์— vuex์˜ actions๋ฅผ import ์‹œํ‚ค๋ฉด ...mapActions๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

import ์‹œํ‚ค์ง€ ์•Š๋”๋ผ๋„ this.$store.dispatch('actionsAddTodo')๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค.

vue → store actions ํ˜ธ์ถœ : dispatch
actions → mutations ํ˜ธ์ถœ : commit

 

 

Add ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด actionsAddTodo๋ฅผ '12345'๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์„œ ์‹คํ–‰์‹œํ‚จ๋‹ค.

mutatilnsAddTodo์—์„œ state todos์— push ์‹œํ‚ค๊ณ  state์˜ todos๋ฅผ ์ฝ˜์†”๋กœ ์ฐ์–ด๋ณด๋ฉด

๊ฐ™์ด ๋„˜๊ฒจ์คฌ๋˜ 12345๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ด์ œ ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ text-field์—์„œ ์ ์€ ๊ฐ’์„ ๋„˜๊ฒจ๋ด…์‹œ๋‹ค ๐Ÿ˜˜

<!-- src/components/TodoInput.vue -->
<script>
import { mapActions } from 'vuex';

export default {
    data() {
        return {
            todoText: ''
        }
    },
    methods: {
        ...mapActions(['actionsAddTodo'])
    },
}
</script>

๋จผ์ € TodoInput script์— ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์„ ๋นˆ todoText๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

 

<!-- src/components/TodoInput.vue -->
<template>
    <v-container fluid>
        <v-row class="mt-6" justify="center">
            <v-col cols="4">
                <v-text-field v-model="todoText" outlined></v-text-field>
            </v-col>
            <v-col cols="1">
                <v-btn @click="actionsAddTodo(todoText)" block x-large color="primary">Add</v-btn>
            </v-col>
        </v-row>
    </v-container>
</template>

๊ทธ๋ฆฌ๊ณ  ํ…์ŠคํŠธ ํ•„๋“œ ํƒœ๊ทธ์— v-model์— todoText๋ฅผ ๋„ฃ์–ด์ค€๋‹ค!

๊ทธ๋Ÿฌ๋ฉด ํ…์ŠคํŠธ ํ•„๋“œ๊ฐ€ todoText๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ๋˜๊ณ ,

๊ทธ ๊ฐ’์„ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  actionsAddTodo๊ฐ€ ์‹คํ–‰๋ ๋•Œ ๊ฐ™์ด ๋„˜๊ฒจ์ค€๋‹ค.

 

๋ฐ์ดํ„ฐ ์ž…๋ ฅ ํ›„ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  ์ฝ˜์†”์— ์ฐํžŒ ๊ฐ’์„ ํ™•์ธํ•ด๋ณด๋ฉด ์ž˜ ๋„˜์–ด์˜จ๋‹ค!

 

 

3. UUID๋กœ ID ๋ถ€์—ฌํ•˜๊ธฐ

npm i --save uuid

์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” todoText๋Š” store์—์„œ title๋กœ ๊ด€๋ฆฌ๋  ๊ฒƒ์ด๊ณ ,

ID์—๋Š” ๊ณ ์œ ํ•œ key๊ฐ’์„ ๋„ฃ๊ธฐ ์œ„ํ•ด์„œ UUID๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

 

 

<!-- src/components/TodoInput.vue -->
<template>
    <v-container fluid>
        <v-row class="mt-6" justify="center">
            <v-col cols="4">
                <v-text-field v-model="todoText" outlined></v-text-field>
            </v-col>
            <v-col cols="1">
                <v-btn @click="addTodo" block x-large color="primary">Add</v-btn>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
import { mapActions } from 'vuex';
import { v1 } from 'uuid';

export default {
    data() {
        return {
            todoText: ''
        }
    },
    methods: {
        ...mapActions(['actionsAddTodo']),
        addTodo() {
            this.actionsAddTodo({
                id: v1(),
                title: this.todoText
            });
        }
    },
}
</script>

uuid๋ฅผ import ์‹œ์ผœ์ฃผ๊ณ , addTodo()๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ,

actionsAddTodo๋ฅผ ์‹คํ–‰ํ• ๋•Œ id์™€ title์„ ๋„ฃ์–ด์„œ ๋ณด๋‚ด์ฃผ๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค.

 

๋ฒ„ํŠผ ํด๋ฆญ์‹œ์—๋„ addTodo๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ์ˆ˜์ •ํ•ด์ค€๋‹ค.

 

 

test1์ด๋ผ๋Š” ๊ฐ™์€ ๊ฐ’์„ ๋‘๋ฒˆ ๋„˜๊ฒจ์คฌ์ง€๋งŒ id๋Š” ๊ณ ์œ ํ•˜๊ฒŒ ๋ถ€์—ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์—

๋งค๋ฒˆ ๋‹ค๋ฅธ id๊ฐ€ ๋„˜์–ด๊ฐ€๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

4. Text Field ์ดˆ๊ธฐํ™” ๋ฐ TodoList, TodoItem ์ˆ˜์ •

๊ธฐ์กด์—๋Š” Add ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋„˜์–ด๊ฐ€์ง€๋งŒ ํ…์ŠคํŠธ ํ•„๋“œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ๋Š” ์ƒํƒœ์˜€๋‹ค.

ํ•˜์ง€๋งŒ Add ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด store์— ์ €์žฅ์ด ๋˜๊ธฐ๋•Œ๋ฌธ์—, ํ…์ŠคํŠธ ํ•„๋“œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™” ์‹œ์ผœ์ค„ ๊ฑฐ๋‹ค!

 

 

<!-- src/components/TodoInput.vue -->
<v-text-field @change="todoTextChg" :value="todoText" outlined></v-text-field>

๋จผ์ € TodoInput.vue์— ์žˆ๋Š” ํ…์ŠคํŠธ ํ•„๋“œ ์†์„ฑ์„ ์ข€ ๋ฐ”๊ฟ”์ค€๋‹ค.

@change="todoTextChg" ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์„œ ํ…์ŠคํŠธ ํ•„๋“œ์˜ ๊ฐ’์ด ๋ฐ”๋€”๋•Œ๋งˆ๋‹ค todoTextChg๋ฅผ ์‹คํ–‰์‹œํ‚ค๋„๋ก ํ•œ๋‹ค.

 

 

// src/components/TodoInput.vue
methods: {
    ...mapActions(['actionsAddTodo']),
    todoTextChg(e) {
        this.todoText = e;
    },
    addTodo() {
        this.actionsAddTodo({
            id: v1(),
            title: this.todoText
        });
        this.todoText = '';
    }
},

methods์— todoTextChg ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  todoText ๊ฐ’์„ e๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  addTodo๊ฐ€ ์‹คํ–‰๋ ๋•Œ actionsAddTodo๊ฐ€ ์‹คํ–‰๋˜๊ณ ๋‚˜์„œ todoText๊ฐ’์„ ๋นˆ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด

 

 

abcd๋ผ๋Š” ๊ฐ’์„ ์ž…๋ ฅํ•˜๊ณ  Add ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด

์ฝ˜์†”์— ์ฐํžŒ ๋ฐ์ดํ„ฐ์— abcd๊ฐ€ ์ฐํ˜€์žˆ๊ณ 

ํ…์ŠคํŠธ ํ•„๋“œ๋Š” ๊ฐ’์ด ์ดˆ๊ธฐํ™”๊ฐ€ ๋œ๋‹ค.

 

 

์ด์ œ ๊ธฐ์กด์— TodoList.vue์—์„œ ํ•˜๋“œ์ฝ”๋”ฉ์œผ๋กœ ๋„ฃ์–ด๋†จ๋˜ ๋ฐ์ดํ„ฐ๋ฅผ

store getters allTodos๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์™€์„œ ๋„ฃ์–ด์ค„๊ฑฐ๋‹ค.

<!-- src/components/TodoList.vue ๋ณ€๊ฒฝ ์ „ -->
<template>
    <v-container>
        <TodoItem/>
        <TodoItem/>
        <TodoItem/>
    </v-container>
</template>

<script>
import TodoItem from '@/components/TodoItem';

export default {
    components: {
        TodoItem
    }
}
</script>
<!-- src/components/TodoList.vue ๋ณ€๊ฒฝ ํ›„ -->
<template>
    <v-container>
        <v-row v-for="todo in allTodos"
               :key="todo.id"
        >
            <TodoItem :todo='todo'/>
        </v-row>
    </v-container>
</template>

<script>
import TodoItem from '@/components/TodoItem';
import { mapGetters } from 'vuex';

export default {
    components: {
        TodoItem
    },
    computed: {
        ...mapGetters(['allTodos'])
    },
}
</script>

v-container ์•ˆ์— v-row๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , mapGetters๋กœ ๋ถˆ๋Ÿฌ์˜จ allTodos์˜ ์ˆ˜๋งŒํผ for๋ฌธ์„ ๋Œ๋ฆฐ๋‹ค.

allTodos์˜ ์ˆ˜๋งŒํผ TodoItem์ด ๋‚˜์˜ฌ๊ฑฐ๊ณ , ์ž์‹ ์ปดํฌ๋„ŒํŠธ์ธ TodoItem์— todo๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

 

 

<!-- src/components/TodoItem.vue -->
<template>
    <v-container fluid>
        <v-row class="mb-3" justify="center" align="center">
            <v-col cols="4">
                {{ todo.title }}
            </v-col>
            <v-col cols="1">
                <v-btn block color="primary">Edit</v-btn>
            </v-col>
            <v-col cols="1">
                <v-btn block color="error">Delete</v-btn>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
export default {
    props: {
        todo: {}
    }
}
</script>

TodoItem์— props๋ฅผ ๋งŒ๋“ค์–ด์ค˜์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ ๊ฐ’์ธ todo๋ฅผ ์„ ์–ธํ•ด๋‘”๋‹ค.

{{ todo.title }}์„ ์ ์–ด๋‘๋ฉด ๋ถ€๋ชจ์—๊ฒŒ ๋ฐ›์€ todo์˜ title์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

 

5. ๊ฒฐ๊ณผ ๐Ÿคฃ

store index.js์— ์ฒ˜์Œ ์ ์–ด๋‘” One Two Three๊ฐ€ ๋จผ์ € ๋‚˜์˜ค๊ณ ,

์ž…๋ ฅํ•œ Four Five๋„ ์ž˜ Add ๋œ๋‹ค.

 

 

์‚ญ์ œ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ ๊ธ€์—์„œ ๐Ÿ˜Š

+ Recent posts