컴포넌트에 할떄는 필수고 아니어도 좀 쓰는 습관을 ...들여야함...

 

렌더링이 안돼... 

 

vue3 setup pinia  props & emit  사용법 예제

 

 

view 에서만 모든걸 다뤄버리면 너무 난해해지고 ,,, 또 setup 쓰다보니 코드가 스파게티.. 완전 난리도아니었다 

 

그래서 컴포넌트로 최대한 뺐는데 

사실 props 는 종종 썼었는데 emit 은 사용안해봤어서 정리해보려고 한다 

 

예제는 모달창띄우기. 

 

// view 부모컴포넌트 

<simple-modal
	v-model="modalFunc.flag.value"
    
    // props , 자식컴포넌트에선 value 라는 이름으로 받으면 된다 
    :value="modalFunc.data.value"
    
    // emit , 자식컴포넌트에선 closeModal 이라는 이름으로 올려주면 된다
    @closeModal="modalFunc.close()"
    @openModal="modalFunc.open()"
    @submitModal="modalFunc.submit()"
/>


<script setup>

const modalFunc = {
	flag: ref(false),
    data: ref(''),
    // 단순히 클로즈가 아니라 온오프 기능을 함께 가지고 있게 할수도있겠고... 
    close: () => {
    	modalFunc.flag.value = false
    },
    // 오픈은 val 을 통해서 어떤 data를 가진 modal을 띄울지 정한다
    open: (val) => {
        modalFunc.flag.value = true
    	modalFunc.data.value = val
    }
    // submit같은경우는 그냥 자식컴포넌트로 내려버려도 괜찮을듯...
    // 단 위에서 다른 컴포넌트랑 상호작용해야하는것들만 위로 올리기
    submit: (val) => {
    	// 이런느낌으로???
        otherModal.open('welcome')
        modalFunc.flag.value = true
    }
 }

부모컴포넌트 대강 만들었던거랑 유사하게 만들었는데

 

원래는 플래그고 데이터고 클로즈 오픈 다 떨어져있어서 여기저기 왔다갔다 해야해서 짜증났었는데 그냥 하나로 묶어버렸다...

 

코드가 좀 길어질 수 있다는 단점이 있는데 여기저기 코드찾으러 안다녀도 되니까 정말 편하다... 

 

그리고 최대한 자식컴포넌트한테 많은걸 넘겨주고싶었는데 그건 좀 ... 힘들었다 

 

자식컴포넌트는 

 

// 이런식으로 하면 중간값이 변수여도 잘 나옴 []안에 값을 잘 넣어보자
{{ modalType[props.value].title }}

{{ modalType[props.value].text }}



<script setup>

// props는 defineProps를 통해서 적용한다 사용은 props.value 이런식으로 
const props = defineProps({
	value: {
    	type: String,
        required: true
    }
})


// 위로 올려줄 이벤트 이름 작성
let emit = defineEmits(['closeModal' , 'openModal', 'submitModal' ])

function closeModal() {
	// 이 안에 다른 로직 넣어도 실행된다 
	emit('closeModal')
}

function openModal() {
	emit('openModal')
}

function submitModal() {
	// 서브밋같은경우에 변경사항이 있다면 이쪽에 적어주는것도 좋은 방법 
    
   // 서브밋버튼을 누를시 router.push 한다던가... 하는 방식 
   
	emit('submitModal')
}


// prop.value를 통해 home, hello, bye 중 어떤걸 내보낼지 정함 
const modalTyep = {
	home: {
    	title: ~~
        text: ~~
    },
    hello: {
    	title: ~~
        text: ~~
    },
    bye: {
    	title: ~~
        text: ~~
    }
}

 

이런식으로 최대한 컴포넌트에 많은것들을 주려고 했으나 마냥 쉽지만은 않았다. 

 

이번엔 코드 수정을 통해 이렇게 나왔는데 다음엔 짤때부터 이 기반으로 짜고 그 이후에 수정을 통해 업그레이드 해야겠다

import {defineStore} from "pinia";

export const user = defineStore("user", {
    state: () => ({
    	// 데이터들의 초기값 설정이 매우 중요하다
        // vue 파일에서 사용할때 const user = computed(() => user().userData )
        // 이런식으로 computed를 사용하였다. 안그러면 초기값만 계속 가져옴..
        // 이건 전역으로 사용되지만 지역으로 사용되는 변수들은 ref , reactive 가 있었고 
        // reactive는 object 사용할때만 나머지는 다 ref 로 사용하였다.
        // ref는 값 할당하거나 사용할때 .value 같이 붙여줘야한다 reactive는 안붙임 
        userData: []
    }),
    actions: {
        use() {
          return axios
          		// import.meta.env.VITE_API_URL 이부분은 .env로 dev, qa, stage를
                // 나눴을때 편의성을 위해서 사용하였다 
            .get(`${import.meta.env.VITE_API_URL}/user`, {
              headers: {
                Authorization: cookies.get('token'),
              }
            })
            .then(({data}) => {
              console.log(data)

              return Promise.resolve();
            })
            .catch((err) => {
            	
              return Promise.reject(err);
            });
        }
      },
    getters: {
    // getters는 위의 데이터들을 다 가져와서 묶음으로 만든다음에 써버릴수도 있었지만 굳이 싶어서 사용하지않았다
    
    }
});

 

computed를 사용해서 값이 바뀌어도 

 

ui 그려짐 -> ui에 초기값할당 -> 값 변경됨 -> 변경된 값 ui에 표기 

 

또는 

 

초기값 할당 -> api를 통해 변경된 값 할당 

 

이런식으로 진행되어야 한다고 생각했는데 값은 변경되어도 변경된 값이 ui에 표기되지않고 

console 을 찍어도 초기값만 줄줄 내려오는 경우가 간간히 있었다.

 

그리고 뒤늦게 콘솔찍으면 할당된 값 나옴.... 

 

어케어케 다 하긴했는데 진짜 안나오는애들은 그냥 

 

<script setup>

user().use().then(()=> {
	const userData = computed(()=> user().userData)
    
    // userData사용 혹은 
    
    // checkData를 리턴하는 함수 
    test().check()
    

})

// testChechkData 사용 
const testCheckData = computed(()=> test().checkData )

이런식으로 then 사용해서 돌려버리거나 

있는 값을 리턴하는 함수사용해서 돌려버리거나... 

 

단순히 api 뿐만 아니라 전역변수로 설정할만한것 몇개를 포함하다보니 저런 방식으로 써야 돌아가는 경우도 있었다... 

 

물론 방법을 잘 몰라서 좋은 방법이 있었겠지만 ... 이런 경험을 하게되었다... ?

 

 

처음엔 지역가드로 만들었다가 다시 전역가드로 변경하였다 

 

router.beforeEach((to, from, next) => {
	// to.name , to.query.name 등을 사용하였다 
    // 중간에 if문이랑 switch 문을 섞어서 사용하였는데 case break로 안됨 
    // 내부 if문 next()에 return next()로 써버리니까 되었다 
    // 단순히 로컬스토리지나 쿠키값을 가져와서 체크할수도있지만 api에서 받아오는 값으로 구현하였다
})

 

하나의 지역가드는 남겨두었는데 

 

{
	path: '/home',
    name: 'home',
    beforeEnter: (to, from, next) => {
    	// if ~~   next({path: /404}) 의 내용을 사용하였다 
        // 내가 지정한 쿼리값을 변조해서 사용하는걸 막기위한 가드였다
       // 처음에 사용할 때 함수가 비활성화 상태였는데 갑자기 됨... 오타있었나...뭔지모르겠따..
    },
    component: () => import("../views/home.vue")
    
}

 

아 추가로 컴포넌트 내부에서 router 사용할때  이번 프로젝트는 

vue3 setup + pinia 로 사용했었는데 

 

useRouter 임포트한다음에 useRouter() 를 통해서 라우터를 사용하였다 

컴포넌트 내부에서 실행하는 라우터는 좀 제한적인 부분이 있었다 

'vue' 카테고리의 다른 글

vue3 v-for 사용할때 key 좀 입력하자...  (0) 2023.03.09
vue3 setup pinia props & emit 사용법 예제  (0) 2023.03.09
vue3 pinia store 사용기  (0) 2023.03.09
vue3 quasar 설치  (0) 2023.02.15

+ Recent posts