본문 바로가기

front-end 국비과정 학습일지

국비지원 52일차 vite로 vue프로젝트 진행하는법,vuex 정리

vite로 vue 프로젝트를 진행하는 절차
1 터미널에서 npm create vite@latest <프로젝트 이름> 이라고 명시한다 
2 설치가 완료되면 터미널에서 해당 프로젝트로 이동한 후 npm i 라고 명시하여 package들을 설치한다
3 터미널에서 eslint, eslint-plugin-vue, scss를 사용하는경우 sass를 개발의존성 패키지(-D)로 설치한다 
4 src폴더에 .eslintrc.json파일을 만들어 lint설정을 한다 
5 터미널에서 npm run dev라고 명시하여 잘 돌아가는지 확인한다



vuex 기본사용법
1 개발서버가 꺼진 상태에서 npm i vuex라고 명시하여 vuex를 설치한다
2 src폴더에 vuex를 사용 할 store 파일을 만든다 
필자는 주로 store라는 폴더를 만들고 그안에 index.js라는 파일로 명시하는데 
index.js라고 명시하면 기본값으로 인식하여 다른 파일에서 import할때 파일이름을 명시하지 않아도 된다 
즉 index.js를 생략하고 사용 할 수 있다 
3store파일 여기선 index.js에서 createStore를 vuex에서 구조분해 할당하여 import한다 
그후 createStore를 기본내보내기(export default)한다 
4 store폴더에 index.js를 import하여 #app을 mount하는 파일 여기선 main.js에서 use라는 메소드를 사용하여 store을 연결 시켜준다
5 컴포넌트에서 사용해본다 
ex)

//store역할을 하는 index.js
import { createStore } from "vuex";

export default createStore({
  state() {
    return {
      test: "store 에서 가져온 데이터",
    };
  },
});
// #app을 mount하는 main.js 
import { createApp } from "vue";
import App from "./App.vue";
import store from "./store";

createApp(App).use(store).mount("#app");

//test.vue에서 스토어에 저장된 state(데이터) 사용 test
<template>
  <div>{{ $store.state.test }}</div>
</template>

<script>
export default {
 
}
</script>

<style>

</style>


vuex 기본 문법

state : state는 컴포넌트에서 사용할 데이터를 명시하는 영역이다
state안에 데이터를 컴포넌트에서 사용하기위해선 $store.state.데이터 이름 이라고 명시하여 사용한다

mutations: mutations는 state의 상태를 변경 할 수 있는 권한을 가지고 있기 때문에  state를 변경 할때 사용하는 영역이다
 

  함수로 작성한다 이때 1번파라미터로 state를 받는데 state는 위에 정의한 state를 의미한다
  mutations에 정의된 함수를 컴포넌트에서 사용하고자 한다면 $store.commit('<함수이름>)이라고 명시하여 사용한다.


  2번파라미터도 작성 할 수 있는데 2번 파라미터에는 컴포넌트에서 commit을 사용한 함수에 2번파라미터에 명시된 데이   터를 받아오는 역할을 한다
 이때 컴포넌트 뿐만 아니라 actions에서 commit을 사용하여 actions에서 사용된 데이터도 받아 올 수 있다.

주의사항! mutations에서는 데이터를 수정하는 역할만 수행하고 나머지 함수로직은 actions 작성하는것이 권장된다

 actions :비동기 요청 이나 함수로직을 명시하는 영역이다
 1actions에 명시된 함수를 컴포넌트에서 사용하고자한다면 $store.dispatch('<함수이름>')이라 명시한다
  만약 actions영역에서 state를 변경하는 경우가 생긴다면 이는 mutation에서 해야 할 일 이기 때문에
  commit의 2번파라미터로 actions에서 전달 할 내용을 mutations에게 전달한다
  actions에서 commit을 사용하기 위해선 context라는 인자를 받아야하는데 context는 commit,dispatch,getters,state를 가 지고 있는 객체데이터이다

  getters:컴포넌트에 computed처럼 vuex에 계산된 데이터이다 즉 return값을 캐시메모리에 저장해 함수를 호출 하지않아도 결과 값을 반환하는 역할을 하는 영역이다 
  주의사항! mutations는 2번파라미터에 컴포넌트가 mutations에 데이터를 전달 할 수 있지만 getters는 불가능하다 

  ex)

  //store역할을 하는 index.js
import { createStore } from "vuex";

export default createStore({
  state() {
    return {
      test: "store에서 가져온 데이터",
      count: 0,
      text: "",
      text2: "change 메소드가 호출되면 바뀌는 text",
      //state는 store에서 data를 정의하는 영역이다!
    };
  },
  mutations: {
    increase(state, payload) {
      state.count += 1;
      console.log(payload);
      state.text = payload;
      //컴포넌트에서 전달된 데이터를 콘솔창에 출력 해보고
      //state에 text라는 데이터를 만들어 할당한 예시
    },
  },
  actions: {
    change(context, payload) {
      context.state.text2 = "change메소드 호출됨";
      console.log(payload);
      //chage함수가 호출되면 payload에 text가 전달되는것을 확인하는 코드
    },
  },
});

//index.js에 명시된 내용을 사용한 컴포넌트
<template>
  <div @click="$store.commit('increase',text)">
    <!-- 스토어에 mutations에 정의된 increase메소드를 가져와 이벤트에 직접 작성한 예시  -->
    <!-- mutations의 정의된 메소드를 가져올때 commit을 사용하는 부분에 주목하자 -->
    {{ $store.state.count }}
    <!-- store에 state에 정의된 데이터 사용 예시  -->
    <div> {{ $store.state.text }}</div>
    <!-- payload로 전달된 데이터 화면에 출력하는 예시 -->
  </div>
  <button @click="countUp">
    +
  </button>
  <!-- 스토어에 mutations에 정의된 increase메소드를 가져와 method영역에 정의하여 사용한 예시 -->
  
  <div>{{ $store.state.text2 }}</div>
  <button @click="$store.dispatch('change',text)">
    textChange
  </button> 
  <!-- actions에 명시된 change함수를 컴포넌트에 연결한 예시 mutations와 다르게 dispatch메소드가 사용된다 -->
</template>

<script>
export default {
 data(){
  return{
    text:'payload에 전달 할 데이터'
  }
 }
 ,methods: {
  countUp(){
    this.$store.commit('increase',this.text)
  }
  // methods에 mutations메소드를 정의할땐 this를 붙여줘야한다
 },
}
</script>

<style>

</style>



★modules:store(저장소)에 명시할 내용이 많아지면 가독성이 떨어지기 때문에 store(저장소)를 모듈화 할 수 있는데 그때 사용되는 기능이다 


개인적인 생각으론 project규모가 커지면 커질수록 store에 정의할 내용 또한 반드시 늘어나므로 효율적인 코딩을 하기 위해선 반드시 알아야 하는 내용이라고 생각한다.

사용법:
1 module들을 관리할 폴더를 src폴더에 만들어 준다 이곳은 vuex가 import된 store파일과 모듈화된 파일을 효율적으로 관리하기 위한 판단이다
2 모듈화된 파일을 객체형태로 export default로 내보내기를 한후 내부에서 state,getters,mutations,actions등등을 
필요할때 사용한다 
주의사항! 모듈화된 파일에는 따로 vuex 즉 createStore를 명시하지 않는다
createStore가 사용되는 파일에 modules영역에 명시해서 사용하기 때문이다 
3모듈화된 파일을 사용할때 해당 파일에  namespaced:true라고 명시해야만 사용 할 수 있다 

 

namespaced란 무엇인가?
namespaced는 createStore가 사용된 파일에 모듈화된 파일을 import하여 modules영역에 등록한이름이다 
즉 modules영역에 등록된 이름이다
4 모듈화된파일을 import하여 createStore가 명시된 파일에 등록한다음 
 modules영역에 등록한다 
5 컴포넌트에서 사용한다 이때 사용법이 store를 하나만 사용 할 때와는 다르다 
5-1 모듈화한 파일에 state는 $store.state.<사용할 모듈파일의namespaced>.<state이름>이라고 명시하여 사용하고,
5-2 모듈화한 파일에 mutations,actions,getters등등의 메소드는 .commit('사용할 모듈파일의namespaced/메소드 이름',<해당 컴포넌트에서 전달할 데이터>) 또는 .dispatch('사용할 모듈파일의namespaced/메소드 이름',<해당 컴포넌트에서 전달할 데이터>)
라고 명시한다 
ex)

// 모듈화된파일 msg.js 
import { createStore } from "vuex";
import msg from "./msg.js";
import count from "./count.js";
export default createStore({
  state() {
    return {};
  },
  modules: {
    msg: msg,
    count,
    //참고로 key value가 동일하면 하나를 생략 할 수 있기 때문에 count처럼 명시해도 동작한다
  },
});

//모듈화된 파일count.js
export default {
  namespaced: true,
  state() {
    return {
      count: 0,
    };
  },
  getters: {},
  mutations: {
    countUp(state, payload) {
      state.count++;
      console.log(payload);
    },
  },
  actions: {},
};

//createStore가사용된 index.js
import { createStore } from "vuex";
import msg from "./msg.js";
import count from "./count.js";
export default createStore({
  state() {
    return {};
  },
  modules: {
    msg: msg,
    count,
    //참고로 key value가 동일하면 하나를 생략 할 수 있기 때문에 count처럼 명시해도 동작한다
  },
});

//컴포넌트에서 데이터를 사용한 예시
<template>
  <div>{{ $store.state.msg.msg }}</div>
  <button @click="change">
    changeText
  </button>
  <div>{{ $store.state.count.count }}</div>
  <button @click="increase">
    +
  </button>
</template>

<script>
export default {
  data(){
    return{
      text:'app.vue에서 전달하는 msg'
    }
  },
  methods:{
    change(){
      this.$store.commit('msg/updateMessage',this.text)
    },
    increase(){
      this.$store.commit('count/countUp',this.text)
    }
  }
}
</script>

<style>

</style>


store에 저장되어있는 내용 컴포넌트에서 쉽게 사용하게 해주는 mapState,mapMutations,mapActions

mapState:store에 있는 state를 컴포넌트에서 사용하기 위해선 $stote.state.<데이터 이름> 이라고 명시해서 사용하는데
store에 저장되어있는 데이터가 많으면 많을수록 $stote.state.<데이터 이름> 이라고 명시하는것이 불편하다 판단 할 수 있다
mapState를 사용하면 $store.state를 생략하고 데이터 이름만 가지고 컴포넌트에서 사용 할 수 있게 도와주는 헬퍼 함수이다 

사용법 
1 mapState를 사용하고자 하는 컴포넌트에서 import {mapState} from 'vuex'라고 명시한다 
mapState는 store에 데이터를 컴포넌트에서 작명하는것을 쉽게 만들어주는 vuex에 헬퍼함수이다 
때문에 vuex에 많은 기능중에 구조분해 할당{}으로 mapState만 꺼내와서 사용하겠다고 명시한다 

2 script태그에서 computed영역을 명시한후 mapState함수를 호출한다 이때 ...(전개연산자)를 사용한다
mapState는 배열로 만드는데 컴포넌트에서 데이터로 사용할때에는 해당 배열안에 내용을 사용해야하기 때문에 전개연산자로 배열안에 내부내용을 꺼내준다 생각하면 좋을듯하다 
만약 store에 파일이 모듈화된 파일이라면 1번파라미터에 모듈이름명시하고 2번파라미터에 배열의 형식으로 만들어 store에 사용하고싶은 state를 해당 배열에 명시한다 

3{{}}에 mapState로 가져온 state를 연결해본다 

mapActions,mapMutations

사용법 
1 mapState처럼 구조분해 할당을 이용해 vuex에서 mapActions,mapMutations를 꺼낸다 
2 mapActions,mapMutations는 함수이기 때문에 methods에서 mapActions,mapMutations를 명시한다 
mapActions,mapMutations도 mapState와 작성법이 같기 때문에 ...(전개연산자를) 사용해야한다 
모듈화된 파일에서 Actions,Mutations에 정의된 내용을 가져오는 경우라면 1번 파라미터에 모듈이름 2번파라미터에 배열의 형식으로 만들어 store에 명시되어있는Actions,Mutations를 꺼내사용한다 

ex)

// 모듈화된 msg.js
export default {
  namespaced: true,
  state() {
    return {
      msg: "버튼 누르면 변함",
      test1: "test text1",
      test2: "test text2",
      test3: "test text3",
    };
  },
  getters: {},
  mutations: {
    updateMessage(state, payload) {
      state.msg = "test";
      console.log(payload);
    },
  },
  actions: {
  },
};
//모듈화된 count.js
export default {
  namespaced: true,
  state() {
    return {
      msg: "버튼 누르면 변함",
      test1: "test text1",
      test2: "test text2",
      test3: "test text3",
    };
  },
  getters: {},
  mutations: {
    updateMessage(state, payload) {
      state.msg = "test";
      console.log(payload);
    },
  },
  actions: {
  },
};
//createStore가 사용된 index.js
import { createStore } from "vuex";
import msg from "./msg.js";
import count from "./count.js";
export default createStore({
  state() {
    return {};
  },
  modules: {
    msg: msg,
    count,
    //참고로 key value가 동일하면 하나를 생략 할 수 있기 때문에 count처럼 명시해도 동작한다
  },
});